163 lines
5.5 KiB
TypeScript
163 lines
5.5 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from "react"
|
||
import { Button } from "@/components/ui/button"
|
||
import {
|
||
Dialog,
|
||
DialogContent,
|
||
DialogDescription,
|
||
DialogFooter,
|
||
DialogHeader,
|
||
DialogTitle,
|
||
DialogTrigger,
|
||
} from "@/components/ui/dialog"
|
||
import { Badge } from "@/components/ui/badge"
|
||
import { Eye, Edit, Award, Zap, Gift, Heart, Coins, Shirt, BadgeCheck } from "lucide-react"
|
||
import type { Achievement } from "@/lib/api/types"
|
||
|
||
type AchievementDetailDialogProps = {
|
||
achievement: Achievement
|
||
onEdit?: () => void
|
||
}
|
||
|
||
export function AchievementDetailDialog({ achievement, onEdit }: AchievementDetailDialogProps) {
|
||
const [open, setOpen] = useState(false)
|
||
|
||
const getCategoryColor = (category: string) => {
|
||
switch (category) {
|
||
case "互动":
|
||
return "bg-blue-500"
|
||
case "好感度":
|
||
return "bg-pink-500"
|
||
case "收集":
|
||
return "bg-purple-500"
|
||
case "探索":
|
||
return "bg-green-500"
|
||
case "特殊":
|
||
return "bg-amber-500"
|
||
case "隐藏":
|
||
return "bg-gray-500"
|
||
default:
|
||
return "bg-gray-500"
|
||
}
|
||
}
|
||
|
||
const getRewardIcon = (rewardType: string) => {
|
||
switch (rewardType) {
|
||
case "经验值":
|
||
return <Zap className="h-5 w-5 text-blue-500" />
|
||
case "好感度":
|
||
return <Heart className="h-5 w-5 text-pink-500" />
|
||
case "虚拟币":
|
||
return <Coins className="h-5 w-5 text-amber-500" />
|
||
case "道具":
|
||
return <Gift className="h-5 w-5 text-purple-500" />
|
||
case "服装":
|
||
return <Shirt className="h-5 w-5 text-teal-500" />
|
||
case "称号":
|
||
return <BadgeCheck className="h-5 w-5 text-indigo-500" />
|
||
default:
|
||
return <Gift className="h-5 w-5 text-gray-500" />
|
||
}
|
||
}
|
||
|
||
const getIconComponent = (iconName: string) => {
|
||
// 这里可以根据iconName返回对应的Lucide图标
|
||
// 简化处理,默认返回Award图标
|
||
return <Award className="h-6 w-6 text-amber-500" />
|
||
}
|
||
|
||
return (
|
||
<Dialog open={open} onOpenChange={setOpen}>
|
||
<DialogTrigger asChild>
|
||
<Button variant="ghost" size="icon" className="hover:bg-amber-50 hover:text-amber-600">
|
||
<Eye className="h-4 w-4" />
|
||
</Button>
|
||
</DialogTrigger>
|
||
<DialogContent className="sm:max-w-[600px]">
|
||
<DialogHeader>
|
||
<DialogTitle className="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-amber-600 to-orange-600">
|
||
成就详情
|
||
</DialogTitle>
|
||
<DialogDescription>查看成就的详细信息和解锁条件</DialogDescription>
|
||
</DialogHeader>
|
||
|
||
<div className="py-4">
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<div className="h-16 w-16 rounded-full bg-amber-100 flex items-center justify-center">
|
||
{achievement.icon ? getIconComponent(achievement.icon) : <Award className="h-8 w-8 text-amber-500" />}
|
||
</div>
|
||
<div>
|
||
<h3 className="text-xl font-bold">{achievement.name}</h3>
|
||
<div className="flex items-center gap-2 mt-1">
|
||
<Badge className={getCategoryColor(achievement.category)}>{achievement.category}</Badge>
|
||
{achievement.isHidden && <Badge className="bg-gray-500">隐藏成就</Badge>}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="space-y-4">
|
||
<div className="p-4 bg-amber-50 rounded-lg">
|
||
<h4 className="font-medium text-amber-700 mb-2">成就描述</h4>
|
||
<p>{achievement.description}</p>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div className="space-y-1">
|
||
<div className="text-sm text-gray-500">解锁条件</div>
|
||
<p className="font-medium">{achievement.requirement}</p>
|
||
</div>
|
||
|
||
<div className="space-y-1">
|
||
<div className="text-sm text-gray-500">解锁率</div>
|
||
<p className="font-medium">{achievement.unlockRate ? `${achievement.unlockRate}%` : "未知"}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="p-4 bg-gradient-to-r from-amber-50 to-orange-50 rounded-lg">
|
||
<h4 className="font-medium text-amber-700 mb-3">奖励</h4>
|
||
<div className="flex items-center gap-3">
|
||
{getRewardIcon(achievement.rewardType)}
|
||
<div>
|
||
<p className="font-medium">
|
||
{achievement.rewardType} x {achievement.rewardAmount}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-2 gap-4 text-sm text-gray-500">
|
||
<div>
|
||
<span>创建时间: </span>
|
||
<span className="font-medium">{achievement.createdAt}</span>
|
||
</div>
|
||
<div>
|
||
<span>更新时间: </span>
|
||
<span className="font-medium">{achievement.updatedAt}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<DialogFooter>
|
||
<Button variant="outline" onClick={() => setOpen(false)}>
|
||
关闭
|
||
</Button>
|
||
{onEdit && (
|
||
<Button
|
||
className="bg-gradient-to-r from-amber-500 to-orange-600 hover:from-amber-600 hover:to-orange-700"
|
||
onClick={() => {
|
||
setOpen(false)
|
||
onEdit()
|
||
}}
|
||
>
|
||
<Edit className="mr-2 h-4 w-4" />
|
||
编辑成就
|
||
</Button>
|
||
)}
|
||
</DialogFooter>
|
||
</DialogContent>
|
||
</Dialog>
|
||
)
|
||
}
|