Files
telegram-shop/src/admin/views/partials/app-sidebar.ejs
NW 61c7a90aeb fix(bot): issue #130 — crypto deposit photo-edit 400, chat cleanup via lastInlineMessageId
- depositHandler: handleDepositInstruction + handleDepositSelectWallet use editOrSendCallback (photo-safe fallback) — fixes 'no text in the message to edit' 400
- resetUserContext deletes lastInlineMessageId (stale inline menus cleaned on Reply Keyboard nav)
- showProducts/showProfile/showBalance/showPurchases store lastInlineMessageId on sendMessage
- answerCallbackQuery verified before dispatch (v1.2.4)
- 48 tests pass; bump v1.2.5
2026-08-05 12:20:16 +01:00

141 lines
7.8 KiB
Plaintext

<aside class="app-sidebar d-flex flex-column">
<%- include('app-logo') %>
<%- include('app-menu-filter') %>
<nav id="js-primary-nav" class="primary-nav flex-grow-1 custom-scroll" aria-label="Primary">
<%- include('generated-navigation') %>
<div class="no-results-msg pt-3 info-container">
<h6 class="mb-1"> No menu items found.</h6>
<p class="fs-sm">Try searching with different keywords.</p>
<div class="d-flex align-items-center gap-1 fs-xs fw-500 font-style-italic">
<kbd class="kbd-key">
<svg width="15" height="15" aria-label="Escape key" role="img">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2">
<path d="M13.6167 8.936c-.1065.3583-.6883.962-1.4875.962-.7993 0-1.653-.9165-1.653-2.1258v-.5678c0-1.2548.7896-2.1016 1.653-2.1016.8634 0 1.3601.4778 1.4875 1.0724M9 6c-.1352-.4735-.7506-.9219-1.46-.8972-.7092.0246-1.344.57-1.344 1.2166s.4198.8812 1.3445.9805C8.465 7.3992 8.968 7.9337 9 8.5c.032.5663-.454 1.398-1.4595 1.398C6.6593 9.898 6 9 5.963 8.4851m-1.4748.5368c-.2635.5941-.8099.876-1.5443.876s-1.7073-.6248-1.7073-2.204v-.4603c0-1.0416.721-2.131 1.7073-2.131.9864 0 1.6425 1.031 1.5443 2.2492h-2.956"></path>
</g>
</svg>
</kbd> to reset
</div>
</div>
</nav>
<div class="nav-footer">
<div class="d-flex align-items-center gap-2" role="button" data-bs-toggle="modal" data-bs-target="#versionModal" style="cursor:pointer;" title="View version history">
<svg class="sa-icon sa-thin">
<use href="/icons/sprite.svg#tag"></use>
</svg>
<span class="fs-xs opacity-70">v1.2.5</span>
</div>
</div>
</aside>
<!-- Version History Modal -->
<div class="modal fade" id="versionModal" tabindex="-1" aria-labelledby="versionModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="versionModalLabel">Version History</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="alert alert-info mb-3">
<strong>Current:</strong> v1.2.5 &middot; 2026-08-05
</div>
<h6 class="fw-bold mb-2">v1.2.5 <span class="text-muted fs-sm">&mdash; 2026-08-05</span></h6>
<ul class="small mb-3">
<li><span class="badge bg-info">refactor</span> Removed deposit amount-selection step; deposit_wallet_ now goes directly to Mercuryo instructions</li>
<li><span class="badge bg-primary">feat</span> Updated Mercuryo button text to include VISA/Mastercard branding in all locales</li>
<li><span class="badge bg-primary">feat</span> Added deposit_important5 note about Mercuryo authorization limits and top-up reserve</li>
</ul>
<h6 class="fw-bold mb-2">v1.2.0 <span class="text-muted fs-sm">&mdash; 2026-07-08</span></h6>
<ul class="small mb-3">
<li><span class="badge bg-warning text-dark">fix</span> Disabled CSRF checks in admin panel for Tor / onion zone compatibility</li>
<li><span class="badge bg-warning text-dark">fix</span> Fixed "Invalid wallet type" error in Telegram bot purchase flow</li>
<li><span class="badge bg-primary">feat</span> Added version history modal in admin sidebar</li>
</ul>
<h6 class="fw-bold mb-2">v1.1.0 <span class="text-muted fs-sm">&mdash; 2026-07-02</span></h6>
<ul class="small mb-3">
<li><span class="badge bg-primary">feat</span> Mercuryo gateway, crypto QR deposit, mono products, wallet auto-refresh</li>
<li><span class="badge bg-warning text-dark">fix</span> CSRF cookie sameSite=false for Tor, auth cookie fix, async handlers</li>
<li><span class="badge bg-primary">feat</span> Draggable dashboard panels + business KPI redesign</li>
<li><span class="badge bg-primary">feat</span> SmartAdmin template redesign + security hardening</li>
</ul>
<h6 class="fw-bold mb-2">v1.0.0 <span class="text-muted fs-sm">&mdash; 2026-06-24</span></h6>
<ul class="small mb-0">
<li><span class="badge bg-primary">feat</span> Initial release — Telegram shop bot with admin panel</li>
<li><span class="badge bg-primary">feat</span> Crypto wallets (BTC, LTC, ETH, USDT, USDC)</li>
<li><span class="badge bg-primary">feat</span> Product catalog with locations, categories, subcategories</li>
<li><span class="badge bg-primary">feat</span> Purchase system with hidden content delivery</li>
<li><span class="badge bg-primary">feat</span> Admin panel with dashboard, wallets, users, purchases, audit log</li>
<li><span class="badge bg-primary">feat</span> Tor proxy support (.onion access)</li>
<li><span class="badge bg-primary">feat</span> i18n localization (en/es/de)</li>
</ul>
</div>
<div class="modal-footer">
<span class="text-muted small">Update version in <code>VERSION.md</code> + <code>app-sidebar.ejs</code></span>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="backdrop" data-action="toggle-swap" data-toggleclass="app-mobile-menu-open"></div>
<!-- Sidebar Link Active Script -->
<script>
const sideNavMenu = document.getElementById("js-nav-menu");
const currentUrl = window.location.href.split(/[?#]/)[0];
const allLinks = sideNavMenu.querySelectorAll("a");
const allCollapses = sideNavMenu.querySelectorAll("li [aria-expanded='true']");
sideNavMenu.querySelectorAll("li .has-ul").forEach((toggle) => { toggle.addEventListener("click", (e) => e.preventDefault()); });
allCollapses.forEach((collapse) => {
collapse.addEventListener("show.bs.collapse", (event) => {
const currentCollapse = event.target;
const ancestors = [];
let el = currentCollapse.parentElement;
while (el && el !== sideNavMenu) {
if (el.classList.contains("collapse")) {
ancestors.push(el);
}
el = el.parentElement;
}
allCollapses.forEach((other) => {
if (other !== currentCollapse && !ancestors.includes(other)) {
new bootstrap.Collapse(other, { toggle: false }).hide();
}
});
});
});
allLinks.forEach((link) => {
if (link.href === currentUrl) {
link.classList.add("active");
let currentElement = link.closest("li");
while (currentElement && currentElement !== sideNavMenu) {
currentElement.classList.add("active");
const parentCollapse = currentElement.closest("[role='menu']");
if (parentCollapse) {
new bootstrap.Collapse(parentCollapse, { toggle: false }).show();
const collapseParentLi = parentCollapse.closest("li");
if (collapseParentLi) {
collapseParentLi.classList.add("active");
}
currentElement = collapseParentLi;
} else {
currentElement = currentElement.parentElement;
}
}
}
});
</script>