dramaling-vocab-learning/frontend/hooks/flashcards/useFlashcardDetailData.ts

122 lines
3.7 KiB
TypeScript
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.

import { useState, useEffect } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import { flashcardsService, type Flashcard } from '@/lib/services/flashcards'
// 假資料 - 用於展示效果
const mockCards: {[key: string]: any} = {
'mock1': {
id: 'mock1',
word: 'hello',
translation: '你好',
partOfSpeech: 'interjection',
pronunciation: '/həˈloʊ/',
definition: 'A greeting word used when meeting someone or beginning a phone conversation',
example: 'Hello, how are you today?',
exampleTranslation: '你好,你今天怎麼樣?',
masteryLevel: 95,
timesReviewed: 15,
isFavorite: true,
nextReviewDate: '2025-09-21',
cardSet: { name: '基礎詞彙', color: 'bg-blue-500' },
cefr: 'A1',
createdAt: '2025-09-17',
synonyms: ['hi', 'greetings', 'good day'],
exampleImages: [],
hasExampleImage: false,
primaryImageUrl: null
},
'mock2': {
id: 'mock2',
word: 'elaborate',
translation: '詳細說明',
partOfSpeech: 'verb',
pronunciation: '/ɪˈlæbərət/',
definition: 'To explain something in more detail; to develop or present a theory, policy, or system in further detail',
example: 'Could you elaborate on your proposal?',
exampleTranslation: '你能詳細說明一下你的提案嗎?',
masteryLevel: 45,
timesReviewed: 5,
isFavorite: false,
nextReviewDate: '2025-09-19',
cardSet: { name: '高級詞彙', color: 'bg-purple-500' },
cefr: 'B2',
createdAt: '2025-09-14',
synonyms: ['explain', 'detail', 'expand', 'clarify'],
exampleImages: [],
hasExampleImage: false,
primaryImageUrl: null
}
}
interface UseFlashcardDetailDataReturn {
flashcard: Flashcard | null
loading: boolean
error: string | null
isEditing: boolean
editedCard: any
setFlashcard: (card: Flashcard | null) => void
setIsEditing: (editing: boolean) => void
setEditedCard: (card: any) => void
}
export const useFlashcardDetailData = (cardId: string): UseFlashcardDetailDataReturn => {
const router = useRouter()
const searchParams = useSearchParams()
const [flashcard, setFlashcard] = useState<Flashcard | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [isEditing, setIsEditing] = useState(false)
const [editedCard, setEditedCard] = useState<any>(null)
// 載入詞卡資料
useEffect(() => {
const loadFlashcard = async () => {
try {
setLoading(true)
// 首先檢查是否為假資料
if (mockCards[cardId]) {
setFlashcard(mockCards[cardId])
setEditedCard(mockCards[cardId])
setLoading(false)
return
}
// 載入真實詞卡 - 使用直接 API 調用
const result = await flashcardsService.getFlashcard(cardId)
if (result.success && result.data) {
setFlashcard(result.data)
setEditedCard(result.data)
} else {
throw new Error(result.error || '詞卡不存在')
}
} catch (err) {
setError('載入詞卡時發生錯誤')
} finally {
setLoading(false)
}
}
loadFlashcard()
}, [cardId])
// 檢查 URL 參數,自動開啟編輯模式
useEffect(() => {
if (searchParams.get('edit') === 'true' && flashcard) {
setIsEditing(true)
// 清理 URL 參數,保持 URL 乾淨
router.replace(`/flashcards/${cardId}`)
}
}, [flashcard, searchParams, cardId, router])
return {
flashcard,
loading,
error,
isEditing,
editedCard,
setFlashcard,
setIsEditing,
setEditedCard
}
}