92 lines
2.2 KiB
TypeScript
92 lines
2.2 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { useAuth } from "@/contexts/auth-context"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Heart } from "lucide-react"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
interface FavoriteButtonProps {
|
|
appId: string
|
|
initialFavorited?: boolean
|
|
onToggle?: (appId: string, isFavorited: boolean) => void
|
|
size?: "sm" | "md" | "lg"
|
|
variant?: "default" | "ghost" | "outline"
|
|
}
|
|
|
|
export function FavoriteButton({
|
|
appId,
|
|
initialFavorited = false,
|
|
onToggle,
|
|
size = "md",
|
|
variant = "ghost",
|
|
}: FavoriteButtonProps) {
|
|
const { user, isFavorite, toggleFavorite } = useAuth()
|
|
const [isFavorited, setIsFavorited] = useState(initialFavorited)
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
|
|
// 使用 isFavorite 的實時結果
|
|
const currentFavorited = user ? isFavorite(appId) : isFavorited
|
|
|
|
// 載入收藏狀態
|
|
useEffect(() => {
|
|
if (user) {
|
|
const favorited = isFavorite(appId)
|
|
setIsFavorited(favorited)
|
|
}
|
|
}, [user, appId, isFavorite])
|
|
|
|
const handleToggle = async () => {
|
|
if (!user) {
|
|
console.warn('用戶未登入,無法收藏')
|
|
return
|
|
}
|
|
|
|
setIsLoading(true)
|
|
|
|
try {
|
|
const newFavoriteState = await toggleFavorite(appId)
|
|
setIsFavorited(newFavoriteState)
|
|
|
|
// Call the callback if provided
|
|
onToggle?.(appId, newFavoriteState)
|
|
} catch (error) {
|
|
console.error("Failed to toggle favorite:", error)
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
const sizeClasses = {
|
|
sm: "h-8 w-8",
|
|
md: "h-9 w-9",
|
|
lg: "h-10 w-10",
|
|
}
|
|
|
|
const iconSizes = {
|
|
sm: "w-3 h-3",
|
|
md: "w-4 h-4",
|
|
lg: "w-5 h-5",
|
|
}
|
|
|
|
return (
|
|
<Button
|
|
variant={variant}
|
|
size="icon"
|
|
className={cn(sizeClasses[size], "transition-all duration-200", currentFavorited && "text-red-500 hover:text-red-600")}
|
|
onClick={handleToggle}
|
|
disabled={isLoading}
|
|
title={currentFavorited ? "取消收藏" : "加入收藏"}
|
|
>
|
|
<Heart
|
|
className={cn(
|
|
iconSizes[size],
|
|
"transition-all duration-200",
|
|
currentFavorited && "fill-current",
|
|
isLoading && "animate-pulse",
|
|
)}
|
|
/>
|
|
</Button>
|
|
)
|
|
}
|