Files
soul/app/admin/withdrawals/page.tsx
2026-01-09 11:58:08 +08:00

173 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState, useEffect } from "react"
import { useStore } from "@/lib/store"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Check, Clock, Wallet, History } from "lucide-react"
export default function WithdrawalsPage() {
const { withdrawals, completeWithdrawal } = useStore()
const [mounted, setMounted] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) return null
const pendingWithdrawals = withdrawals?.filter((w) => w.status === "pending") || []
const historyWithdrawals =
withdrawals
?.filter((w) => w.status !== "pending")
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) || []
const totalPending = pendingWithdrawals.reduce((sum, w) => sum + w.amount, 0)
const handleApprove = (id: string) => {
if (confirm("确认打款并完成此提现申请吗?")) {
completeWithdrawal(id)
}
}
return (
<div className="p-8 max-w-6xl mx-auto">
<div className="mb-8">
<h1 className="text-2xl font-bold text-white"></h1>
<p className="text-gray-400 mt-1">
{pendingWithdrawals.length} ¥{totalPending.toFixed(2)}
</p>
</div>
<div className="grid gap-6">
{/* 待处理申请 */}
<Card className="bg-[#0f2137] border-gray-700/50 shadow-xl">
<CardHeader>
<CardTitle className="flex items-center gap-2 text-white">
<div className="p-2 rounded-lg bg-orange-500/20">
<Clock className="w-5 h-5 text-orange-400" />
</div>
({pendingWithdrawals.length})
</CardTitle>
</CardHeader>
<CardContent>
{pendingWithdrawals.length === 0 ? (
<div className="text-center py-12">
<Wallet className="w-12 h-12 text-gray-600 mx-auto mb-3" />
<p className="text-gray-500"></p>
</div>
) : (
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="bg-[#0a1628] text-gray-400">
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-right font-medium"></th>
</tr>
</thead>
<tbody className="divide-y divide-gray-700/50">
{pendingWithdrawals.map((w) => (
<tr key={w.id} className="hover:bg-[#0a1628] transition-colors">
<td className="p-4 text-gray-400">{new Date(w.createdAt).toLocaleString()}</td>
<td className="p-4">
<div>
<p className="font-medium text-white">{w.name}</p>
<p className="text-xs text-gray-500 font-mono">{w.userId.slice(0, 8)}...</p>
</div>
</td>
<td className="p-4">
<Badge
className={
w.method === "wechat"
? "bg-green-500/20 text-green-400 hover:bg-green-500/20 border-0"
: "bg-blue-500/20 text-blue-400 hover:bg-blue-500/20 border-0"
}
>
{w.method === "wechat" ? "微信" : "支付宝"}
</Badge>
</td>
<td className="p-4 font-mono text-gray-300">{w.account}</td>
<td className="p-4">
<span className="font-bold text-orange-400">¥{w.amount.toFixed(2)}</span>
</td>
<td className="p-4 text-right">
<Button
size="sm"
onClick={() => handleApprove(w.id)}
className="bg-[#38bdac] hover:bg-[#2da396] text-white"
>
<Check className="w-4 h-4 mr-1" />
</Button>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</CardContent>
</Card>
{/* 处理历史 */}
<Card className="bg-[#0f2137] border-gray-700/50 shadow-xl">
<CardHeader>
<CardTitle className="flex items-center gap-2 text-white">
<div className="p-2 rounded-lg bg-gray-700/50">
<History className="w-5 h-5 text-gray-400" />
</div>
</CardTitle>
</CardHeader>
<CardContent>
{historyWithdrawals.length === 0 ? (
<div className="text-center py-12">
<History className="w-12 h-12 text-gray-600 mx-auto mb-3" />
<p className="text-gray-500"></p>
</div>
) : (
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="bg-[#0a1628] text-gray-400">
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
<th className="p-4 text-left font-medium"></th>
</tr>
</thead>
<tbody className="divide-y divide-gray-700/50">
{historyWithdrawals.map((w) => (
<tr key={w.id} className="hover:bg-[#0a1628] transition-colors">
<td className="p-4 text-gray-400">{new Date(w.createdAt).toLocaleString()}</td>
<td className="p-4 text-gray-400">
{w.completedAt ? new Date(w.completedAt).toLocaleString() : "-"}
</td>
<td className="p-4 font-medium text-white">{w.name}</td>
<td className="p-4 text-gray-300">{w.method === "wechat" ? "微信" : "支付宝"}</td>
<td className="p-4 font-medium text-white">¥{w.amount.toFixed(2)}</td>
<td className="p-4">
<Badge className="bg-green-500/20 text-green-400 hover:bg-green-500/20 border-0">
</Badge>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</CardContent>
</Card>
</div>
</div>
)
}