
# Plan: Client-Side Router & Centralized In-Flight Data Sync...
Prompt
# Plan: Client-Side Router & Centralized In-Flight Data Sync ## Problem & Goals When navigating between pages in the current multi-page architecture, the browser terminates the active JavaScript runtime and aborts in-flight network requests. If the user navigates before the initial database sync or report loads complete, multiple duplicate requests are triggered and aborted in a loop. We will implement: 1. **Client-Side SPA Navigation (Turbo/App-Shell Router)** in Vanilla JS (`app-shell.js`): - Intercept internal navigation clicks (`bottom-nav`, `menu-drawer`, and internal links). - Fetch the target HTML and swap the `<main>` content and container classes without full page reload. - Preserve the JavaScript execution context so in-flight `fetch` requests are never aborted when switching pages. - Support browser back/forward history (`popstate`) and direct bookmark/URL loads. - Handle component cleanup (Flatpickr destruction, open modal resets) between transitions. 2. **Centralized In-Flight SyncAll & Deduplication** (`auth.js`, `api.js`, `store.js`, page controllers): - Centralize initial data loading through a shared `syncAll` promise that outlives page navigation. - Ensure page controllers (`stats.js`, `sales-history.js`, `expenses-history.js`, `products-list.js`, `constants.js`) seamlessly react to the global `3dpm_data_refreshed` event without firing conflicting duplicate requests when `syncAll` is already in-flight. --- ## Proposed Changes ### Core Shell & Navigation #### [MODIFY] app-shell.js - Implement `registerPage(pageId, initFn, cleanupFn)` in `bootstrapPage`. - Implement client-side navigation router `navigate(url, { pushState = true })`: - Fetch target page HTML. - Parse and replace `<main>` element and its classes (e.g. `main-container-with-summary`). - Update `document.title`. - Close any open modals/overlays and run previous page's cleanup function. - Dynamically load or invoke the target page controller. - Update active states in sticky bottom navigation and slide-out menu drawer. - Bind global click interceptor on internal `.nav-item`, `.drawer-nav-item`, and internal links. - Bind `window.addEventListener('popstate')` for browser back/forward buttons. --- ### Data Layer & Deduplication #### [MODIFY] auth.js - Maintain `isSyncingAll` and `activeSyncAllPromise` in memory. - Provide a helper `ensureSyncComplete()` so pages can await ongoing sync rather than firing duplicate requests. #### [MODIFY] api.js - Enhance in-flight request deduplication for read actions (`syncAll`, `getSalesHistory`, `getExpensesHistory`, `getPrintersAndFilaments`). - Ensure read requests join existing in-flight promises instead of creating concurrent duplicate network calls. --- ### Page Controllers Lifecycle Alignment #### [MODIFY] stats.js - Await `auth.ensureSyncComplete()` or use cached sales/expenses if available; avoid spawning parallel `getSalesHistory`/`getExpensesHistory` while `syncAll` is active. #### [MODIFY] sales-history.js - Implement cleanup function for Flatpickr instance (`fpInstance?.destroy()`). - Avoid duplicate background fetches when `syncAll` is already in flight. #### [MODIFY] expenses-history.js - Implement cleanup function for Flatpickr instance (`fpInstance?.destroy()`). - Avoid duplicate background fetches when `syncAll` is already in flight. #### [MODIFY] sale.js, expense.js, product.js, products-list.js, constants.js, settings.js - Ensure clean re-initialization when navigated to dynamically via router. --- ## Verification Plan ### Automated Tests - Run `npm test` to verify all unit tests, calculation logic, security helpers, and date parsers pass. ### Manual Verification 1. Open the app via `npx netlify dev` (or `npx serve src` with mock mode). 2. Click rapidly between **İstatistikler**, **Geçmiş Satışlar**, **Geçmiş Harcamalar**, **Satış Yap**. 3. Verify that network requests are not repeatedly aborted and restarted. 4. Verify that when the initial `syncAll` completes, whatever page is open instantly renders with the fresh data. 5. Verify browser back/forward buttons work as expected. 6. Verify direct URL reloads (e.g. `http://localhost:.../stats.html`) still work cleanly. - - - Is this a good plan?