╔════════════════════════════════════════════════════════════════════════════╗
║        GOODGO PLATFORM AI - NEXT.JS FRONTEND QUICK REFERENCE               ║
╚════════════════════════════════════════════════════════════════════════════╝

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. PROJECT STRUCTURE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

/apps/web/
├─ app/[locale]/              ← Next.js 15 App Router (public, auth, dashboard, admin)
├─ components/                ← React components (listings, neighborhood, map, charts, design-system)
├─ lib/                        ← API clients, hooks, stores, utilities
├─ i18n/ & messages/          ← Internationalization (vi/en)
└─ public/                    ← Static assets

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2. CORE TECHNOLOGIES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Framework:           Next.js 15.5.14 (App Router)
Runtime:             React 18.3.0
Styling:             Tailwind CSS 3.4.0 + CVA 0.7.1
Forms:               react-hook-form 7.72.1 + Zod 4.3.6
State:               Zustand 5.0.12 (client) + React Query 5.96.2 (server)
Mapping:             Mapbox GL 3.21.0
Charts:              Recharts 3.8.1
Icons:               lucide-react 1.7.0
i18n:                next-intl 4.9.0
Theme:               next-themes 0.4.6
Real-time:           socket.io-client 4.8.3
PDF Export:          html2canvas 1.4.1 + jspdf 4.2.1

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3. NEIGHBORHOOD FEATURES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

COMPONENTS:
  ✓ NeighborhoodPOIMap              (11 KB, Mapbox GL + 6 POI categories)
  ✓ NeighborhoodRadarChart         (2 KB, Recharts radar, 0-10 scores, 6 categories)
  ✓ NeighborhoodScore              (2 KB, compact score display)

TYPES & CONFIG:
  ✓ NeighborhoodCategory           (label, score 0-10, icon)
  ✓ POIItem                         (id, name, category, lat/lng, distance)
  ✓ POICategory                     (school, hospital, transit, shopping, restaurant, park)
  ✓ NeighborhoodScoreData          (overall score, categories, POIs, center)

INTEGRATION:
  ✓ Dynamically loaded in listing-detail-client.tsx
  ✓ Part of enrichment data pipeline (API response)
  ✓ Maps imported with SSR disabled for performance

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4. MAPBOX GL USAGE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

COMPONENTS:
  • listing-map.tsx              Multiple listings + click handlers
  • location-picker.tsx          Interactive location selection
  • neighborhood-poi-map.tsx     POI visualization with filters

STYLING:
  • Light: mapbox://styles/mapbox/streets-v12
  • Dark:  mapbox://styles/mapbox/dark-v11
  • Theme-aware via useMapboxStyle() hook

PATTERN:
  'use client'                    ← Must be client component
  import 'mapbox-gl/dist/mapbox-gl.css'
  const style = useMapboxStyle()  ← Get theme-aware style
  new mapboxgl.Map({ style })     ← Create map instance

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5. CHART COMPONENTS (RECHARTS)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ✓ price-area-chart.tsx         Trend visualization (up/down coloring)
  ✓ price-trend-chart.tsx        Historical trends
  ✓ district-bar-chart.tsx       District comparisons
  ✓ district-heatmap.tsx         Heat visualization (9 KB)
  ✓ agent-performance.tsx        Agent metrics (6 KB)
  ✓ neighborhood-radar-chart.tsx Radar chart (0-10 scores)

PATTERN:
  ResponsiveContainer            ← Responsive sizing
  CSS variables for theming       ← --color-signal-up, --color-signal-down
  Custom Tooltip styling          ← Themed backgrounds
  Vietnamese number formatting    ← tr/k notation

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
6. API CLIENT PATTERN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

BASE CLIENT (lib/api-client.ts):
  apiClient.get<T>(endpoint, headers?)
  apiClient.post<T>(endpoint, body?, headers?)
  apiClient.patch<T>(endpoint, body?, headers?)
  apiClient.delete<T>(endpoint, headers?)

FEATURES:
  ✓ CSRF token handling (from cookies)
  ✓ Automatic 401 refresh-and-retry (except auth endpoints)
  ✓ Concurrent refresh coalescing
  ✓ Type-safe with generics
  ✓ Base URL from NEXT_PUBLIC_API_URL env var

