lty/qy-lty-admin/components/achievements/achievement-detail-dialog.tsx
2026-03-17 13:17:02 +08:00

163 lines
5.5 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.

"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>
)
}