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

224 lines
7.4 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 { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import { Trophy, Loader2 } from "lucide-react"
import { toast } from "@/components/ui/use-toast"
import type { Achievement } from "@/lib/api/types"
type AddAchievementDialogProps = {
onAchievementAdded: () => void
}
export function AddAchievementDialog({ onAchievementAdded }: AddAchievementDialogProps) {
const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(false)
const [formData, setFormData] = useState<Partial<Achievement>>({
name: "",
description: "",
category: "互动",
requirement: "",
rewardType: "经验值",
rewardAmount: 100,
isHidden: false,
})
const handleChange = (field: keyof Achievement, value: any) => {
setFormData((prev) => ({ ...prev, [field]: value }))
}
const handleSubmit = async () => {
if (!formData.name || !formData.description || !formData.requirement) {
toast({
title: "表单不完整",
description: "请填写所有必填字段",
variant: "destructive",
})
return
}
setLoading(true)
try {
// 模拟API调用
await new Promise((resolve) => setTimeout(resolve, 1000))
toast({
title: "成就添加成功",
description: `成就 "${formData.name}" 已成功添加到系统`,
})
setOpen(false)
setFormData({
name: "",
description: "",
category: "互动",
requirement: "",
rewardType: "经验值",
rewardAmount: 100,
isHidden: false,
})
onAchievementAdded()
} catch (error) {
toast({
title: "添加失败",
description: "添加成就时发生错误,请重试",
variant: "destructive",
})
} finally {
setLoading(false)
}
}
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button className="bg-gradient-to-r from-amber-500 to-orange-600 hover:from-amber-600 hover:to-orange-700">
<Trophy className="mr-2 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="grid gap-4 py-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="name"> *</Label>
<Input
id="name"
value={formData.name}
onChange={(e) => handleChange("name", e.target.value)}
placeholder="输入成就名称"
/>
</div>
<div className="space-y-2">
<Label htmlFor="category"> *</Label>
<Select value={formData.category} onValueChange={(value) => handleChange("category", value)}>
<SelectTrigger>
<SelectValue placeholder="选择类别" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel></SelectLabel>
<SelectItem value="互动"></SelectItem>
<SelectItem value="好感度"></SelectItem>
<SelectItem value="收集"></SelectItem>
<SelectItem value="探索"></SelectItem>
<SelectItem value="特殊"></SelectItem>
<SelectItem value="隐藏"></SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="description"> *</Label>
<Textarea
id="description"
value={formData.description}
onChange={(e) => handleChange("description", e.target.value)}
placeholder="输入成就描述"
/>
</div>
<div className="space-y-2">
<Label htmlFor="requirement"> *</Label>
<Textarea
id="requirement"
value={formData.requirement}
onChange={(e) => handleChange("requirement", e.target.value)}
placeholder="输入解锁条件"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="rewardType"></Label>
<Select value={formData.rewardType} onValueChange={(value) => handleChange("rewardType", value)}>
<SelectTrigger>
<SelectValue placeholder="选择奖励类型" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel></SelectLabel>
<SelectItem value="经验值"></SelectItem>
<SelectItem value="好感度"></SelectItem>
<SelectItem value="虚拟币"></SelectItem>
<SelectItem value="道具"></SelectItem>
<SelectItem value="服装"></SelectItem>
<SelectItem value="称号"></SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="rewardAmount"></Label>
<Input
id="rewardAmount"
type="number"
value={formData.rewardAmount}
onChange={(e) => handleChange("rewardAmount", Number.parseInt(e.target.value) || 0)}
min={0}
/>
</div>
</div>
<div className="flex items-center space-x-2">
<Switch
id="isHidden"
checked={formData.isHidden}
onCheckedChange={(checked) => handleChange("isHidden", checked)}
/>
<Label htmlFor="isHidden"></Label>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
</Button>
<Button
className="bg-gradient-to-r from-amber-500 to-orange-600 hover:from-amber-600 hover:to-orange-700"
onClick={handleSubmit}
disabled={loading}
>
{loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Trophy className="mr-2 h-4 w-4" />}
{loading ? "添加中..." : "添加成就"}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}