CD 修復: - 修復 buildx HTTP vs HTTPS 問題 (insecure registry 設定) - 移除 UAT 環境 (違反 Memory 鐵律) - 新增 Production 部署 Telegram 通知 - 修復 deploy-prod.yml 硬編碼 Token (改用 secrets) docs: - 新增 guidelines/ 結構化指引目錄 - ARCHITECTURE.md, FRONTEND.md, OPERATIONS.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
160 lines
3.0 KiB
Markdown
160 lines
3.0 KiB
Markdown
# AWOOOI 前端指引
|
||
|
||
> 前端開發的核心原則與規範
|
||
|
||
## 快速索引
|
||
|
||
| 主題 | 核心原則 | 詳細章節 |
|
||
|------|---------|---------|
|
||
| i18n | 100% next-intl,零硬編碼 | [→ i18n](#i18n-雙語) |
|
||
| 視覺 | Nothing.tech 風格 | [→ 視覺規範](#視覺規範) |
|
||
| 狀態 | Zustand (禁止 Redux) | [→ 狀態管理](#狀態管理) |
|
||
| 數據 | 真實 API,禁止假數據 | [→ 數據規範](#數據規範) |
|
||
|
||
---
|
||
|
||
## i18n 雙語
|
||
|
||
**Memory 來源:** `feedback_i18n_zero_hardcode.md`, `feedback_naming_i18n.md`
|
||
|
||
### 鐵律
|
||
|
||
```tsx
|
||
// ❌ 禁止 - 任何硬編碼文字
|
||
<button>Submit</button>
|
||
<span>Loading...</span>
|
||
<p>System Status</p>
|
||
|
||
// ✅ 正確 - 100% next-intl
|
||
<button>{t('common.submit')}</button>
|
||
<span>{t('common.loading')}</span>
|
||
<p>{t('dashboard.systemStatus')}</p>
|
||
```
|
||
|
||
### 支援語言
|
||
|
||
- `zh-TW` - 繁體中文 (預設)
|
||
- `en` - English
|
||
|
||
### 翻譯檔位置
|
||
|
||
```
|
||
apps/web/src/messages/
|
||
├── zh-TW.json
|
||
└── en.json
|
||
```
|
||
|
||
### 新增翻譯流程
|
||
|
||
1. 在 `zh-TW.json` 新增 key
|
||
2. 在 `en.json` 新增對應翻譯
|
||
3. 在組件使用 `t('your.key')`
|
||
|
||
---
|
||
|
||
## 視覺規範
|
||
|
||
**Memory 來源:** `feedback_naming_i18n.md`
|
||
|
||
### Nothing.tech 風格
|
||
|
||
```
|
||
- 白玻璃毛玻璃效果 (awoooi-glass)
|
||
- 點陣紋理背景
|
||
- DataPincer 數據鉗容器
|
||
- 黑白紅極簡配色
|
||
```
|
||
|
||
### 顏色系統
|
||
|
||
```css
|
||
/* 主色 */
|
||
--nothing-black: #000000
|
||
--nothing-white: #ffffff
|
||
--claw-red: #ff0000
|
||
|
||
/* 狀態色 */
|
||
--status-healthy: #00ff00
|
||
--status-warning: #ffaa00
|
||
--status-critical: #ff0000
|
||
```
|
||
|
||
### 組件規範
|
||
|
||
```tsx
|
||
// DataPincerPanel - 標準容器
|
||
<DataPincerPanel title={t('dashboard.title')} status="healthy">
|
||
{children}
|
||
</DataPincerPanel>
|
||
|
||
// DataPincerCard - 卡片容器
|
||
<DataPincerCard>
|
||
{content}
|
||
</DataPincerCard>
|
||
```
|
||
|
||
---
|
||
|
||
## 狀態管理
|
||
|
||
**Memory 來源:** ADR-004
|
||
|
||
### 鐵律
|
||
|
||
```tsx
|
||
// ❌ 禁止 - Redux
|
||
import { useSelector } from 'react-redux'
|
||
|
||
// ✅ 正確 - Zustand
|
||
import { useStore } from '@/stores/xxx.store'
|
||
```
|
||
|
||
### Store 結構
|
||
|
||
```
|
||
apps/web/src/stores/
|
||
├── agent.store.ts - Agent 狀態
|
||
├── incident.store.ts - Incident 狀態
|
||
└── ui.store.ts - UI 狀態
|
||
```
|
||
|
||
---
|
||
|
||
## 數據規範
|
||
|
||
**Memory 來源:** `feedback_no_fake_data.md`
|
||
|
||
### 鐵律
|
||
|
||
```tsx
|
||
// ❌ 禁止 - 假數據
|
||
const data = DEMO_DATA
|
||
const mockMetrics = generateMockData()
|
||
|
||
// ✅ 正確 - 真實 API
|
||
const { data } = useRealAPI()
|
||
const { metrics } = useGlobalPulseMetrics()
|
||
```
|
||
|
||
### 2026-03-23 教訓
|
||
|
||
`GlobalPulseChartDemo` 使用假數據,導致用戶無法看到真實系統狀態。已修正為 `GlobalPulseChart` 連接真實 API。
|
||
|
||
### Loading/Error 處理
|
||
|
||
```tsx
|
||
const { data, isLoading, error } = useAPI()
|
||
|
||
if (isLoading) return <Spinner />
|
||
if (error) return <ErrorState message={error} />
|
||
return <RealData data={data} />
|
||
```
|
||
|
||
---
|
||
|
||
## 相關 ADR
|
||
|
||
- [ADR-002: Nothing.tech 設計系統](adr/ADR-002-nothing-tech-design-system.md)
|
||
- [ADR-004: 狀態管理 (Zustand)](adr/ADR-004-state-management.md)
|
||
- [UX-001: Incident Card Fatigue](design/UX-001-incident-card-fatigue.md)
|