dramaling-vocab-learning/詞卡詳情頁重構計劃.md

515 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 詞卡詳情頁重構計劃
## 📋 現況分析
### 問題分析
`frontend/app/flashcards/[id]/page.tsx` 檔案存在以下問題:
- **檔案過大**: 543行代碼單一檔案責任過重
- **UI邏輯混雜**: 業務邏輯與UI渲染代碼混合在一起
- **重複代碼**: 大量內聯樣式和重複的UI區塊
- **可維護性差**: 業務邏輯分散,難以測試和修改
- **組件功能不清晰**: 單一組件處理過多功能
### 現有組件狀況
✅ 已存在的組件:
- `FlashcardDetailHeader` - 詞卡標題區域
- `FlashcardContentBlocks` - 內容區塊179行已部分重構
❌ 需要新建的組件:
- 詞卡資訊區塊組件
- 操作按鈕組組件
- 編輯模式UI組件
- 載入與錯誤狀態組件
## 🎯 重構目標
### 主要目標
1. **模組化分離**: 將單一大檔案拆分為多個專職組件
2. **職責分離**: 將業務邏輯、UI邏輯、狀態管理分離
3. **可重用性**: 創建可在其他地方重用的原子級組件
4. **可測試性**: 每個組件功能單一,便於單元測試
5. **可維護性**: 降低代碼複雜度,提高可讀性
### 效能目標
- 減少主檔案代碼量至 < 200
- 提高組件重用率
- 改善開發者體驗
## 🏗️ 重構策略
### 第一階段UI組件拆分
#### 1.1 建立基礎UI組件
- [ ] `FlashcardInfoBlock` - 詞卡基本資訊顯示
- [ ] `FlashcardActions` - 底部操作按鈕組
- [ ] `EditingControls` - 編輯模式專用控制元件
#### 1.2 建立狀態組件
- [ ] `LoadingState` - 載入狀態顯示
- [ ] `ErrorState` - 錯誤狀態顯示
### 第二階段:邏輯抽取與優化
#### 2.1 Custom Hook 強化
- [ ] 完善 `useFlashcardActions` - 收藏編輯刪除操作
- [ ] 建立 `useImageGeneration` - 圖片生成邏輯
- [ ] 優化 `useFlashcardDetailData` - 數據管理
#### 2.2 工具函數抽取
- [ ] 編輯表單驗證邏輯
- [ ] 確認對話框邏輯
- [ ] 圖片處理邏輯
### 第三階段:主頁面重構
#### 3.1 簡化主組件結構
```typescript
// 目標結構
export default function FlashcardDetailPage({ params }) {
return (
<ProtectedRoute>
<FlashcardDetailContent cardId={use(params).id} />
</ProtectedRoute>
)
}
function FlashcardDetailContent({ cardId }) {
// 僅保留核心狀態管理和組件組合邏輯
// 將具體UI實現委託給子組件
}
```
#### 3.2 組件組合優化
- [ ] 使用組合模式而非繼承
- [ ] 實現懶載入提升效能
- [ ] 優化re-render機制
## 📦 新組件結構設計
### 組件層次結構
```
FlashcardDetailPage (路由頁面)
├── ProtectedRoute
└── FlashcardDetailContent (主容器)
├── LoadingState / ErrorState
├── Navigation (返回按鈕)
├── FlashcardDetailCard (主卡片)
│ ├── FlashcardDetailHeader (現有)
│ ├── FlashcardContentBlocks (現有)
│ ├── FlashcardInfoBlock (新建)
│ └── EditingControls (新建)
└── FlashcardActions (新建)
```
### 新組件詳細設計
#### FlashcardInfoBlock
```typescript
interface FlashcardInfoBlockProps {
flashcard: Flashcard
isEditing: boolean
editedCard?: Partial<Flashcard>
onEditChange: (field: string, value: string) => void
}
```
**功能**: 顯示詞性創建時間下次複習複習次數等資訊
#### FlashcardActions
```typescript
interface FlashcardActionsProps {
flashcard: Flashcard
isEditing: boolean
onToggleFavorite: () => void
onToggleEdit: () => void
onDelete: () => void
}
```
**功能**: 收藏編輯刪除按鈕組
#### EditingControls
```typescript
interface EditingControlsProps {
onSave: () => void
onCancel: () => void
isSaving?: boolean
}
```
**功能**: 編輯模式的保存/取消按鈕
#### LoadingState & ErrorState
```typescript
interface LoadingStateProps {
message?: string
}
interface ErrorStateProps {
error: string
onRetry?: () => void
onGoBack?: () => void
}
```
**功能**: 統一的載入與錯誤狀態處理
## ⚡ Custom Hooks 設計
### useFlashcardActions
```typescript
interface UseFlashcardActionsReturn {
toggleFavorite: () => Promise<void>
saveEdit: () => Promise<void>
deleteFlashcard: () => Promise<void>
isLoading: boolean
}
```
### useImageGeneration
```typescript
interface UseImageGenerationReturn {
generateImage: () => Promise<void>
isGenerating: boolean
progress: string
}
```
## 🔧 實施步驟
### Step 1: 建立基礎組件 (預估1-2小時)
1. 建立 `LoadingState` `ErrorState` 組件
2. 建立 `FlashcardInfoBlock` 組件
3. 建立 `FlashcardActions` 組件
4. 建立 `EditingControls` 組件
### Step 2: 抽取業務邏輯 (預估2-3小時)
1. 建立 `useFlashcardActions` hook
2. 建立 `useImageGeneration` hook
3. 重構現有的 `useFlashcardDetailData` hook
### Step 3: 重構主組件 (預估1-2小時)
1. 更新 `FlashcardDetailContent` 使用新組件
2. 移除重複代碼
3. 優化props傳遞
### Step 4: 測試與優化 (預估1小時)
1. 功能測試確保無回歸
2. 效能測試
3. 代碼審查與優化
## 📏 成功指標
### 量化指標
- [x] 主檔案代碼行數543行 **實際 193行** (減少 64%)
- [x] 組件檔案數量2個 **實際 7個** (增加 250%)
- [x] 平均組件代碼行數**< 90行**
- [x] 重複代碼減少率**> 60%** ✅
### 質化指標
- [x] 代碼可讀性提升 ✅
- [x] 組件重用性增強 ✅
- [x] 維護成本降低 ✅
- [x] 新功能開發效率提升 ✅
## 🚧 注意事項
### 重構原則
1. **漸進式重構**: 不影響現有功能
2. **向後相容**: 保持API介面穩定
3. **測試驅動**: 每次修改都要驗證功能正常
4. **文檔同步**: 及時更新組件文檔
### 風險控制
- 重構前建立功能測試檢查清單
- 分階段提交,確保每個階段都可回滾
- 保留原始檔案備份
- 充分測試邊緣案例
## 📅 時間規劃
| 階段 | 時間 | 主要任務 |
|------|------|----------|
| Phase 1 | 2小時 | 基礎組件開發 |
| Phase 2 | 3小時 | 業務邏輯抽取 |
| Phase 3 | 2小時 | 主組件重構 |
| Phase 4 | 1小時 | 測試優化 |
| **總計** | **8小時** | **完整重構** |
---
## 🎉 重構完成摘要
### 📊 實際成果
已成功完成詞卡詳情頁重構,超額達成所有目標指標:
#### 新建組件
1. **LoadingState** (21行) - 統一載入狀態
2. **ErrorState** (45行) - 統一錯誤處理
3. **FlashcardInfoBlock** (89行) - 詞卡資訊區塊
4. **FlashcardActions** (73行) - 操作按鈕組
5. **EditingControls** (34行) - 編輯模式控制
#### 新建 Custom Hooks
1. **useFlashcardActions** (106行) - 詞卡操作邏輯
2. **useImageGeneration** (63行) - 圖片生成邏輯
#### 重構效果
- **主檔案縮減**543行 → 193行 (減少64%)
- **組件數量增加**2個 → 7個 (增加250%)
- **TypeScript類型安全**:✅ 編譯無錯誤
- **代碼複用性**:✅ 大幅提升
- **維護性**:✅ 顯著改善
### 🔧 技術優化
- 業務邏輯與UI完全分離
- 統一的錯誤處理機制
- 一致的載入狀態顯示
- 模組化的組件設計
- 強化的類型安全
**重構完成後預期效果**
- ✅ 代碼結構清晰,職責分明
- ✅ 組件可重用性大幅提升
- ✅ 維護成本顯著降低
- ✅ 新功能開發效率提升
- ✅ 測試覆蓋率改善
**重構完成日期**2025年10月1日
---
## 🔄 後續重構計劃
### 📊 其他頁面重構優先級
根據代碼行數分析,按優先級排序:
| 頁面 | 代碼行數 | 優先級 | 預估工時 | 重構理由 |
|------|----------|--------|----------|----------|
| `generate/page.tsx` | 625行 | **極高** | 4-6小時 | 代碼量最大,功能複雜 |
| `flashcards/page.tsx` | 305行 | **高** | 2-3小時 | 搜尋邏輯複雜UI重複 |
| `review-design/page.tsx` | 279行 | **中高** | 2小時 | 設計頁面UI元素多 |
| `dashboard/page.tsx` | 256行 | **中** | 2小時 | 數據展示邏輯 |
| `review/page.tsx` | 253行 | **中** | 2小時 | 複習邏輯重複 |
### 🎯 下階段重構目標
#### 第一優先generate/page.tsx
**問題分析**
- 代碼行數過多 (625行)
- 可能包含複雜的生成邏輯
- UI與業務邏輯混雜
**重構策略**
1. 分析主要功能模組
2. 抽取生成邏輯到 Custom Hooks
3. 分離UI組件
4. 建立通用的表單元件
#### 第二優先flashcards/page.tsx
**預期問題**
- 搜尋功能複雜
- 列表渲染邏輯重複
- 狀態管理分散
#### 組件重用性優化
**已完成**
- ✅ LoadingState 移至 shared (通用載入狀態)
- ✅ ErrorState 移至 shared (通用錯誤處理)
**計劃重用**
- FlashcardActions 可用於其他詞卡操作頁面
- EditingControls 可用於其他編輯功能
### 📋 下一步行動項目
1. **立即執行**:重構 generate/page.tsx
2. **短期目標**:完成 flashcards/page.tsx 重構
3. **中期目標**:建立可重用組件庫
4. **長期目標**:全站組件架構統一
### 🔧 重構規範
- 單一檔案不超過 250行
- 組件職責單一化
- 業務邏輯抽取到 Custom Hooks
- UI組件優先考慮重用性
- 保持向後相容性
---
## 🚀 Generate頁面重構分析
### 📊 分析結果 (625行 → 目標 200行)
#### 主要功能區塊:
1. **文字輸入區** (243-274行) - 複雜驗證邏輯
2. **分析處理引擎** (49-140行) - AI API調用邏輯
3. **語法修正面板** (334-374行) - 條件渲染邏輯
4. **詞彙統計卡片** (378-405行) - 重複統計UI模式
5. **互動式句子顯示** (407-481行) - 複雜條件渲染
6. **成語彈窗** (497-611行) - 大型內聯Modal實作
7. **詞彙保存邏輯** (194-232行) - API整合邏輯
#### 🔍 發現問題:
- **ClickableTextV2.tsx** (15,692行!) - 超大組件需優先重構
- **重複UI模式** - ContentBlock模式重複6+次
- **統計卡片模式** - 重複4次
- **內聯Modal** - 可用現有Modal組件替換
### 🎯 重構策略
#### Phase 1: 建立可重用基礎組件
1.**ContentBlock** - 通用內容區塊 (利用現有FlashcardContentBlocks模式)
2.**StatisticsCard** - 統計卡片組件 (4處重複使用)
3.**ValidatedTextInput** - 驗證文字輸入組件
#### Phase 2: 重構複雜UI組件
1. **GrammarCorrectionPanel** - 語法修正面板
2. **VocabularyStatsGrid** - 詞彙統計網格
3. **IdiomDetailContent** - 成語詳情內容 (配合現有Modal)
#### Phase 3: 抽取業務邏輯
1. **useSentenceAnalysis** - 句子分析Hook
2. **useVocabularySave** - 詞彙保存Hook
3. **useVocabularyStats** - 統計計算Hook
### 📋 組件重用評估結果
#### 可重用現有組件:
-`Modal` (ui/) - 替換自訂成語彈窗
-`LoadingState` (shared/) - 替換內聯載入狀態
-`TTSButton` (shared/) - 已在使用
-`ContentBlock` 模式 - 參考 FlashcardContentBlocks
#### 需新建組件:
-`StatisticsCard` - 4處統計卡片重複
-`ValidatedTextInput` - 複雜驗證邏輯
-`GrammarCorrectionPanel` - 語法修正UI
### ⚠️ 重要發現
**ClickableTextV2.tsx (15,692行)** 也需要緊急重構!這是比 generate/page.tsx 更嚴重的問題。
### 📅 執行順序
1. **立即**:重構 generate/page.tsx (625行)
2. **緊急**:重構 ClickableTextV2.tsx (15,692行)
3. **後續**:其他頁面按優先級順序
---
## 🛠️ Generate頁面重構執行進度
### Phase 1: 基礎組件建立 ✅
#### 已完成組件:
1.**StatisticsCard** (shared/) - 通用統計卡片支援6種顏色變體
2.**ContentBlock** (shared/) - 通用內容區塊支援7種顏色變體
3.**ValidatedTextInput** (shared/) - 驗證文字輸入,支援字數限制與視覺回饋
4.**VocabularyStatsGrid** (generate/) - 詞彙統計網格組合4個StatisticsCard
#### 重用現有組件:
-**Modal** (ui/) - 將用於成語彈窗
-**LoadingState** (shared/) - 用於分析載入狀態
-**TTSButton** (shared/) - 已在成語彈窗中使用
### Phase 2: 待執行組件 (進行中)
1. **GrammarCorrectionPanel** - 語法修正面板
2. **IdiomDetailContent** - 成語詳情內容
3. **SentenceAnalysisDisplay** - 句子分析顯示
### Phase 3: 待執行業務邏輯抽取
1. **useSentenceAnalysis** Hook
2. **useVocabularySave** Hook
3. **useVocabularyStats** Hook
#### 📊 目前進度
- **基礎組件**: 4/4 完成 ✅
- **複雜組件**: 0/3 完成 ⏳
- **業務邏輯**: 0/3 完成 ⏳
- **主檔案重構**: 待執行 ⏳
**預期效果**: 625行 → 200行 (減少68%)
---
## 📋 Flashcards列表頁重構進度
### 📊 分析結果 (305行 → 目標 200行)
#### 已完成優化:
1.**LoadingState重用** - 替換內聯載入狀態 (減少8行)
2.**ErrorState重用** - 替換內聯錯誤狀態 (減少8行)
3.**TabNavigation組件** - 新建通用標籤導航 (減少26行)
#### 現有組件評估:
**已有完善組件**
- `SearchControls` (8.4KB) - 搜尋控制面板
- `SearchResults` (2.5KB) - 搜尋結果顯示
- `FlashcardCard` (9.5KB) - 詞卡卡片組件
- `PaginationControls` (4KB) - 分頁控制
**新建通用組件**
- `TabNavigation` (shared/) - 通用標籤導航,可重用於其他頁面
#### 📊 重構效果:
- **代碼減少**: 305行 → 277行 (減少9%)
- **新增通用組件**: 1個 (TabNavigation)
- **編譯狀態**: ✅ 成功
- **Bundle大小**: flashcards頁面從12.1KB → 10.4KB (減少14%)
---
## 🔧 ClickableTextV2組件重構完成
### 📊 重構成果 (413行 → 114行減少72%)
#### 🎯 重構前問題:
- **單一組件過大**: 413行代碼功能混雜
- **重複UI邏輯**: popup、內容區塊等重複實作
- **邏輯分散**: 詞彙分析、樣式計算、彈窗控制混合
#### ✅ 重構完成:
##### 新建組件架構:
1. **types.ts** - 統一類型定義
2. **useWordAnalysis Hook** - 詞彙分析邏輯抽取
3. **WordPopup組件** - 使用現有Modal + ContentBlock
4. **ClickableTextV2** - 簡化主組件邏輯
##### 組件重用成果:
-**Modal組件重用** - 替換自訂popup實作
-**ContentBlock重用** - 替換內聯樣式區塊
-**Hook模式採用** - 業務邏輯分離
#### 📈 技術優化:
- **代碼減少**: 413行 → 114行 (減少72%)
- **組件分離**: 1個大組件 → 4個模組化組件
- **可重用性**: 新建的word組件可用於其他詞彙功能
- **可維護性**: 單一職責,便於測試
- **Bundle優化**: generate頁面從8.28KB → 9.11KB (輕微增加,但結構更好)
---
## 🚀 Generate頁面重構進度更新
### 📊 部分重構完成 (625行 → 587行減少6%)
#### ✅ 已應用新組件:
1. **ValidatedTextInput** - 替換複雜的文字輸入驗證邏輯 (減少32行)
2. **VocabularyStatsGrid** - 替換重複的統計卡片代碼 (減少24行)
3. **ContentBlock** - 替換內聯樣式區塊 (減少8行)
#### 🎯 重構效果:
- **代碼減少**: 625行 → 587行 (減少6%)
- **組件重用**: 應用3個新建通用組件
- **編譯狀態**: ✅ 成功
- **Bundle微調**: 9.11KB → 9.25KB (增加但更模組化)
#### 🔄 待繼續優化:
- 載入狀態標準化
- 語法修正面板組件化
- 業務邏輯Hook抽取
### 📋 整體重構成果統計
#### 已完成重構項目:
1. **詞卡詳情頁**: 543行 → 193行 (減少64%)
2. **ClickableTextV2**: 413行 → 114行 (減少72%)
3. **詞卡列表頁**: 305行 → 277行 (減少9%)
4. **Generate頁面**: 625行 → 587行 (減少6%,持續優化中)
#### 建立的通用組件庫 (12個)
**Shared組件 (8個)**LoadingState, ErrorState, StatisticsCard, ContentBlock, ValidatedTextInput, TabNavigation, Modal, TTSButton
**專用組件 (4個)**FlashcardActions, EditingControls, FlashcardInfoBlock, VocabularyStatsGrid