270 lines
7.1 KiB
Markdown
270 lines
7.1 KiB
Markdown
# Flashcards 頁面重構計劃
|
||
|
||
**目標**: 將 898行的 flashcards/page.tsx 重構為可維護的模組化架構
|
||
**當前問題**: 單一檔案過大,責任過多,難以維護
|
||
|
||
---
|
||
|
||
## 📊 **現況分析**
|
||
|
||
### 🚨 **嚴重性評估**
|
||
- **檔案大小**: 898行 (超標 4.5倍,建議 <200行)
|
||
- **複雜度**: 高 - 包含多個獨立功能模組
|
||
- **維護性**: 低 - 修改風險高,測試困難
|
||
|
||
### 🔍 **功能分析**
|
||
1. **搜尋與篩選** (~150行)
|
||
2. **詞卡列表顯示** (~200行)
|
||
3. **圖片生成邏輯** (~100行)
|
||
4. **表單管理** (~100行)
|
||
5. **狀態管理** (~150行)
|
||
6. **UI交互邏輯** (~200行)
|
||
|
||
---
|
||
|
||
## 🎯 **重構目標架構**
|
||
|
||
### 📁 **新的檔案結構**
|
||
```
|
||
/app/flashcards/
|
||
├── page.tsx (~150行) 主頁面容器
|
||
└── components/
|
||
├── FlashcardList.tsx (~120行) 詞卡列表組件
|
||
├── SearchFilters.tsx (~100行) 搜尋篩選器
|
||
├── FlashcardActions.tsx (~80行) 操作按鈕群組
|
||
└── ImageGenerationDialog.tsx (~100行) 圖片生成對話框
|
||
|
||
/hooks/flashcards/
|
||
├── useFlashcardActions.ts (~80行) 操作邏輯Hook
|
||
└── useImageGeneration.ts (~60行) 圖片生成Hook
|
||
|
||
/lib/utils/
|
||
└── flashcardUtils.ts (~40行) 工具函數
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 **詳細重構方案**
|
||
|
||
### 1. **主頁面容器** (`page.tsx`)
|
||
**目標大小**: ~150行
|
||
**責任範圍**:
|
||
- 路由控制和認證
|
||
- 頂層狀態管理
|
||
- 組件組合和佈局
|
||
|
||
**保留內容**:
|
||
```typescript
|
||
// 頂層狀態
|
||
const [activeTab, setActiveTab] = useState<'all-cards' | 'favorites'>('all-cards')
|
||
const [showForm, setShowForm] = useState(false)
|
||
|
||
// 主要佈局結構
|
||
return (
|
||
<ProtectedRoute>
|
||
<Navigation />
|
||
<SearchFilters />
|
||
<FlashcardList />
|
||
<FlashcardActions />
|
||
</ProtectedRoute>
|
||
)
|
||
```
|
||
|
||
### 2. **詞卡列表組件** (`FlashcardList.tsx`)
|
||
**目標大小**: ~120行
|
||
**責任範圍**:
|
||
- 詞卡卡片渲染
|
||
- 分頁控制
|
||
- 載入狀態顯示
|
||
|
||
**核心邏輯**:
|
||
```typescript
|
||
interface FlashcardListProps {
|
||
flashcards: Flashcard[]
|
||
pagination: PaginationState
|
||
onCardClick: (id: string) => void
|
||
onImageGenerate: (id: string) => void
|
||
}
|
||
```
|
||
|
||
### 3. **搜尋篩選器** (`SearchFilters.tsx`)
|
||
**目標大小**: ~100行
|
||
**責任範圍**:
|
||
- 搜尋輸入框
|
||
- 篩選下拉選單
|
||
- 排序控制
|
||
- 進階搜尋切換
|
||
|
||
**介面定義**:
|
||
```typescript
|
||
interface SearchFiltersProps {
|
||
searchState: SearchState
|
||
searchActions: SearchActions
|
||
showAdvanced: boolean
|
||
onToggleAdvanced: () => void
|
||
}
|
||
```
|
||
|
||
### 4. **操作按鈕群組** (`FlashcardActions.tsx`)
|
||
**目標大小**: ~80行
|
||
**責任範圍**:
|
||
- 新增詞卡按鈕
|
||
- 批量操作按鈕
|
||
- 匯入/匯出功能
|
||
|
||
### 5. **圖片生成對話框** (`ImageGenerationDialog.tsx`)
|
||
**目標大小**: ~100行
|
||
**責任範圍**:
|
||
- 圖片生成進度顯示
|
||
- 生成參數設定
|
||
- 狀態輪詢管理
|
||
|
||
---
|
||
|
||
## 🎣 **Custom Hooks 設計**
|
||
|
||
### 1. **useFlashcardActions**
|
||
```typescript
|
||
// 操作邏輯封裝
|
||
export const useFlashcardActions = () => {
|
||
const handleEdit = (id: string) => { /* 編輯邏輯 */ }
|
||
const handleDelete = (id: string) => { /* 刪除邏輯 */ }
|
||
const handleFavorite = (id: string) => { /* 收藏邏輯 */ }
|
||
|
||
return { handleEdit, handleDelete, handleFavorite }
|
||
}
|
||
```
|
||
|
||
### 2. **useImageGeneration**
|
||
```typescript
|
||
// 圖片生成邏輯封裝
|
||
export const useImageGeneration = () => {
|
||
const [generating, setGenerating] = useState<Set<string>>(new Set())
|
||
const [progress, setProgress] = useState<{[id: string]: string}>({})
|
||
|
||
const generateImage = async (flashcardId: string) => { /* 生成邏輯 */ }
|
||
|
||
return { generating, progress, generateImage }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🛠️ **工具函數提取**
|
||
|
||
### `flashcardUtils.ts`
|
||
```typescript
|
||
// 詞性顯示轉換
|
||
export const getPartOfSpeechDisplay = (partOfSpeech: string): string => { ... }
|
||
|
||
// CEFR顏色獲取
|
||
export const getCEFRColor = (level: string): string => { ... }
|
||
|
||
// 熟練度顏色獲取
|
||
export const getMasteryColor = (level: number): string => { ... }
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 **重構執行計劃**
|
||
|
||
### **階段一**: 工具函數提取 (30分鐘)
|
||
1. ✅ 創建 `lib/utils/flashcardUtils.ts`
|
||
2. ✅ 移動工具函數
|
||
3. ✅ 更新import引用
|
||
|
||
### **階段二**: Custom Hooks 分離 (45分鐘)
|
||
1. ✅ 創建 `useFlashcardActions.ts`
|
||
2. ✅ 創建 `useImageGeneration.ts`
|
||
3. ✅ 從主組件中提取邏輯
|
||
|
||
### **階段三**: UI組件拆分 (1小時)
|
||
1. ✅ 創建 `SearchFilters.tsx`
|
||
2. ✅ 創建 `FlashcardList.tsx`
|
||
3. ✅ 創建 `FlashcardActions.tsx`
|
||
4. ✅ 創建 `ImageGenerationDialog.tsx`
|
||
|
||
### **階段四**: 主頁面重構 (30分鐘)
|
||
1. ✅ 簡化主組件邏輯
|
||
2. ✅ 整合新的子組件
|
||
3. ✅ 測試功能完整性
|
||
|
||
### **階段五**: 測試與優化 (15分鐘)
|
||
1. ✅ 編譯測試
|
||
2. ✅ 功能測試
|
||
3. ✅ 效能驗證
|
||
|
||
---
|
||
|
||
## 🎯 **預期成果**
|
||
|
||
### 📊 **量化目標**
|
||
- **主檔案**: 898行 → ~150行 (減少83%)
|
||
- **組件數量**: 1個 → 5個 (模組化)
|
||
- **單一責任**: ✅ 每個組件職責明確
|
||
- **可測試性**: ✅ 組件獨立可測
|
||
|
||
### 🚀 **品質提升**
|
||
- **可維護性**: 🔴 → 🟢 (大幅提升)
|
||
- **可讀性**: 🟡 → 🟢 (結構清晰)
|
||
- **可擴展性**: 🟡 → 🟢 (易於添加功能)
|
||
- **測試覆蓋**: 🔴 → 🟢 (組件化便於測試)
|
||
|
||
### 💡 **開發體驗**
|
||
- **修改局部性**: 修改特定功能時只需要動對應組件
|
||
- **協作友善**: 多人開發時減少衝突
|
||
- **debugging**: 問題定位更精確
|
||
|
||
---
|
||
|
||
## ⚠️ **風險控制**
|
||
|
||
### 🔴 **潛在風險**
|
||
1. **狀態管理複雜化**: 跨組件狀態傳遞
|
||
2. **Props Drilling**: 深層組件傳值問題
|
||
3. **功能回歸**: 重構過程中功能遺失
|
||
|
||
### 🛡️ **緩解策略**
|
||
1. **漸進式重構**: 一次拆分一個組件
|
||
2. **保持向下相容**: 確保API接口不變
|
||
3. **充分測試**: 每個階段完成後立即測試
|
||
4. **備份計劃**: Git commit 每個主要階段
|
||
|
||
---
|
||
|
||
## 📚 **最佳實踐應用**
|
||
|
||
### 🎨 **設計原則**
|
||
- **單一責任原則**: 每個組件只負責一個核心功能
|
||
- **組合優於繼承**: 通過組合小組件構建複雜功能
|
||
- **Props接口明確**: 清晰定義組件間的數據流
|
||
|
||
### 🔄 **狀態管理策略**
|
||
- **狀態上提**: 共享狀態提升到最近的共同父組件
|
||
- **局部狀態**: 組件特定狀態保持在組件內部
|
||
- **Hook封裝**: 複雜邏輯封裝到自定義Hook
|
||
|
||
---
|
||
|
||
## 🎉 **重構價值**
|
||
|
||
### 💼 **商業價值**
|
||
- **開發效率**: 提升 50%+ (組件化開發)
|
||
- **維護成本**: 降低 60%+ (責任明確)
|
||
- **新功能開發**: 加速 40%+ (可復用組件)
|
||
|
||
### 🏗️ **技術價值**
|
||
- **代碼品質**: 企業級標準
|
||
- **架構清晰**: 易於理解和擴展
|
||
- **測試友善**: 單元測試覆蓋率可達 80%+
|
||
|
||
---
|
||
|
||
**準備開始重構嗎?建議分階段執行,確保每個步驟都穩定可靠!**
|
||
|
||
---
|
||
|
||
**生成時間**: 2025-10-01 18:15
|
||
**預估工時**: 2.5小時
|
||
**風險等級**: 🟡 中風險 (有完整計劃)
|
||
**推薦執行**: ✅ 立即開始 |