129 lines
3.6 KiB
TypeScript
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
|
|
}
|
|
} |