136 lines
5.6 KiB
TypeScript
136 lines
5.6 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { useStore, type Withdrawal } from "@/lib/store"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|
import { Check, X, Clock } 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 handleApprove = (id: string) => {
|
|
if (confirm("确认打款并完成此提现申请吗?")) {
|
|
completeWithdrawal(id)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="p-6 max-w-6xl mx-auto">
|
|
<h1 className="text-2xl font-bold mb-6">提现管理</h1>
|
|
|
|
<div className="grid gap-6">
|
|
{/* Pending Requests */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<Clock className="w-5 h-5 text-orange-500" />
|
|
待处理申请 ({pendingWithdrawals.length})
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{pendingWithdrawals.length === 0 ? (
|
|
<p className="text-gray-500 text-center py-8">暂无待处理申请</p>
|
|
) : (
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full text-sm text-left">
|
|
<thead className="bg-gray-50 text-gray-700">
|
|
<tr>
|
|
<th className="p-3">申请时间</th>
|
|
<th className="p-3">用户ID</th>
|
|
<th className="p-3">姓名</th>
|
|
<th className="p-3">渠道</th>
|
|
<th className="p-3">账号</th>
|
|
<th className="p-3">金额</th>
|
|
<th className="p-3 text-right">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y">
|
|
{pendingWithdrawals.map((w) => (
|
|
<tr key={w.id} className="hover:bg-gray-50">
|
|
<td className="p-3">{new Date(w.createdAt).toLocaleString()}</td>
|
|
<td className="p-3 font-mono text-xs">{w.userId.slice(0, 8)}...</td>
|
|
<td className="p-3 font-medium">{w.name}</td>
|
|
<td className="p-3">
|
|
<span className={`px-2 py-1 rounded-full text-xs text-white ${w.method === "wechat" ? "bg-green-600" : "bg-blue-600"}`}>
|
|
{w.method === "wechat" ? "微信" : "支付宝"}
|
|
</span>
|
|
</td>
|
|
<td className="p-3 font-mono">{w.account}</td>
|
|
<td className="p-3 font-bold text-orange-600">¥{w.amount.toFixed(2)}</td>
|
|
<td className="p-3 text-right">
|
|
<Button size="sm" onClick={() => handleApprove(w.id)} className="bg-green-600 hover:bg-green-700 text-white">
|
|
<Check className="w-4 h-4 mr-1" />
|
|
确认打款
|
|
</Button>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* History */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>处理历史</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{historyWithdrawals.length === 0 ? (
|
|
<p className="text-gray-500 text-center py-8">暂无历史记录</p>
|
|
) : (
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full text-sm text-left">
|
|
<thead className="bg-gray-50 text-gray-700">
|
|
<tr>
|
|
<th className="p-3">申请时间</th>
|
|
<th className="p-3">处理时间</th>
|
|
<th className="p-3">姓名</th>
|
|
<th className="p-3">渠道</th>
|
|
<th className="p-3">金额</th>
|
|
<th className="p-3">状态</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y">
|
|
{historyWithdrawals.map((w) => (
|
|
<tr key={w.id} className="hover:bg-gray-50">
|
|
<td className="p-3 text-gray-500">{new Date(w.createdAt).toLocaleString()}</td>
|
|
<td className="p-3 text-gray-500">{w.completedAt ? new Date(w.completedAt).toLocaleString() : "-"}</td>
|
|
<td className="p-3">{w.name}</td>
|
|
<td className="p-3">
|
|
{w.method === "wechat" ? "微信" : "支付宝"}
|
|
</td>
|
|
<td className="p-3 font-medium">¥{w.amount.toFixed(2)}</td>
|
|
<td className="p-3">
|
|
<span className="px-2 py-1 rounded-full text-xs text-green-600 border border-green-200 bg-green-50">
|
|
已完成
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|