const API_BASE_URL = '/api'; let currentLocale = localStorage.getItem('locale') || 'zh_CN'; let authToken = localStorage.getItem('auth_token'); function showLoading() { document.getElementById('loadingOverlay').classList.add('active'); } function hideLoading() { document.getElementById('loadingOverlay').classList.remove('active'); } function showToast(message, type = 'success') { const toast = document.createElement('div'); toast.className = `alert alert-${type} position-fixed top-0 start-50 translate-middle-x mt-3`; toast.style.zIndex = '99999'; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } async function apiRequest(endpoint, options = {}) { const headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', ...options.headers }; if (authToken && !options.skipAuth) { headers['Authorization'] = `Bearer ${authToken}`; } try { const response = await fetch(API_BASE_URL + endpoint, { ...options, headers }); const data = await response.json(); if (!response.ok) { // If the response has a business-level success field, return it as-is // so callers can handle it uniformly (e.g. show 'fail' UI instead of throwing) if (data && data.success !== undefined) { return data; } throw new Error(data.message || 'Request failed'); } return data; } catch (error) { console.error('API Error:', error); throw error; } } // ===== Sidebar toggle (only on pages that don't use layouts/app.blade.php) ===== if (!document.querySelector('meta[name="layout-loaded"]')) { const sidebar = document.getElementById('sidebar'); const overlay = document.getElementById('overlay'); const sidebarToggle = document.getElementById('sidebarToggle'); const sidebarClose = document.getElementById('sidebarClose'); function openSidebar() { sidebar?.classList.add('open'); overlay?.classList.add('active'); } function closeSidebar() { sidebar?.classList.remove('open'); overlay?.classList.remove('active'); } sidebarToggle?.addEventListener('click', openSidebar); sidebarClose?.addEventListener('click', closeSidebar); overlay?.addEventListener('click', closeSidebar); } // ========================== // startScanBtn handler is defined in index.blade.php (hides overlay before initScanner) document.getElementById('loginBtn')?.addEventListener('click', () => { const loginModal = new bootstrap.Modal(document.getElementById('loginModal')); loginModal.show(); }); document.getElementById('showRegister')?.addEventListener('click', (e) => { e.preventDefault(); const loginModal = bootstrap.Modal.getInstance(document.getElementById('loginModal')); loginModal.hide(); const registerModal = new bootstrap.Modal(document.getElementById('registerModal')); registerModal.show(); }); document.getElementById('showLogin')?.addEventListener('click', (e) => { e.preventDefault(); const registerModal = bootstrap.Modal.getInstance(document.getElementById('registerModal')); registerModal.hide(); const loginModal = new bootstrap.Modal(document.getElementById('loginModal')); loginModal.show(); }); if (authToken) { document.getElementById('loginBtn')?.classList.add('d-none'); }