feat: add role-based wallet view for consumer vs player/owner

This commit is contained in:
zetaloop
2026-02-20 22:46:28 +08:00
parent 977d19ed5c
commit 86ece33c00
+104 -52
View File
@@ -1,3 +1,5 @@
"use client"
import { import {
ArrowDownLeft, ArrowDownLeft,
ArrowUpRight, ArrowUpRight,
@@ -12,6 +14,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input" import { Input } from "@/components/ui/input"
import { Separator } from "@/components/ui/separator" import { Separator } from "@/components/ui/separator"
import { mockTransactions, walletBalance } from "@/lib/mock-data" import { mockTransactions, walletBalance } from "@/lib/mock-data"
import { useAuthStore } from "@/store/auth"
const typeLabels: Record<string, string> = { const typeLabels: Record<string, string> = {
topup: "充值", topup: "充值",
@@ -30,6 +33,20 @@ const typeIcons: Record<string, typeof ArrowUpRight> = {
} }
export default function WalletPage() { export default function WalletPage() {
const { currentRole } = useAuthStore()
const isConsumer = currentRole === "consumer"
const filteredTransactions = mockTransactions.filter((tx) => {
if (isConsumer) {
return ["topup", "payment", "refund"].includes(tx.type)
}
return ["income", "withdrawal"].includes(tx.type)
})
const incomeBalance = mockTransactions
.filter((tx) => tx.type === "income")
.reduce((acc, tx) => acc + tx.amount, 0)
return ( return (
<div className="max-w-2xl space-y-6"> <div className="max-w-2xl space-y-6">
<h1 className="text-2xl font-bold"></h1> <h1 className="text-2xl font-bold"></h1>
@@ -38,43 +55,74 @@ export default function WalletPage() {
<CardContent className="pt-6"> <CardContent className="pt-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm text-muted-foreground"></p> <p className="text-sm text-muted-foreground">
<p className="text-3xl font-bold mt-1">¥{walletBalance.toFixed(2)}</p> {isConsumer ? "账户余额" : "收入余额"}
</p>
<p className="text-3xl font-bold mt-1">
¥{isConsumer ? walletBalance.toFixed(2) : incomeBalance.toFixed(2)}
</p>
</div> </div>
<Wallet className="h-10 w-10 text-muted-foreground" /> <Wallet className="h-10 w-10 text-muted-foreground" />
</div> </div>
<div className="flex gap-2 mt-4"> <div className="flex gap-2 mt-4">
<Button> {isConsumer ? (
<DollarSign className="mr-1 h-4 w-4" /> <Button>
<DollarSign className="mr-1 h-4 w-4" />
</Button>
<Button variant="outline"> </Button>
<CreditCard className="mr-1 h-4 w-4" /> ) : (
<Button variant="outline">
</Button> <CreditCard className="mr-1 h-4 w-4" />
</Button>
)}
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
<Card> {isConsumer ? (
<CardHeader> <Card>
<CardTitle className="text-base"></CardTitle> <CardHeader>
</CardHeader> <CardTitle className="text-base"></CardTitle>
<CardContent className="space-y-4"> </CardHeader>
<div className="grid grid-cols-3 gap-2"> <CardContent className="space-y-4">
{[50, 100, 200, 500, 1000, 2000].map((amount) => ( <div className="grid grid-cols-3 gap-2">
<Button key={`amount-${amount}`} variant="outline" className="h-12"> {[50, 100, 200, 500, 1000, 2000].map((amount) => (
¥{amount} <Button key={`amount-${amount}`} variant="outline" className="h-12">
</Button> ¥{amount}
))} </Button>
</div> ))}
<Separator /> </div>
<div className="flex gap-2"> <Separator />
<Input placeholder="自定义金额" type="number" /> <div className="flex gap-2">
<Button></Button> <Input placeholder="自定义金额" type="number" />
</div> <Button></Button>
</CardContent> </div>
</Card> </CardContent>
</Card>
) : (
<Card>
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-3 gap-4 text-center">
<div>
<p className="text-xs text-muted-foreground"></p>
<p className="text-lg font-bold">¥1,280.00</p>
</div>
<div>
<p className="text-xs text-muted-foreground"></p>
<p className="text-lg font-bold">¥320.00</p>
</div>
<div>
<p className="text-xs text-muted-foreground"></p>
<p className="text-lg font-bold">¥5,400.00</p>
</div>
</div>
</CardContent>
</Card>
)}
<Card> <Card>
<CardHeader className="flex flex-row items-center justify-between"> <CardHeader className="flex flex-row items-center justify-between">
@@ -85,33 +133,37 @@ export default function WalletPage() {
</Button> </Button>
</CardHeader> </CardHeader>
<CardContent className="space-y-3"> <CardContent className="space-y-3">
{mockTransactions.map((tx) => { {filteredTransactions.length > 0 ? (
const Icon = typeIcons[tx.type] filteredTransactions.map((tx) => {
const isIncome = tx.amount > 0 const Icon = typeIcons[tx.type]
return ( const isIncome = tx.amount > 0
<div key={tx.id} className="flex items-center justify-between"> return (
<div className="flex items-center gap-3"> <div key={tx.id} className="flex items-center justify-between">
<div className="h-8 w-8 rounded-full bg-muted flex items-center justify-center"> <div className="flex items-center gap-3">
<Icon className="h-4 w-4" /> <div className="h-8 w-8 rounded-full bg-muted flex items-center justify-center">
<Icon className="h-4 w-4" />
</div>
<div>
<p className="text-sm font-medium">{tx.description}</p>
<p className="text-xs text-muted-foreground">
{new Date(tx.createdAt).toLocaleString("zh-CN")}
</p>
</div>
</div> </div>
<div> <div className="text-right">
<p className="text-sm font-medium">{tx.description}</p> <p className={`text-sm font-medium ${isIncome ? "text-green-600" : ""}`}>
<p className="text-xs text-muted-foreground"> {isIncome ? "+" : ""}¥{Math.abs(tx.amount).toFixed(2)}
{new Date(tx.createdAt).toLocaleString("zh-CN")}
</p> </p>
<Badge variant="outline" className="text-[10px]">
{typeLabels[tx.type]}
</Badge>
</div> </div>
</div> </div>
<div className="text-right"> )
<p className={`text-sm font-medium ${isIncome ? "text-green-600" : ""}`}> })
{isIncome ? "+" : ""}¥{Math.abs(tx.amount).toFixed(2)} ) : (
</p> <div className="text-center py-8 text-muted-foreground text-sm"></div>
<Badge variant="outline" className="text-[10px]"> )}
{typeLabels[tx.type]}
</Badge>
</div>
</div>
)
})}
</CardContent> </CardContent>
</Card> </Card>
</div> </div>