Debugging & Resolution Log
This document serves as a technical retrospective of the debugging phase and architectural refinements implemented during the Zlot dashboard development.
1. NUQS Architecture Failure (404/Missing Adapter)
- Issue: The application threw a runtime error:
[nuqs] nuqs requires an adapter to work with your framework.and URL synchronization stopped working. - Root Cause:
nuqs(v2+) requires an explicit provider/adapter for the Next.js App Router to bridge the state between React components and the URL. - Solution:
- Updated
app/layout.tsx. - Wrapped the application tree in
NuqsAdapterfromnuqs/adapters/next/app. - Placed it inside the
QueryProviderto ensure clean hydration.
- Updated
2. Sidebar Navigation Logic Regression
- Issue: After refactoring the sidebar to support grouped categories (Operations, Intelligence, etc.), the "Active" state for navigation links broke, and ESlint reported unused
pathnamevariables. - Root Cause: The grouping logic (using
.reduce()) inadvertently stripped out theisActiveutility function and its associated logic during the mapping phase. - Solution:
- Restored the
isActivehelper function. - Re-integrated
usePathnamefor real-time URI matching. - Implemented a nested mapping strategy to render group headers without losing individual item functionality.
- Restored the
3. Duplicate Export Collision
- Issue: Next.js build failed due to multiple default exports in
app/dashboard/parking/entry/page.tsxandapp/dashboard/parking/active/page.tsx. - Root Cause: During the transition from static placeholders to dynamic server components, boilerplate code was accidentally duplicated.
- Solution:
- Audited page files and consolidated the logic into a single
default export. - Serialized BigInt data types (database IDs) into strings during the fetch phase to prevent hydration errors.
- Audited page files and consolidated the logic into a single
4. Icon Registry Mismatches
- Issue: Multiple components were showing "Icon not found" or triggering linting warnings regarding missing imports from
@phosphor-icons/react. - Root Cause: Shift from
dist/ssrto standard imports and missing icon names in the bundle across separate table components. - Solution:
- Standardized icons across
UsersTable,VehiclesTable, andHistoryTable. - Swapped custom SVG wrappers for official Phosphor components for design consistency.
- Standardized icons across
5. Analytics UI Hydration (Charts)
- Issue: Analytics page remained static with placeholder text despite
rechartsbeing in the dependencies. - Root Cause: Chart components were not marked with
"use client", causing server-side rendering failures for browser-specific APIs (DOM measurements). - Solution:
- Created a dedicated
charts.tsxwith the"use client"directive. - Implemented responsive containers to handle the "Industrial-Eco" layout's fluid grid.
- Created a dedicated
6. Type Safety & Non-Null Assertions
- Issue: Frequent linting errors regarding
anytypes and potential null pointers in transaction lookups. - Root Cause: Direct database row mapping to UI didn't account for optional fields like
exitTimeortotalCost. - Solution:
- Defined strict TypeScript interfaces for
Transaction,Vehicle, andArea. - Implemented proper null-checking and provided defaults (e.g.,
₱0.00) in theHistoryTablecells.
- Defined strict TypeScript interfaces for
7. Framer-Motion Invisible Rows (Animation Bug)
- Issue: Table rows would become completely invisible after a data mutation (e.g., deleting a record or adding a new one) until a manual page refresh.
- Root Cause:
motion.tbodyused a stagger animation that only triggered on the initial mount.router.refresh()updated the data but didn't trigger a re-mount, leaving new rows withopacity: 0. - Solution:
- Implemented a data-dependent
keyonmotion.tbody(e.g.,key={table.getRowModel().rows.map(r => r.id).join()}). - This forces a component re-mount on any data change, re-triggering the entrance animations cleanly.
- Implemented a data-dependent
8. Areas Module Performance & Browser Freezing
- Issue: The browser would hang or become unresponsive when clicking "Add Zone" or typing in the filter input.
- Root Cause: Infinite re-render loop triggered by an unstable
routingobject in TanStack Table's state and a lack of memoization for table columns/handlers. - Solution:
- Memoized the
sortingstate usinguseMemo. - Wrapped
columnsand all action handlers (handleEdit,handleSave) inuseMemoanduseCallback. - Stabilized the
useReactTablehook to comply with React Compiler (Forget) optimization patterns.
- Memoized the
9. Synchronous Filtering & Sorting State
- Issue: Filtering and sorting worked in the URL (URL updated) but the table content remained unchanged.
- Root Cause:
getFilteredRowModelandgetSortedRowModelwere missing from the TanStack Table configuration, preventing the UI from reacting to the URL state. - Solution:
- Integrated full TanStack Table models for filtering and sorting.
- Tied
globalFilterdirectly to thenuqssearch state. - Implemented client-side filtering for immediate feedback in the
AreasManagerandHistoryTable.