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

346 lines
14 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, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Plus, Upload, AlertTriangle, Loader2 } from "lucide-react"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Switch } from "@/components/ui/switch"
import { cn } from "@/lib/utils"
export function AddOutfitDialog() {
const [open, setOpen] = useState(false)
const [step, setStep] = useState(1)
const [isSubmitting, setIsSubmitting] = useState(false)
const [outfitType, setOutfitType] = useState("")
const [rarity, setRarity] = useState("")
const [printQuantity, setPrintQuantity] = useState(1000)
const [isLimited, setIsLimited] = useState(false)
const [previewId, setPreviewId] = useState(
"OFT" +
Math.floor(Math.random() * 1000)
.toString()
.padStart(3, "0"),
)
const handleSubmit = async () => {
setIsSubmitting(true)
// 模拟API请求
await new Promise((resolve) => setTimeout(resolve, 1500))
setIsSubmitting(false)
setOpen(false)
// 重置表单
setStep(1)
setOutfitType("")
setRarity("")
setPrintQuantity(1000)
setIsLimited(false)
setPreviewId(
"OFT" +
Math.floor(Math.random() * 1000)
.toString()
.padStart(3, "0"),
)
}
const handleNext = () => {
setStep(step + 1)
}
const handleBack = () => {
setStep(step - 1)
}
const handleClose = () => {
setOpen(false)
setStep(1)
}
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button className="bg-gradient-to-r from-pink-500 to-purple-600 hover:from-pink-600 hover:to-purple-700 transition-all duration-300 shadow-md hover:shadow-lg">
<Plus 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-purple-600 to-pink-600">
</DialogTitle>
<DialogDescription>ID</DialogDescription>
</DialogHeader>
<Tabs value={`step-${step}`} className="mt-2">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger
value="step-1"
className={cn(
"data-[state=active]:bg-gradient-to-r data-[state=active]:from-pink-500 data-[state=active]:to-purple-600 data-[state=active]:text-white",
step >= 1 ? "text-pink-600" : "text-gray-500",
)}
disabled
>
</TabsTrigger>
<TabsTrigger
value="step-2"
className={cn(
"data-[state=active]:bg-gradient-to-r data-[state=active]:from-pink-500 data-[state=active]:to-purple-600 data-[state=active]:text-white",
step >= 2 ? "text-pink-600" : "text-gray-500",
)}
disabled
>
</TabsTrigger>
<TabsTrigger
value="step-3"
className={cn(
"data-[state=active]:bg-gradient-to-r data-[state=active]:from-pink-500 data-[state=active]:to-purple-600 data-[state=active]:text-white",
step >= 3 ? "text-pink-600" : "text-gray-500",
)}
disabled
>
</TabsTrigger>
</TabsList>
<TabsContent value="step-1" className="space-y-4 py-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="name" className="text-right">
<span className="text-red-500">*</span>
</Label>
<Input
id="name"
placeholder="输入服装名称"
className="border-gray-300 focus-visible:ring-pink-500"
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="type" className="text-right">
<span className="text-red-500">*</span>
</Label>
<Select value={outfitType} onValueChange={setOutfitType} required>
<SelectTrigger className="border-gray-300 focus:ring-pink-500">
<SelectValue placeholder="选择服装类型" />
</SelectTrigger>
<SelectContent>
<SelectItem value="regular"></SelectItem>
<SelectItem value="seasonal"></SelectItem>
<SelectItem value="festival"></SelectItem>
<SelectItem value="special"></SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="rarity" className="text-right">
<span className="text-red-500">*</span>
</Label>
<Select value={rarity} onValueChange={setRarity} required>
<SelectTrigger className="border-gray-300 focus:ring-pink-500">
<SelectValue placeholder="选择稀有度" />
</SelectTrigger>
<SelectContent>
<SelectItem value="common"></SelectItem>
<SelectItem value="rare"></SelectItem>
<SelectItem value="epic"></SelectItem>
<SelectItem value="legendary"></SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="print-quantity" className="text-right">
<span className="text-red-500">*</span>
</Label>
<Input
id="print-quantity"
type="number"
min={1}
value={printQuantity}
onChange={(e) => setPrintQuantity(Number.parseInt(e.target.value))}
placeholder="输入印刷数量"
className="border-gray-300 focus-visible:ring-pink-500"
required
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="description" className="text-right">
<span className="text-red-500">*</span>
</Label>
<Textarea
id="description"
placeholder="输入服装描述"
className="min-h-[100px] border-gray-300 focus-visible:ring-pink-500"
required
/>
</div>
<div className="flex items-center space-x-2 pt-2">
<Switch id="limited" checked={isLimited} onCheckedChange={setIsLimited} />
<Label htmlFor="limited" className="cursor-pointer">
</Label>
</div>
{isLimited && (
<div className="p-3 bg-amber-50 border border-amber-200 rounded-lg flex items-start">
<AlertTriangle className="h-5 w-5 text-amber-500 mr-2 flex-shrink-0 mt-0.5" />
<div className="text-sm text-amber-700">
<p className="font-medium"></p>
<p></p>
</div>
</div>
)}
</TabsContent>
<TabsContent value="step-2" className="space-y-4 py-4">
<div className="space-y-2">
<Label className="text-right">
<span className="text-red-500">*</span>
</Label>
<div className="border-2 border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center hover:border-pink-500 transition-colors cursor-pointer">
<Upload className="h-8 w-8 text-gray-400 mb-2" />
<p className="text-sm text-gray-500"></p>
<p className="text-xs text-gray-400 mt-1"> PNG, JPG, JPEG 5MB</p>
</div>
</div>
<div className="space-y-2 mt-4">
<Label className="text-right"> ()</Label>
<div className="border-2 border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center hover:border-pink-500 transition-colors cursor-pointer">
<Upload className="h-8 w-8 text-gray-400 mb-2" />
<p className="text-sm text-gray-500"></p>
<p className="text-xs text-gray-400 mt-1">5</p>
</div>
</div>
<div className="p-3 bg-blue-50 border border-blue-200 rounded-lg flex items-start mt-2">
<AlertTriangle className="h-5 w-5 text-blue-500 mr-2 flex-shrink-0 mt-0.5" />
<div className="text-sm text-blue-700">
<p className="font-medium"></p>
<p>APP展示使PNG格式</p>
</div>
</div>
</TabsContent>
<TabsContent value="step-3" className="space-y-4 py-4">
<div className="p-4 bg-gray-50 rounded-lg">
<h3 className="text-lg font-medium mb-3"></h3>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500">ID</p>
<p className="font-medium text-pink-600">{previewId}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">
{outfitType === "regular"
? "常规"
: outfitType === "seasonal"
? "季节限定"
: outfitType === "festival"
? "节日限定"
: outfitType === "special"
? "特别版"
: "-"}
</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">
{rarity === "common"
? "普通"
: rarity === "rare"
? "稀有"
: rarity === "epic"
? "史诗"
: rarity === "legendary"
? "传说"
: "-"}
</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{printQuantity}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{isLimited ? "是" : "否"}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium"></p>
</div>
</div>
<div className="mt-4 p-3 bg-pink-50 border border-pink-200 rounded-lg flex items-start">
<AlertTriangle className="h-5 w-5 text-pink-500 mr-2 flex-shrink-0 mt-0.5" />
<div className="text-sm text-pink-700">
<p className="font-medium"></p>
<p>ID</p>
</div>
</div>
</div>
</TabsContent>
</Tabs>
<DialogFooter className="flex items-center justify-between mt-2">
{step > 1 ? (
<Button variant="outline" onClick={handleBack} disabled={isSubmitting}>
</Button>
) : (
<Button variant="outline" onClick={handleClose} disabled={isSubmitting}>
</Button>
)}
{step < 3 ? (
<Button
className="bg-gradient-to-r from-pink-500 to-purple-600 hover:from-pink-600 hover:to-purple-700"
onClick={handleNext}
>
</Button>
) : (
<Button
className="bg-gradient-to-r from-pink-500 to-purple-600 hover:from-pink-600 hover:to-purple-700"
onClick={handleSubmit}
disabled={isSubmitting}
>
{isSubmitting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
...
</>
) : (
"创建服装"
)}
</Button>
)}
</DialogFooter>
</DialogContent>
</Dialog>
)
}