# T551 — fe-radar-today-page > Status: `done` > Milestone: `M3` > Kind: `feat` > Est. change: `~200 lines` ## Goal 完成後系統應:`/app/radar` 打開就看到今日統計列與高/中/低分組名單(低意向預設收合),0 筆時顯示原因與下一步。 ## Depends on - T502、T503、T545 ## Inputs - Spec:`../spec.md` §4.4、§5.3、§9.3(TD-01、TD-02) - 既有:`apps/web/src/pages/TodayPage.tsx`(版面語彙參考)、`src/components/ui/` ## Outputs ### 程式變更(預期路徑) | 路徑 | 動作 | 說明 | |------|------|------| | `apps/web/src/pages/RadarTodayPage.tsx` | add | 統計列+三個分組+截斷提示+空狀態 | | `apps/web/src/components/radar/OpportunityCard.tsx` | add | 五欄位卡片:原文摘要、分數、band badge、地區、發布距今 | | `apps/web/src/App.tsx` | edit | 註冊 `/app/radar` | | `apps/web/src/data/live/radarRepos.ts` | edit | today/opportunities 實作 | | `apps/web/src/styles/radar.css` | edit | 統計列與卡片樣式 | ### 行為變更 - 空狀態依後端 `empty_reason` 顯示對應原因與行動按鈕(去建服務檔案/去恢復 watch/放寬關鍵字/看失敗紀錄),**不得顯示空白頁**。 - 有 `truncated_count` 時顯示「已達今日上限,N 筆較低意向未收錄」。 - 發布距今由 `posted_at`(ns)在前端換算。 - 低意向分組預設收合,可展開。 ## Out of scope - 卡片動作與回覆面板(T552) - 側欄與手機底欄(T553) ## Acceptance - [x] 18 筆情境:統計與分組數字一致 - [x] 0 筆情境:六種 `empty_reason` 各有對應文案與動作 - [x] 指令: ```bash cd apps/web && npm run build && npm run check:tokens && npm run test && npm run lint ```