Skip to content

Dashboard — Implementation

Routing

React Router v7 (react-router-dom) handles client-side routing. Routes defined in App.tsx.

9 routes: / (Overview), /stock, /predictions, /news, /trends, /tickers, /portfolio, /account, /chat

AuthGuard wraps all authenticated routes — unauthenticated requests redirect to /login.

Data Fetching

  • TanStack Query v5 (@tanstack/react-query) manages all API calls: staleTime: 60_000, retry: 1
  • frontend/src/api/client.ts — thin fetch wrapper with credentials: "include" for cookie auth
  • Domain modules (prices.ts, news.ts, predictions.ts, etc.) call FastAPI endpoints and type responses

Market Filter Implementation

  • Overview / Stock Detail / Predictions / News Feed: filtering uses live ticker sets from load_ticker_sets(db) (FastAPI backend call, cached 60s) — frontend receives all data and filters client-side by ticker membership
  • Sector Trends: filtering is API-side — market query param passed to GET /trends/heat and GET /trends/alerts, which join SentimentScore to NewsArticle and filter on NewsArticle.market at DB level
  • Sector Sentiment chart (GET /trends/sectors): always cross-market — TrendingTopic has no market column
  • get_trending_alerts(db, n=5, days=3) from models/trend_analyzer.py
  • Heat score = mention_count × abs(avg_sentiment)
  • Each result includes up to 3 recent headlines with title, url, published_at, label
  • Cached 300s on the API side

Price Chart

  • Area/line chart — close >= period_open → green; otherwise red
  • Time range selector computes chart_days from a static map; re-fetches price history at selected depth
  • pre_df captures rows before the cutoff to derive prev_close for the reference line
  • Recharts; height 280px

Headline Translation

  • _get_display_title() selects the correct headline based on user's translation choice
  • title_en / title_ko are None until batch_translate() is called — components must handle null
  • One API call per page load for all missing translations (batch mode)

Gotchas

  • CORS: allowed origins default to localhost:5173,localhost:3000; override with the CORS_ORIGINS env var (comma-separated)
  • Sector Trends market filter is API-side — unlike other pages; see Market Filter section above
  • Vite proxy: /api requests proxied to localhost:8000 in dev; no path rewrite — the backend serves all routes under /api prefix
  • Production serving: api/main.py serves frontend/dist as a static SPA when the directory exists (built by Docker multi-stage or npm run build); the /assets mount must come before the catch-all /{full_path:path} route

Adding New UI Text

Add the string directly to the relevant React component in frontend/src/. For bilingual text, add both EN and KO variants inline in the component.