refactor: align client state and ui with backend contract

This commit is contained in:
zetaloop
2026-05-03 05:40:01 +08:00
parent a3f0b49112
commit 0e7270aa8d
4 changed files with 51 additions and 9 deletions
+26 -2
View File
@@ -5,7 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { EmptyState } from "@/components/ui/empty-state"
import { Progress } from "@/components/ui/progress"
import { StatusBadge, type StatusBadgeProps } from "@/components/ui/status-badge"
import { listOrders, listPlayers, listServices, listShops } from "@/lib/api"
import { getShopIncomeStats, listOrders, listPlayers, listServices, listShops } from "@/lib/api"
import { statusLabels } from "@/lib/constants"
import type { Player, PlayerService, Shop } from "@/lib/types"
import { useAuthStore } from "@/store/auth"
@@ -40,6 +40,7 @@ export default function DashboardPage() {
const [shop, setShop] = useState<Shop | null>(null)
const [services, setServices] = useState<PlayerService[]>([])
const [orders, setOrders] = useState<Awaited<ReturnType<typeof listOrders>>>([])
const [monthlyIncome, setMonthlyIncome] = useState<string>("0")
const recentOrders = orders.slice(0, 3)
useEffect(() => {
@@ -88,6 +89,29 @@ export default function DashboardPage() {
}
}, [orderRole])
useEffect(() => {
if (!shop) {
setMonthlyIncome("0")
return
}
let cancelled = false
getShopIncomeStats(shop.id)
.then((stats) => {
if (cancelled) return
setMonthlyIncome(stats.monthlyIncome)
})
.catch(() => {
if (cancelled) return
setMonthlyIncome("0")
})
return () => {
cancelled = true
}
}, [shop])
const totalOrders = isOwner ? (shop?.totalOrders ?? 0) : (player?.totalOrders ?? 0)
const rating = isOwner ? (shop?.rating ?? 0) : (player?.rating ?? 0)
const playerCount = shop?.playerCount ?? 0
@@ -149,7 +173,7 @@ export default function DashboardPage() {
)}
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{isOwner ? "——" : serviceCount}</div>
<div className="text-2xl font-bold">{isOwner ? `¥${monthlyIncome}` : serviceCount}</div>
</CardContent>
</Card>
</div>