"use client" import { useState, useEffect, useCallback } from "react" import { useRouter } from "next/navigation" import { DashboardShell } from "@/components/dashboard-shell" import { DashboardHeader } from "@/components/dashboard-header" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Badge } from "@/components/ui/badge" import { Search, Edit, Video, Eye, Plus, Loader2, Archive } from "lucide-react" import { AddDanceDialog } from "@/components/dances/add-dance-dialog" import { DeleteConfirmationDialog } from "@/components/delete-confirmation-dialog" import { PublishConfirmationDialog } from "@/components/publish-confirmation-dialog" import { useToast } from "@/hooks/use-toast" import { getDances, deleteDance, publishDance, archiveDance } from "@/lib/api/dances" import { isSuperUser } from "@/lib/api/auth" import type { Dance } from "@/lib/api/types" function formatDate(dateStr?: string): string { if (!dateStr) return "" try { return new Date(dateStr).toLocaleDateString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", }) } catch { return dateStr } } export default function DancesPage() { const { toast } = useToast() const router = useRouter() const [dances, setDances] = useState([]) const [searchTerm, setSearchTerm] = useState("") const [currentPage, setCurrentPage] = useState(1) const [totalItems, setTotalItems] = useState(0) const [isLoading, setIsLoading] = useState(true) const [isAddDialogOpen, setIsAddDialogOpen] = useState(false) const [danceToEdit, setDanceToEdit] = useState(undefined) const itemsPerPage = 10 const fetchDances = useCallback(async () => { setIsLoading(true) try { const result = await getDances(currentPage, itemsPerPage, searchTerm) if (result.data) { setDances(result.data) setTotalItems(result.pagination?.totalItems || 0) } } catch (error) { toast({ title: "加载失败", description: "无法获取舞蹈列表", variant: "destructive", }) } finally { setIsLoading(false) } }, [currentPage, searchTerm, itemsPerPage, toast]) useEffect(() => { fetchDances() }, [fetchDances]) const totalPages = Math.ceil(totalItems / itemsPerPage) // 处理添加/编辑舞蹈后刷新列表 const handleDanceSaved = () => { setDanceToEdit(undefined) setIsAddDialogOpen(false) fetchDances() toast({ title: "保存成功", description: "舞蹈数据已更新", }) } // 处理删除舞蹈 const handleDeleteDance = async (danceId: string, danceName: string) => { try { await deleteDance(danceId) await fetchDances() toast({ title: "删除成功", description: `舞蹈 ${danceName} 已成功删除`, variant: "destructive", }) } catch (error) { toast({ title: "删除失败", description: "无法删除该舞蹈", variant: "destructive", }) } } // 发布舞蹈 const handlePublishDance = async (danceId: string, danceName: string) => { try { await publishDance(danceId) await fetchDances() toast({ title: "发布成功", description: `舞蹈 "${danceName}" 已成功发布`, }) } catch (error) { toast({ title: "发布失败", description: "无法发布舞蹈,请稍后重试", variant: "destructive", }) } } // 归档舞蹈 const handleArchiveDance = async (danceId: string, danceName: string) => { try { await archiveDance(danceId) await fetchDances() toast({ title: "归档成功", description: `舞蹈 "${danceName}" 已归档`, }) } catch (error) { toast({ title: "归档失败", description: "无法归档舞蹈,请稍后重试", variant: "destructive", }) } } // 打开编辑对话框 const openEditDialog = (dance: Dance) => { setDanceToEdit(dance) setIsAddDialogOpen(true) } // 查看舞蹈详情 const viewDanceDetails = (dance: Dance) => { router.push(`/dances/${dance.id}`) } return (
{ setSearchTerm(e.target.value) setCurrentPage(1) }} />
舞蹈列表
管理洛天依可以表演的舞蹈
{isLoading ? (
) : ( ID 舞蹈名称 编舞者 难度 分类 时长 发布日期 状态 操作 {dances.map((dance) => (
{dance.id} {dance.name} {dance.choreographer || "未知"} {dance.difficulty || "未知"} {dance.category || "未分类"} {dance.duration || "未知"} {formatDate(dance.publishedAt) || "-"} {dance.status || "草稿"}
{/* 草稿状态:显示发布按钮 */} {dance.status === "草稿" && ( handlePublishDance(dance.id, dance.name)} /> )} {/* 已发布状态:显示归档按钮 */} {dance.status === "已发布" && ( )} {(dance.status !== "已发布" || isSuperUser()) && ( <> handleDeleteDance(dance.id, dance.name)} /> )}
))} {dances.length === 0 && ( 没有找到匹配的舞蹈 )}
)}
显示 {dances.length > 0 ? (currentPage - 1) * itemsPerPage + 1 : 0}- {Math.min(currentPage * itemsPerPage, totalItems)} 共 {totalItems} 个舞蹈
{/* 添加/编辑舞蹈对话框 */}
) }