DOMAIN-SPECIFIC CLIENTS (lib/*-api.ts):
  listings-api.ts      | Listing CRUD, search
  analytics-api.ts     | Market reports, heatmaps, trends
  neighborhood-api.ts  | Neighborhood scoring (if exists)
  valuation-api.ts     | AVM estimates
  agents-api.ts        | Agent profiles
  khu-cong-nghiep-api  | Industrial parks
  du-an-api.ts         | Projects
  inquiries-api.ts     | Inquiries
  leads-api.ts         | Leads
  admin-api.ts         | Admin operations

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
7. REACT QUERY HOOKS (lib/hooks/)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

PATTERN:
  const analyticsKeys = {
    all: ['analytics'] as const,
    marketReport: (city, period) => ['analytics', 'market-report', city, period] as const,
  };

  export function useMarketReport(city: string, period: string) {
    return useQuery({
      queryKey: analyticsKeys.marketReport(city, period),
      queryFn: () => analyticsApi.getMarketReport(city, period),
    });
  }

AVAILABLE HOOKS:
  use-analytics.ts              useMarketReport, useHeatmap, usePriceTrend, etc.
  use-listings.ts              useListings, useListing
  use-khu-cong-nghiep.ts       useIndustrialParks
  use-du-an.ts                 useProjects
  use-valuation.ts             useValuation
  use-inquiries.ts             useInquiries
  use-leads.ts                 useLeads
  use-reports.ts               useReports
  use-saved-searches.ts        useSavedSearches

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
8. LISTING DETAIL PAGE FLOW
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ROUTE: /[locale]/(public)/listings/[id]/page.tsx

1. SERVER COMPONENT (RSC)
   ├─ generateMetadata()          ← SEO: OG, canonical, schema
   └─ fetchListingById(id)        ← Data fetching

2. CLIENT COMPONENT (listing-detail-client.tsx - 39 KB)
   ├─ ImageGallery               ← Media slideshow
   ├─ KPI Strip                   ← Trader-style metrics
   ├─ Core Details                ← Address, bedrooms, etc.
   ├─ PriceHistoryChart           ← Recharts trend
   ├─ Neighborhood Section
   │  ├─ NeighborhoodRadarChart  ← (dynamic import, SSR: false)
   │  └─ NeighborhoodPOIMap      ← (dynamic import, SSR: false)
   ├─ AiAdviceCards              ← Personas
   ├─ SimilarListings             ← Recommendations
   ├─ AgentCard                   ← Quality score
   └─ CTA Section                 ← Inquiry, comparison, estimate

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
9. STATE MANAGEMENT LAYERS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

LAYER 1: REACT QUERY (Server State)
  Purpose:       Fetch & cache API data
  Provider:      QueryProvider (components/providers/query-provider.tsx)
  Error Handle:  QueryErrorResetBoundary + custom error boundary
  Usage:         useQuery, useMutation hooks

LAYER 2: ZUSTAND (Client State)
  Purpose:       UI state, preferences
  Examples:      auth-store, comparison-store, preferences-store
  Persistence:   localStorage integration
  Usage:         Direct store access or hooks

LAYER 3: CONTEXT (Global Features)
  Theme:         ThemeProvider (next-themes)
  Notifications: NotificationsProvider
  Auth:          AuthProvider
  Query:         QueryProvider

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
10. DESIGN SYSTEM COMPONENTS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

FINANCIAL METRICS:
  ✓ kpi-card.tsx                Key performance indicator
  ✓ stat-card.tsx               Statistics display
  ✓ ticker-strip.tsx            Horizontal ticker/marquee
  ✓ price-delta.tsx             Price change with signal
  ✓ signal.tsx                  Up/down indicator
  ✓ numeric.tsx                 Formatted number display

DATA DISPLAY:
  ✓ data-table.tsx              @tanstack/react-table wrapper
  ✓ empty-state.tsx             Empty data fallback
  ✓ skeleton.tsx                Loading skeleton
  ✓ status-chip.tsx             Status badge

LAYOUT:
  ✓ dashboard-layout.tsx        Dashboard structure
  ✓ density-provider.tsx        Compact/dense mode toggle
  ✓ divider.tsx                 Visual separator

UI PRIMITIVES (from shadcn/ui via design-system/):
  ✓ badge.tsx, button.tsx, card.tsx, dialog.tsx, etc.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
11. INTERNATIONALIZATION (i18n)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SETUP:
  Library:       next-intl 4.9.0
  Locales:       vi (Vietnamese), en (English)
  Route param:   [locale] prefix
  Translations:  /messages/ directory

USAGE:
  const t = useTranslations();
  <span>{t('key.path')}</span>

ROUTES:
  /vi/listings/[id]             ← Vietnamese
  /en/listings/[id]             ← English

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
12. PERFORMANCE OPTIMIZATIONS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

CODE SPLITTING:
  dynamic(() => import(...), { ssr: false })  ← Heavy components (maps, charts)

LAZY LOADING:
  loading: () => <Fallback />   ← Show UI while loading

IMAGE OPTIMIZATION:
  next/image                    ← Built-in optimization

CACHING:
  React Query query keys        ← Automatic deduplication & refetch intervals

CSS-IN-JS:
  Tailwind + CVA               ← Static + composable variants

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
13. KEY FILE PATHS REFERENCE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

NEIGHBORHOOD:
  lib/components/neighborhood/                          Components
  lib/components/neighborhood/types.ts                  Type definitions
  lib/components/neighborhood/neighborhood-poi-map.tsx  Mapbox POI layer
  lib/components/neighborhood/neighborhood-radar-chart.tsx  Radar scores

MAPPING:
  lib/mapbox-style.ts                                  Theme-aware styles
  lib/components/map/listing-map.tsx                   Listings on map
  lib/components/map/location-picker.tsx               Location selection

CHARTS:
  lib/components/charts/                               Chart components
  lib/components/charts/price-area-chart.tsx           Area trend chart

API & STATE:
  lib/api-client.ts                                    Base HTTP client
  lib/listings-api.ts                                  Listings endpoints
  lib/analytics-api.ts                                 Analytics endpoints
  lib/hooks/use-analytics.ts                           Analytics React Query hooks

LISTING DETAIL:
  app/[locale]/(public)/listings/[id]/page.tsx         Server component
  lib/components/listings/listing-detail-client.tsx    Client component (39 KB)

PROVIDERS:
  lib/components/providers/query-provider.tsx          React Query setup
  lib/components/providers/theme-provider.tsx          Theme management

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
14. CODING PATTERNS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

COMPONENT FILE HEADER:
  'use client'                   ← Client component marker
  import ...                     ← External imports
  import ...                     ← Internal imports
  
  interface ComponentProps { ... }  ← Props interface
  
  export function Component({ ... }: ComponentProps) {
    // implementation
  }

API CLIENT USAGE:
  const data = await apiClient.get<Type>('/endpoint');
  const result = await apiClient.post<Type>('/endpoint', body);

REACT QUERY HOOK:
  export function useData(param: string) {
    return useQuery({
      queryKey: ['key', param],
      queryFn: () => api.getData(param),
      enabled: !!param,  ← Conditional queries
    });
  }

COMPONENT IMPORTS:
  import dynamic from 'next/dynamic';
  const Map = dynamic(() => import('...').then(m => m.Component), {
    ssr: false,
    loading: () => <LoadingState />
  });

ZUSTAND STORE:
  import { create } from 'zustand';
  const useStore = create((set) => ({
    value: null,
    setValue: (v) => set({ value: v }),
  }));

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
15. DEBUGGING & DEVELOPMENT TIPS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ENV VARS:
  NEXT_PUBLIC_API_URL            ← Backend API base URL
  NEXT_PUBLIC_SITE_URL           ← Frontend base URL
  MAPBOX_ACCESS_TOKEN            ← Mapbox API key

SCRIPTS:
  npm run dev                    ← Start dev server (port 3000)
  npm run build                  ← Production build
  npm run lint                   ← ESLint
  npm test                       ← Vitest
  npm run typecheck              ← TypeScript check

HOT TIPS:
  • Dynamic imports reduce bundle size for heavy components
  • React Query keys are the foundation of caching strategy
  • Use CSS variables for theming (see design-system/)
  • Barrel exports (index.ts) for cleaner imports
  • Zustand for simple state, React Query for server state
  • Always check enabled condition in useQuery() for dependent queries

╔════════════════════════════════════════════════════════════════════════════╗
║ Report Generated: April 2026                                              ║
║ Base Path: /Users/velikho/Desktop/WORKING/goodgo-platform-ai/apps/web    ║
╚════════════════════════════════════════════════════════════════════════════╝
