"use client" import { ArrowLeft, Lock, Star } from "lucide-react" import Link from "next/link" import { use, useMemo, useState } from "react" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { submitReview } from "@/lib/api/reviews" import { notifyInfo, notifySuccess } from "@/lib/toast" import { useAuthStore } from "@/store/auth" import { useOrderStore } from "@/store/orders" import { useReviewStore } from "@/store/reviews" export default function ReviewPage({ params }: { params: Promise<{ id: string }> }) { const { id } = use(params) const order = useOrderStore((state) => state.orders.find((item) => item.id === id)) const userId = useAuthStore((state) => state.user?.id) const allReviews = useReviewStore((state) => state.reviews) // The selector returns the raw store array and useMemo derives the subset. // This keeps useSyncExternalStore snapshots stable across render checks. // Inline filter inside the selector creates a new array reference each call // and can cause infinite re-render loops in Zustand v5 (pmndrs/zustand#3155). const reviews = useMemo(() => allReviews.filter((item) => item.orderId === id), [allReviews, id]) const [rating, setRating] = useState(0) const [hoverRating, setHoverRating] = useState(0) const [content, setContent] = useState("") if (!order) { return (
订单不存在
) } const hasSubmitted = Boolean(userId && reviews.some((review) => review.fromUserId === userId)) const isRevealed = reviews.length >= 2 && reviews.every((review) => !review.sealed) if (order.status !== "pending_review") { return (

当前阶段不可评价

仅待评价状态的订单可以提交评价。

返回订单详情
) } if (hasSubmitted && !isRevealed) { return (

评价已提交

等待对方提交评价中

双方都提交评价后将同时揭晓

返回订单详情
) } if (hasSubmitted && isRevealed) { return (

评价已揭晓

双方评价已同步公开,可在订单详情查看。

返回订单详情
) } return (
返回订单 评价服务

{order.service.title} · {order.playerName}

{[1, 2, 3, 4, 5].map((star) => ( ))}