fix(pages): scope order views to the active role

This commit is contained in:
zetaloop
2026-04-24 08:58:35 +08:00
parent 3b82602c38
commit ffb420f7e7
3 changed files with 120 additions and 81 deletions
+98 -73
View File
@@ -56,6 +56,13 @@ const ownerTabs = [
{ value: "disputed", label: "争议" },
]
function getOrderRole(role: UserRole): "consumer" | "player" | "owner" | undefined {
if (role === "consumer" || role === "player" || role === "owner") {
return role
}
return undefined
}
export default function OrderListPage() {
const { currentRole, user } = useAuthStore()
const shops = useShopStore((state) => state.shops)
@@ -80,6 +87,7 @@ function OrderListContent({
userId?: string
ownerShopId?: string
}) {
const orderRole = getOrderRole(currentRole)
const [tab, setTab] = useState<TabFilter | "pending">("all")
const [orders, setOrders] = useState<Awaited<ReturnType<typeof listOrders>>>([])
const [sessions, setSessions] = useState<Awaited<ReturnType<typeof listChatSessions>>>([])
@@ -87,9 +95,15 @@ function OrderListContent({
useEffect(() => {
let cancelled = false
if (!orderRole) {
return () => {
cancelled = true
}
}
void (async () => {
try {
const items = await Promise.resolve(listOrders())
const items = await Promise.resolve(listOrders({ role: orderRole }))
if (cancelled) return
setOrders(items)
} catch {
@@ -101,7 +115,7 @@ function OrderListContent({
return () => {
cancelled = true
}
}, [])
}, [orderRole])
useEffect(() => {
let cancelled = false
@@ -148,83 +162,94 @@ function OrderListContent({
? "客户视角"
: currentRole === "player"
? "打手视角"
: "店主视角"}
: currentRole === "owner"
? "店主视角"
: "管理员视角"}
</Badge>
</div>
<Tabs value={tab} onValueChange={(v) => setTab(v as TabFilter | "pending")}>
<TabsList>
{tabs.map((item) => (
<TabsTrigger key={item.value} value={item.value}>
{item.label}
</TabsTrigger>
))}
</TabsList>
{!orderRole ? (
<Card className="hover:shadow-card-hover">
<CardContent className="py-8 text-center text-sm text-muted-foreground">
</CardContent>
</Card>
) : (
<Tabs value={tab} onValueChange={(v) => setTab(v as TabFilter | "pending")}>
<TabsList>
{tabs.map((item) => (
<TabsTrigger key={item.value} value={item.value}>
{item.label}
</TabsTrigger>
))}
</TabsList>
<TabsContent value={tab} className="mt-4 space-y-4">
{filtered.length === 0 ? (
<Card className="hover:shadow-card-hover">
<CardContent className="py-8 text-center text-sm text-muted-foreground">
</CardContent>
</Card>
) : (
filtered.map((order) => (
<Card key={order.id} className="hover:shadow-card-hover">
<CardHeader className="pb-3">
<div className="flex items-center justify-between">
<CardTitle className="text-base">{order.service.title}</CardTitle>
<Badge className={cn("text-xs", statusColors[order.status])}>
{statusLabels[order.status]}
</Badge>
</div>
<p className="text-sm text-muted-foreground">{order.service.title}</p>
</CardHeader>
<CardContent>
<div className="flex items-center justify-between">
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<span className="font-medium text-foreground">¥{order.totalPrice}</span>
<span className="flex items-center gap-1">
<Clock className="h-3.5 w-3.5" />
{new Date(order.createdAt).toLocaleDateString("zh-CN")}
</span>
</div>
<div className="flex gap-2">
{(() => {
if (order.status !== "in_progress" && order.status !== "pending_close")
return null
const session = sessions.find(
(item) => item.type === "order" && item.orderId === order.id,
)
if (!session) return null
return (
<Button variant="outline" size="sm" asChild>
<Link href={`/chat/${session.id}`}>
<MessageSquare className="mr-1 h-3.5 w-3.5" />
</Link>
</Button>
)
})()}
{order.status === "completed" && (
<Button variant="outline" size="sm" asChild>
<Link href={`/order/new?serviceId=${order.service.id}`}>
<RefreshCw className="mr-1 h-3.5 w-3.5" />
</Link>
</Button>
)}
<Button size="sm" asChild>
<Link href={`/order/${order.id}`}></Link>
</Button>
</div>
</div>
<TabsContent value={tab} className="mt-4 space-y-4">
{filtered.length === 0 ? (
<Card className="hover:shadow-card-hover">
<CardContent className="py-8 text-center text-sm text-muted-foreground">
</CardContent>
</Card>
))
)}
</TabsContent>
</Tabs>
) : (
filtered.map((order) => (
<Card key={order.id} className="hover:shadow-card-hover">
<CardHeader className="pb-3">
<div className="flex items-center justify-between">
<CardTitle className="text-base">{order.service.title}</CardTitle>
<Badge className={cn("text-xs", statusColors[order.status])}>
{statusLabels[order.status]}
</Badge>
</div>
<p className="text-sm text-muted-foreground">{order.service.title}</p>
</CardHeader>
<CardContent>
<div className="flex items-center justify-between">
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<span className="font-medium text-foreground">¥{order.totalPrice}</span>
<span className="flex items-center gap-1">
<Clock className="h-3.5 w-3.5" />
{new Date(order.createdAt).toLocaleDateString("zh-CN")}
</span>
</div>
<div className="flex gap-2">
{(() => {
if (order.status !== "in_progress" && order.status !== "pending_close") {
return null
}
const session = sessions.find(
(item) => item.type === "order" && item.orderId === order.id,
)
if (!session) return null
return (
<Button variant="outline" size="sm" asChild>
<Link href={`/chat/${session.id}`}>
<MessageSquare className="mr-1 h-3.5 w-3.5" />
</Link>
</Button>
)
})()}
{order.status === "completed" && (
<Button variant="outline" size="sm" asChild>
<Link href={`/order/new?serviceId=${order.service.id}`}>
<RefreshCw className="mr-1 h-3.5 w-3.5" />
</Link>
</Button>
)}
<Button size="sm" asChild>
<Link href={`/order/${order.id}`}></Link>
</Button>
</div>
</div>
</CardContent>
</Card>
))
)}
</TabsContent>
</Tabs>
)}
</div>
)
}