- Move 8 stray .md (+5 .txt) from ~/Desktop into docs/explorations/from-desktop/ - Reorganize 27 .md/.txt at workspace root: - audit reports -> docs/audits/ - exploration reports -> docs/explorations/ - design system -> docs/design-system/ - Keep only README/CHANGELOG/CONTRIBUTING/CLAUDE at repo root - Refresh docs/README.md as canonical index with links to all groups - Note: pre-existing docs/audits/AUDIT_INDEX.md and AUDIT_SUMMARY.md were overwritten by the newer root-level versions during the move Co-Authored-By: Paperclip <noreply@paperclip.ing>
9.6 KiB
Design System & Analytics Audit Summary
Date: April 21, 2026
Files Analyzed: 20+ component/config files
Status: ✅ Complete comprehensive audit
Executive Summary
This audit comprehensively catalogs the design system primitives, analytics API, and existing visualization components available for the homepage refactor. The platform has a mature, well-organized design system built on:
- 7 core design system components with TypeScript interfaces
- 30+ CSS design tokens in HSL-based light/dark theme
- Complete analytics API with market data, heatmaps, trends, and AI advice
- 3 chart types using Recharts with theme-aware styling
- 3 map implementations using Mapbox with fallbacks and interactive features
All components follow consistent patterns: explicit props, semantic HTML, accessibility-first, and responsive design.
Quick Stats
| Category | Count | Status |
|---|---|---|
| Design System Components | 7 | ✅ Exported + typed |
| Design Tokens | 30+ | ✅ CSS variables + Tailwind |
| Analytics Endpoints | 6+ | ✅ Full API coverage |
| Query Hooks | 4 | ✅ React Query integrated |
| Chart Types | 3 | ✅ Recharts v2 |
| Map Components | 3 | ✅ Mapbox GL JS |
| Fonts | 2 | ✅ Inter + JetBrains Mono |
| Color Variables | 30 | ✅ Light + dark modes |
File Structure
apps/web/
├── components/
│ ├── design-system/
│ │ ├── stat-card.tsx — KPI metric display
│ │ ├── price-delta.tsx — % change with arrows
│ │ ├── market-index.tsx — Hero index value
│ │ ├── data-table.tsx — Sortable tables
│ │ ├── compact-header.tsx — Terminal-style header
│ │ ├── dashboard-layout.tsx — Full-page frame
│ │ ├── ticker-strip.tsx — Scrolling ticker
│ │ └── index.ts — Barrel export
│ ├── charts/
│ │ ├── price-trend-chart.tsx — Dual-axis line chart
│ │ ├── district-bar-chart.tsx — Bar chart
│ │ ├── agent-performance.tsx — Mixed dashboard
│ │ └── district-heatmap.tsx — Mapbox heatmap
│ └── map/
│ ├── listing-map.tsx — Listing markers
│ └── location-picker.tsx — Interactive location
├── lib/
│ ├── analytics-api.ts — Core API endpoints
│ ├── tailwind.config.ts — Design tokens
│ └── hooks/
│ └── use-analytics.ts — React Query wrappers
└── app/
└── globals.css — CSS vars + animations
Component Catalog
Design System (7 components)
- StatCard — Compact metric with delta indicator
- PriceDelta — Directional % change badge
- MarketIndex — Large hero index value
- DataTable — Sortable, sticky-header table
- CompactHeader — Fixed navbar (48px)
- DashboardLayout — Terminal-style page frame
- TickerStrip — Auto-scrolling ticker animation
Charts (3 types)
- PriceTrendChart — Line with dual Y-axis
- DistrictBarChart — Rotated axis bar chart
- AgentPerformance — Mixed KPI + funnel dashboard
Maps (3 implementations)
- DistrictHeatmap — Sized + colored district circles
- ListingMap — Clickable price bubbles
- LocationPicker — Interactive map selection + geocoding
Design Tokens
Colors (30+)
Semantic Groups:
- Background: default, elevated, surface
- Foreground: default, muted, dim
- Signal: up (green), down (red), neutral (yellow)
- UI: border, input, ring, card
- Semantic: primary, success, warning, destructive
Dark + Light modes — CSS variables handle both :root and .dark selector
Typography
- Fonts: Inter (UI), JetBrains Mono (data, code)
- Scales: data-sm (0.75rem), data-md (0.875rem), data-lg (1.25rem), ticker (0.8125rem)
- Alignment:
tabular-numsapplied via[data-numeric]selector
Spacing
- Rows:
h-row(36px) for table rows - Header:
h-header-compact(48px) - Ticker:
h-ticker-bar(32px)
Animations
- Ticker scroll: 60s loop, pauses on hover
- Signal flash: 1s flash on price update
Analytics API
6 Main Endpoints
| Endpoint | Purpose | Returns |
|---|---|---|
getMarketReport() |
District breakdown by city/period | Array of district stats |
getHeatmap() |
Heat map data for districts | Array of heatmap points |
getPriceTrend() |
Historical price trend | Array of period points |
getDistrictStats() |
Current district KPIs | Array of district stats |
getNearbyPOIs() |
Points of interest search | Array of POI markers |
getListingAiAdvice() |
AI valuation + advice | Valuation + advice blocks |
Data Structures
Market Data:
medianPrice: string— Formatted price (e.g., "7.2 tỷ")avgPriceM2: number— Price per m² (numeric)totalListings: number— Listing countdaysOnMarket: number— Average timeabsorptionRate: number | null— Market velocityyoyChange: number | null— Year-over-year %
AI Data:
valuation: { estimateVND, lowVND, highVND, confidence, rationale }advice: { summary, pros[], cons[], suitableFor[] }cacheHit: boolean— Claude API cache status
React Query Integration
Query keys factory for cache management:
analyticsKeys = {
all: ['analytics'],
marketReport: (city, period) => [...],
heatmap: (city, period) => [...],
districtStats: (city, period) => [...],
priceTrend: (district, city, propertyType, periods) => [...],
}
Key Patterns
1. Explicit Props (No Spreading)
Every component has typed, documented props. No {...rest} patterns for clarity.
2. Semantic HTML
- Tables use
<table>,<th scope="col"> - Headers use
<header>,<nav> - Proper heading hierarchy
3. Numeric Alignment
All numbers use font-mono + tabular-nums via the [data-numeric] selector or font-mono class.
4. Signal Colors
- Green: up, positive, success
- Red: down, negative, destructive
- Yellow: neutral, warning
5. Dark-First Architecture
Light mode defined in :root, dark mode in .dark selector. Theme toggle via className="dark" on root.
6. Responsive Mobile-First
Mobile is default; md: and lg: breakpoints for tablet/desktop.
7. Theme-Aware Maps
Maps sync with global theme via useMapboxStyle() hook.
8. Recharts HSL Variables
Charts use hsl(var(--primary)) pattern for dynamic theming instead of hardcoded colors.
Important Notes for Refactor
✅ What's Ready
- Design system is complete — all 7 components are production-ready
- Analytics API is fully typed — strong TypeScript coverage
- Query hooks are cached — React Query integration with proper keys
- Charts are theme-aware — HSL variables, no hardcoded colors
- Maps have fallbacks — graceful handling of missing Mapbox token
- Accessibility built-in — semantic HTML,
aria-hiddenon icons - Responsive by default — mobile-first approach
⚠️ Considerations
- No TEC-3030 design spec found — check project management tools or JIRA
- Mapbox token required — must be set in
.env.local - Charts use mock data —
AgentPerformanceneeds backend integration - Map centroids hardcoded — 3 cities preset, fallback spreads unknowns in ring
- No existing homepage components — design system is for dashboards, not landing page
🔧 Integration Checklist
- Verify NEXT_PUBLIC_MAPBOX_TOKEN is set
- Test dark/light mode toggle
- Validate responsive breakpoints (md: 768px, lg: 1024px)
- Check numeric alignment on all data displays
- Confirm signal colors match brand guidelines
- Test analytics API endpoints with real backend
- Verify React Query cache keys are unique
- Profile chart performance with large datasets
Export Reference
Design System
import {
StatCard, PriceDelta, MarketIndex, DataTable,
CompactHeader, DashboardLayout, TickerStrip,
} from '@/components/design-system';
Analytics
import { analyticsApi } from '@/lib/analytics-api';
import {
useMarketReport, useHeatmap, useDistrictStats, usePriceTrend,
analyticsKeys,
} from '@/lib/hooks/use-analytics';
Charts
import { PriceTrendChart } from '@/components/charts/price-trend-chart';
import { DistrictBarChart } from '@/components/charts/district-bar-chart';
import { AgentPerformance } from '@/components/charts/agent-performance';
Maps
import { DistrictHeatmap } from '@/components/charts/district-heatmap';
import { ListingMap } from '@/components/map/listing-map';
import { LocationPicker } from '@/components/map/location-picker';
Next Steps
- Review TEC-3030 spec — locate design requirements document
- Audit existing homepage code — identify what to replace/extend
- Plan component composition — decide which primitives go in hero/sections
- Backend integration timeline — align API mocking with real endpoints
- Performance testing — profile with real market data volumes
- Accessibility testing — WCAG 2.1 AA compliance check
- Mobile testing — verify responsive breakpoints on actual devices
Files Provided
- DESIGN_SYSTEM_AUDIT_2026_04_21.md — Full detailed audit (10 sections, 500+ lines)
- DESIGN_SYSTEM_QUICK_REFERENCE.md — Copy-paste code examples
- AUDIT_SUMMARY.md — This file
All components are production-ready for immediate homepage integration.