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

129 lines
3.6 KiB
TypeScript

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { useToast } from '@/components/shared/Toast'
import { flashcardsService, type Flashcard } from '@/lib/services/flashcards'
interface UseFlashcardActionsOptions {
flashcard: Flashcard | null
editedCard: Partial<Flashcard> | null
onFlashcardUpdate: (updatedCard: Flashcard) => void
onEditingChange: (isEditing: boolean) => void
}
export function useFlashcardActions({
flashcard,
editedCard,
onFlashcardUpdate,
onEditingChange
}: UseFlashcardActionsOptions) {
const router = useRouter()
const toast = useToast()
const [isLoading, setIsLoading] = useState(false)
const toggleFavorite = async () => {
if (!flashcard) return
try {
setIsLoading(true)
// 假資料處理
if (flashcard.id.startsWith('mock')) {
const updated = { ...flashcard, isFavorite: !flashcard.isFavorite }
onFlashcardUpdate(updated)
toast.success(`${flashcard.isFavorite ? '已取消收藏' : '已加入收藏'}${flashcard.word}`)
return
}
// 真實API調用
const result = await flashcardsService.toggleFavorite(flashcard.id)
if (result.success) {
const updated = { ...flashcard, isFavorite: !flashcard.isFavorite }
onFlashcardUpdate(updated)
toast.success(`${flashcard.isFavorite ? '已取消收藏' : '已加入收藏'}${flashcard.word}`)
}
} catch (error) {
toast.error('操作失敗,請重試')
} finally {
setIsLoading(false)
}
}
const saveEdit = async () => {
if (!flashcard || !editedCard) return
try {
setIsLoading(true)
// 假資料處理
if (flashcard.id.startsWith('mock')) {
onFlashcardUpdate(editedCard as Flashcard)
onEditingChange(false)
toast.success('詞卡更新成功!')
return
}
// 真實API調用
const result = await flashcardsService.updateFlashcard(flashcard.id, {
word: editedCard.word!,
translation: editedCard.translation!,
definition: editedCard.definition!,
pronunciation: editedCard.pronunciation || '',
partOfSpeech: editedCard.partOfSpeech!,
example: editedCard.example!,
exampleTranslation: editedCard.exampleTranslation!,
cefr: editedCard.cefr!
})
if (result.success) {
onFlashcardUpdate(editedCard as Flashcard)
onEditingChange(false)
toast.success('詞卡更新成功!')
} else {
toast.error(result.error || '更新失敗')
}
} catch (error) {
toast.error('更新失敗,請重試')
} finally {
setIsLoading(false)
}
}
const deleteFlashcard = async () => {
if (!flashcard) return
if (!confirm(`確定要刪除詞卡「${flashcard.word}」嗎?`)) {
return
}
try {
setIsLoading(true)
// 假資料處理
if (flashcard.id.startsWith('mock')) {
toast.success('詞卡已刪除(模擬)')
router.push('/flashcards')
return
}
// 真實API調用
const result = await flashcardsService.deleteFlashcard(flashcard.id)
if (result.success) {
toast.success('詞卡已刪除')
router.push('/flashcards')
} else {
toast.error(result.error || '刪除失敗')
}
} catch (error) {
toast.error('刪除失敗,請重試')
} finally {
setIsLoading(false)
}
}
return {
toggleFavorite,
saveEdit,
deleteFlashcard,
isLoading
}
}