2026-03-17 13:17:02 +08:00

383 lines
16 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.

import { DashboardShell } from "@/components/dashboard-shell"
import { DashboardHeader } from "@/components/dashboard-header"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { ArrowLeft, Edit, AlertTriangle, FileText, Plus, Download } from "lucide-react"
import Link from "next/link"
import { AddPrintBatchDialog } from "@/components/props/add-print-batch-dialog"
import { ExportCardsDialog } from "@/components/props/export-cards-dialog"
// Mock data for the prop details
const propData = {
PRP001: {
id: "PRP001",
name: "魔法麦克风",
type: "演出道具",
rarity: "稀有",
description: "洛天依的经典原创道具,可以增强歌声的魔力,让听众更加沉浸在音乐中。",
releaseDate: "2023-11-15",
status: "已发布",
activatedCount: 1245,
printedCount: 2000,
image: "/placeholder.svg?height=300&width=300",
batches: [
{
id: "B001",
date: "2023-09-01",
quantity: 1000,
startId: "PRP001-0001",
endId: "PRP001-1000",
status: "已激活",
activatedCount: 980,
},
{
id: "B002",
date: "2023-12-15",
quantity: 1000,
startId: "PRP001-1001",
endId: "PRP001-2000",
status: "已激活",
activatedCount: 265,
},
],
},
PRP002: {
id: "PRP002",
name: "星光魔杖",
type: "互动道具",
rarity: "史诗",
description: "挥舞魔杖可以创造出美丽的星光效果,增加互动时的好感度。",
releaseDate: "2023-12-01",
status: "已发布",
activatedCount: 876,
printedCount: 1500,
image: "/placeholder.svg?height=300&width=300",
batches: [
{
id: "B003",
date: "2023-05-10",
quantity: 1500,
startId: "PRP002-0001",
endId: "PRP002-1500",
status: "已激活",
activatedCount: 876,
},
],
},
PRP003: {
id: "PRP003",
name: "音乐盒",
type: "收藏品",
rarity: "传说",
description: "精美的音乐盒,打开后会播放洛天依的经典歌曲,是珍贵的收藏品。",
releaseDate: "2024-01-10",
status: "已发布",
activatedCount: 532,
printedCount: 1000,
image: "/placeholder.svg?height=300&width=300",
batches: [
{
id: "B004",
date: "2023-11-15",
quantity: 1000,
startId: "PRP003-0001",
endId: "PRP003-1000",
status: "已激活",
activatedCount: 532,
},
],
},
PRP004: {
id: "PRP004",
name: "虚拟相机",
type: "互动道具",
rarity: "稀有",
description: "可以捕捉洛天依的精彩瞬间,保存为虚拟照片。",
releaseDate: "2024-02-05",
status: "已发布",
activatedCount: 967,
printedCount: 2000,
image: "/placeholder.svg?height=300&width=300",
batches: [
{
id: "B005",
date: "2024-01-05",
quantity: 2000,
startId: "PRP004-0001",
endId: "PRP004-2000",
status: "已激活",
activatedCount: 967,
},
],
},
PRP005: {
id: "PRP005",
name: "节日礼盒",
type: "限定道具",
rarity: "史诗",
description: "节日限定礼盒,内含多种惊喜道具和装饰品。",
releaseDate: "",
status: "未发布",
activatedCount: 0,
printedCount: 1000,
image: "/placeholder.svg?height=300&width=300",
batches: [
{
id: "B007",
date: "2024-03-20",
quantity: 1000,
startId: "PRP005-0001",
endId: "PRP005-1000",
status: "未激活",
activatedCount: 0,
},
],
},
}
export default function PropDetailPage({ params }: { params: { id: string } }) {
const prop = propData[params.id as keyof typeof propData]
if (!prop) {
return (
<DashboardShell>
<div className="flex flex-col items-center justify-center h-[60vh]">
<AlertTriangle className="h-16 w-16 text-red-500 mb-4" />
<h1 className="text-2xl font-bold mb-2"></h1>
<p className="text-gray-500 mb-6">ID为 {params.id} </p>
<Button asChild>
<Link href="/props">
<ArrowLeft className="mr-2 h-4 w-4" />
</Link>
</Button>
</div>
</DashboardShell>
)
}
const isPublished = prop.status === "已发布"
const activationRate = prop.printedCount > 0 ? Math.round((prop.activatedCount / prop.printedCount) * 100) : 0
return (
<DashboardShell>
<div className="absolute top-0 right-0 w-1/2 h-48 bg-gradient-to-bl from-purple-200 via-pink-200 to-transparent opacity-20 rounded-bl-full" />
<div className="flex items-center mb-6">
<Button variant="ghost" size="sm" className="mr-4" asChild>
<Link href="/props">
<ArrowLeft className="mr-2 h-4 w-4" />
</Link>
</Button>
<DashboardHeader heading={prop.name} text={`道具ID: ${prop.id}`}>
<div className="flex space-x-2 ml-auto">
{!isPublished && (
<Button
asChild
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"
>
<Link href={`/props/edit/${params.id}`}>
<Edit className="mr-2 h-4 w-4" />
</Link>
</Button>
)}
<ExportCardsDialog propId={prop.id} />
</div>
</DashboardHeader>
</div>
<Tabs defaultValue="details" className="w-full">
<TabsList className="grid w-full md:w-auto grid-cols-2 md:grid-cols-3 mb-4">
<TabsTrigger value="details"></TabsTrigger>
<TabsTrigger value="batches"></TabsTrigger>
<TabsTrigger value="analytics"></TabsTrigger>
</TabsList>
<TabsContent value="details" className="space-y-6">
<div className="grid gap-6 md:grid-cols-3">
<Card className="md:col-span-1 border-none shadow-lg bg-white">
<CardHeader>
<CardTitle className="text-lg font-bold"></CardTitle>
</CardHeader>
<CardContent className="flex justify-center">
<div className="relative w-full aspect-square max-w-[300px] rounded-lg overflow-hidden bg-gray-100 flex items-center justify-center">
<img src={prop.image || "/placeholder.svg"} alt={prop.name} className="object-cover" />
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-3">
<Badge className={`${isPublished ? "bg-green-500" : "bg-gray-500"}`}>{prop.status}</Badge>
</div>
</div>
</CardContent>
</Card>
<Card className="md:col-span-2 border-none shadow-lg bg-gradient-to-br from-white to-purple-50">
<CardHeader>
<CardTitle className="text-lg font-bold"></CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{prop.type}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{prop.rarity}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{prop.releaseDate || "尚未发布"}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{prop.activatedCount}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{prop.printedCount}</p>
</div>
<div className="space-y-1">
<p className="text-sm font-medium text-gray-500"></p>
<p className="font-medium">{activationRate}%</p>
</div>
</div>
<div className="mt-6">
<p className="text-sm font-medium text-gray-500 mb-2"></p>
<p className="text-gray-700">{prop.description}</p>
</div>
{isPublished && (
<div className="mt-6 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" />
<p className="text-sm text-amber-700"></p>
</div>
)}
</CardContent>
</Card>
</div>
</TabsContent>
<TabsContent value="batches" className="space-y-6">
<Card className="border-none shadow-lg bg-gradient-to-br from-white to-blue-50">
<CardHeader className="flex flex-row items-center justify-between">
<div>
<CardTitle className="text-lg font-bold"></CardTitle>
<CardDescription>ID</CardDescription>
</div>
<AddPrintBatchDialog propId={prop.id} isPublished={isPublished} />
</CardHeader>
<CardContent>
<div className="rounded-md border">
<table className="w-full">
<thead>
<tr className="bg-gray-50 border-b">
<th className="py-3 px-4 text-left text-sm font-medium text-gray-500">ID</th>
<th className="py-3 px-4 text-left text-sm font-medium text-gray-500"></th>
<th className="py-3 px-4 text-left text-sm font-medium text-gray-500"></th>
<th className="py-3 px-4 text-left text-sm font-medium text-gray-500">ID</th>
<th className="py-3 px-4 text-left text-sm font-medium text-gray-500">ID</th>
<th className="py-3 px-4 text-left text-sm font-medium text-gray-500"></th>
<th className="py-3 px-4 text-left text-sm font-medium text-gray-500"></th>
<th className="py-3 px-4 text-right text-sm font-medium text-gray-500"></th>
</tr>
</thead>
<tbody>
{prop.batches.map((batch) => (
<tr key={batch.id} className="border-b hover:bg-gray-50">
<td className="py-3 px-4 text-sm font-medium">{batch.id}</td>
<td className="py-3 px-4 text-sm">{batch.date}</td>
<td className="py-3 px-4 text-sm">{batch.quantity}</td>
<td className="py-3 px-4 text-sm font-mono text-xs">{batch.startId}</td>
<td className="py-3 px-4 text-sm font-mono text-xs">{batch.endId}</td>
<td className="py-3 px-4 text-sm">
<Badge className={`${batch.status === "已激活" ? "bg-green-500" : "bg-gray-500"}`}>
{batch.status}
</Badge>
</td>
<td className="py-3 px-4 text-sm">{batch.activatedCount}</td>
<td className="py-3 px-4 text-right">
<div className="flex justify-end space-x-2">
<Button variant="ghost" size="sm" className="h-8 hover:bg-blue-50 hover:text-blue-600">
<FileText className="h-4 w-4 mr-1" />
</Button>
<Button variant="ghost" size="sm" className="h-8 hover:bg-green-50 hover:text-green-600">
<Download className="h-4 w-4 mr-1" />
</Button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</CardContent>
</Card>
<Card className="border-none shadow-lg bg-white">
<CardHeader>
<CardTitle className="text-lg font-bold"></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-4">
<Button variant="outline" className="border-blue-200 hover:bg-blue-50 hover:text-blue-700">
<Download className="mr-2 h-4 w-4" />
</Button>
<Button variant="outline" className="border-purple-200 hover:bg-purple-50 hover:text-purple-700">
<Plus className="mr-2 h-4 w-4" />
</Button>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="analytics" className="space-y-6">
<Card className="border-none shadow-lg bg-white">
<CardHeader>
<CardTitle className="text-lg font-bold"></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="h-[300px] flex items-center justify-center bg-gray-50 rounded-lg">
<p className="text-gray-500"></p>
</div>
</CardContent>
</Card>
<div className="grid gap-6 md:grid-cols-2">
<Card className="border-none shadow-lg bg-gradient-to-br from-white to-green-50">
<CardHeader>
<CardTitle className="text-lg font-bold"></CardTitle>
</CardHeader>
<CardContent>
<div className="h-[200px] flex items-center justify-center bg-gray-50 rounded-lg">
<p className="text-gray-500"></p>
</div>
</CardContent>
</Card>
<Card className="border-none shadow-lg bg-gradient-to-br from-white to-blue-50">
<CardHeader>
<CardTitle className="text-lg font-bold"></CardTitle>
</CardHeader>
<CardContent>
<div className="h-[200px] flex items-center justify-center bg-gray-50 rounded-lg">
<p className="text-gray-500"></p>
</div>
</CardContent>
</Card>
</div>
</TabsContent>
</Tabs>
</DashboardShell>
)
}