Skip to content

Dashboard

The dashboard is the landing page of tracker-frontend-svelte (src/routes/(app)/+page.svelte). It provides users with an overview of tracker statistics, map visualization, and a table of trackers with search, filtering, sorting, and pagination.

Features

  • Brand/Campaign Filtering: Search-driven dropdowns to filter trackers by brand and by production run (campaign)
  • Status Filtering: Filter trackers by status (In Transit, In Storage, Delivered, Created), via clickable badges or a dropdown
  • Statistics Display: Stat cards showing total, in-transit, delivered, and in-storage counts for the currently filtered trackers
  • Map Visualization: Interactive Leaflet map (with marker clustering) showing tracker locations, driven by the same filters as the table
  • Tracker Table: Sortable, paginated table of trackers with inline name editing, search by name/key/MAC address, and a "view history" action per tracker
  • Deferred Loading: The map and table stay empty until a filter is applied or the user clicks "Load All Data", to avoid loading the full tracker set up front
  • Persisted Filters: Filter selections and page size are persisted to localStorage so they survive a page reload

Architecture

Unlike a typical multi-file "feature folder", the dashboard route is a single page component that composes smaller pieces from two places:

  • App-local components in tracker-frontend-svelte/src/lib/components/dashboard/:
  • StatCard.svelte — a single statistic tile
  • TrackerMap.svelte — the Leaflet map with marker clustering
  • TrackerTable.svelte — the sortable tracker table (with TrackerSortField type)
  • TrackerHistoryModal.svelte / TrackerHistoryMap.svelte — the per-tracker location history modal
  • EditableNameCell.svelte, StatusTimeline.svelte, DailyReportsChart.svelte — supporting pieces used by the table/history views
  • Shared components from packages/tracker-shared/src/components/, reused by both tracker-frontend-svelte and tracker-admin-svelte:
  • SearchDropdown.svelte — the brand/campaign search inputs
  • StatusBadge.svelte — the clickable status filter badges
  • Pagination.svelte — page navigation and page-size controls
  • LoadingIndicator.svelte — the loading spinner shown while data or the map is loading

A local utility module, tracker-frontend-svelte/src/lib/utils/dashboardFilters.ts, handles reading/writing the persisted filter state to localStorage.

Implementation Details

State management

The dashboard does not use a context/store for its own local UI state — it uses Svelte 5 runes directly in +page.svelte:

  • $state: Selected statuses, search inputs, current page, items per page, the fetched trackers array, loading/error flags, sort field/order, and inline-edit state
  • $derived / $derived.by: Filtered brand/campaign options, filtered and sorted trackers, pagination slices, and the per-status stat counts — all recomputed automatically from the underlying $state
  • $effect: Persisting filters to localStorage whenever they change, triggering a tracker fetch whenever the active filters change, and a timeout-based safety net that stops waiting on the map's "ready" signal if it never fires

Application-wide state (the signed-in user) is not part of the dashboard — it lives in the shared authState store in packages/tracker-shared/src/state/auth.ts, a plain Svelte writable store populated by initializeAuth() in the (app) layout (src/routes/(app)/+layout.svelte). The dashboard route only reads tracker, brand, and production-run data via the API functions in packages/tracker-shared/src/api/.

Data fetching

Trackers are fetched with listTrackers() from tracker-shared/api/trackers whenever the brand, campaign, or status filters change, using a fetch-token guard (fetchToken) to discard stale responses if a newer request has already started. Brands and production runs (used to populate the filter dropdowns) are loaded once on mount via listBrands() and listProductionRuns().

Components

StatCard

Renders a single statistic (label, value, and tone/color) in the stats grid at the top of the page.

TrackerMap

Renders an interactive Leaflet map with marker clustering (leaflet.markercluster) for every filtered tracker that has a known location. Exposes a focusTracker(trackerId) method (via component binding) so clicking a table row can pan/zoom the map to that tracker.

TrackerTable

Displays the paginated, sorted list of trackers. Supports:

  • Column sorting (by name, MAC address, or latest location timestamp)
  • Inline editing of a tracker's name
  • A "view history" action that opens TrackerHistoryModal
  • Row clicks that focus the tracker on the map

TrackerHistoryModal / TrackerHistoryMap

A modal showing a tracker's location and status history, including its own map view and a status timeline.

Future Improvements

Potential future improvements to the dashboard include:

  1. Real-time Updates: Implement WebSocket or polling for real-time tracker updates
  2. Advanced Filtering: Add more advanced filtering options, such as date ranges and custom fields
  3. Customizable Layout: Allow users to customize the dashboard layout
  4. Export Functionality: Add the ability to export tracker data to CSV or PDF
  5. Saved Filters: Allow users to save and reuse multiple named filter configurations (today only the single most recent filter state is persisted)