"use client" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { EmptyState } from "@/components/ui/empty-state" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { deletePlayerService, listPlayers, listServices } from "@/lib/api" import { toApiError } from "@/lib/errors" import { useMyShop } from "@/lib/hooks/use-my-shop" import { notifyInfo, notifySuccess } from "@/lib/toast" import type { Player, PlayerService } from "@/lib/types" import { useAuthStore } from "@/store/auth" import { AlertCircle, Edit, Plus, Trash2 } from "lucide-react" import Link from "next/link" import { useCallback, useEffect, useMemo, useState } from "react" export default function ServicesPage() { const userId = useAuthStore((state) => state.user?.id) const currentRole = useAuthStore((state) => state.currentRole) const { shop: ownerShop, loading: shopLoading, error: shopError, } = useMyShop(currentRole === "owner") const [players, setPlayers] = useState([]) const [services, setServices] = useState([]) const [loading, setLoading] = useState(true) const loadData = useCallback(async () => { try { const [nextPlayers, nextServices] = await Promise.all([listPlayers(), listServices()]) setPlayers(nextPlayers) setServices(nextServices) } catch (error) { notifyInfo(toApiError(error).msg) } finally { setLoading(false) } }, []) useEffect(() => { let cancelled = false Promise.all([listPlayers(), listServices()]) .then(([nextPlayers, nextServices]) => { if (cancelled) return setPlayers(nextPlayers) setServices(nextServices) }) .catch((error) => { if (cancelled) return notifyInfo(toApiError(error).msg) }) .finally(() => { if (cancelled) return setLoading(false) }) return () => { cancelled = true } }, []) const scopedPlayerIdSet = useMemo(() => { if (currentRole === "player") { const player = players.find((item) => item.user.id === userId) return new Set(player ? [player.id] : []) } if (currentRole === "owner" && ownerShop) { return new Set( players.filter((player) => player.shopId === ownerShop.id).map((player) => player.id), ) } return new Set() }, [currentRole, ownerShop, players, userId]) const scopedServices = services.filter((service) => scopedPlayerIdSet.has(service.playerId)) async function handleDelete(service: PlayerService) { if (!scopedPlayerIdSet.has(service.playerId)) return try { await deletePlayerService(service.id) notifySuccess("服务已删除") await loadData() } catch (error) { notifyInfo(toApiError(error).msg) } } return (

服务管理

已发布的服务 服务名称 游戏 价格 段位范围 可用时间 操作 {loading || (currentRole === "owner" && shopLoading) ? ( ) : currentRole === "owner" && shopError ? ( ) : scopedServices.length === 0 ? ( ) : ( scopedServices.map((service) => ( {service.title} {service.gameName} ¥{service.price}/{service.unit} {service.rankRange ?? "-"}
{service.availability.map((a) => (
{a}
))}
)) )}
) }