import './style.css'; import { renderHomePage } from './home-page.ts'; import { renderDecksPage } from './decks-page.ts'; import { renderDeckPage } from './deck-page.ts'; import { renderHistoryPage } from './history-page.ts'; import { renderReviewPage } from './review-page.ts'; import { renderSyncPage } from './sync-page.ts'; import { initWorker } from './sqlite-api.ts'; import { setupPwa } from './pwa.ts'; // Каркас приложения: топ-бар + бургер-меню + страницы (Главная / Колоды / Колода / Повторение / История / Синхронизация). type Page = 'home' | 'decks' | 'deck' | 'review' | 'history' | 'sync'; const PAGE_TITLES: Record = { home: 'Главная', decks: 'Колоды', deck: 'Колода', review: 'Повторение', history: 'История', sync: 'Синхронизация', }; function requireEl(id: string): T { const el = document.getElementById(id); if (!el) throw new Error(`[JapLearn] Не найден элемент #${id}`); return el as T; } const burgerBtn = requireEl('burger-btn'); const drawer = requireEl('drawer'); const overlay = requireEl('drawer-overlay'); const pageTitle = requireEl('page-title'); const pageRoot = requireEl('page'); let drawerOpen = false; function setDrawer(open: boolean): void { drawerOpen = open; drawer.classList.toggle('open', open); overlay.hidden = !open; burgerBtn.setAttribute('aria-expanded', String(open)); drawer.setAttribute('aria-hidden', String(!open)); document.body.classList.toggle('drawer-open', open); } function setActiveButton(page: Page): void { drawer.querySelectorAll('.drawer-btn').forEach((btn) => { btn.classList.toggle('active', btn.dataset.page === page); }); } function renderPage(page: Page, deckId?: number): void { pageTitle.textContent = PAGE_TITLES[page]; // Колода / повторение / история — подразделы «Колод»: в меню подсвечиваем «Колоды». setActiveButton(page === 'deck' || page === 'review' || page === 'history' ? 'decks' : page); if (page === 'home') { renderHomePage(pageRoot, {}); } else if (page === 'decks') { renderDecksPage(pageRoot, { goDeck: (id) => renderPage('deck', id), goReview: (id) => renderPage('review', id), }); } else if (page === 'deck') { renderDeckPage(pageRoot, deckId ?? 0, { goDecks: () => renderPage('decks'), goReview: (id) => renderPage('review', id), goHistory: (id) => renderPage('history', id), }); } else if (page === 'review') { renderReviewPage(pageRoot, deckId ?? 0, { goDecks: () => renderPage('decks') }); } else if (page === 'history') { renderHistoryPage(pageRoot, deckId ?? 0, { goDeck: (id) => renderPage('deck', id) }); } else { renderSyncPage(pageRoot); } } burgerBtn.addEventListener('click', () => { setDrawer(!drawerOpen); }); overlay.addEventListener('click', () => { setDrawer(false); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && drawerOpen) setDrawer(false); }); drawer.querySelectorAll('.drawer-btn').forEach((btn) => { btn.addEventListener('click', () => { const page = btn.dataset.page as Page | undefined; if (page === 'home' || page === 'decks' || page === 'sync') renderPage(page); setDrawer(false); }); }); // Старт: главная страница, меню закрыто await initWorker(); setDrawer(false); renderPage('home'); setupPwa(); console.log('[JapLearn] crossOriginIsolated =', window.crossOriginIsolated);