2026-05-15 17:40:21 +05:30

266 lines
17 KiB
JavaScript

import React from 'react';
import { Head } from '@inertiajs/react';
import AdminLayout from '@/Layouts/AdminLayout';
import {
Download,
ArrowUpRight,
ArrowDownRight,
Calendar,
Filter,
Search,
CreditCard,
TrendingUp,
Users,
BadgeDollarSign,
CheckCircle2,
Clock,
FileText,
MoreHorizontal,
XCircle,
Building2,
Zap,
Globe
} from 'lucide-react';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
export default function PaymentsIndex({ stats, payments: initialPayments }) {
const [selectedPayment, setSelectedPayment] = React.useState(null);
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
const payments = initialPayments || [
{ id: 'PAY-001', employer: 'Al Barari Real Estate', plan: 'Premium Pass', amount: 199, date: '2026-05-15', status: 'Completed', method: 'Visa •••• 4242', period: 'May 2026 - June 2026' },
{ id: 'PAY-002', employer: 'Marina Cleaners', plan: 'Basic Search', amount: 99, date: '2026-05-14', status: 'Completed', method: 'Mastercard •••• 8812', period: 'May 2026 - June 2026' },
{ id: 'PAY-003', employer: 'Golden Hospitality', plan: 'VIP Concierge', amount: 499, date: '2026-05-14', status: 'Pending', method: 'Bank Transfer', period: 'May 2026 - June 2026' },
{ id: 'PAY-004', employer: 'Emirates Logistics', plan: 'Premium Pass', amount: 199, date: '2026-05-13', status: 'Completed', method: 'Visa •••• 1002', period: 'May 2026 - June 2026' },
{ id: 'PAY-005', employer: 'Dubai Mall Services', plan: 'Premium Pass', amount: 199, date: '2026-05-12', status: 'Failed', method: 'Visa •••• 4242', period: 'May 2026 - June 2026' },
];
const analytics = [
{ title: 'Total Revenue', value: '42,850', icon: BadgeDollarSign, trend: '+15.2%', positive: true, color: 'emerald' },
{ title: 'Active Subscriptions', value: '184', icon: Users, trend: '+4.3%', positive: true, color: 'blue' },
{ title: 'Failed Payments', value: '3', icon: XCircle, trend: '-2.1%', positive: true, color: 'rose' },
{ title: 'Average Ticket', value: '232', icon: TrendingUp, trend: '+0.8%', positive: true, color: 'amber' },
];
const openDetails = (pay) => {
setSelectedPayment(pay);
setIsDialogOpen(true);
};
return (
<AdminLayout title="Financial Analytics">
<Head title="Payments & Revenue" />
<div className="space-y-8">
{/* Stats Overview */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{analytics.map((item, i) => (
<div key={i} className="bg-white p-6 rounded-2xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-center justify-between mb-4">
<div className={`w-12 h-12 rounded-xl flex items-center justify-center bg-${item.color}-50 text-${item.color}-600 shadow-inner`}>
<item.icon className="w-6 h-6" />
</div>
<div className={`flex items-center space-x-1 px-2 py-1 rounded-full text-[10px] font-black uppercase tracking-tight ${
item.positive ? 'bg-emerald-50 text-emerald-600' : 'bg-rose-50 text-rose-600'
}`}>
{item.positive ? <ArrowUpRight className="w-3 h-3" /> : <ArrowDownRight className="w-3 h-3" />}
<span>{item.trend}</span>
</div>
</div>
<h3 className="text-sm font-semibold text-slate-500 mb-1">{item.title}</h3>
<div className="flex items-baseline space-x-2">
<span className="text-2xl font-black text-slate-900 tracking-tight">{item.title.includes('Revenue') || item.title.includes('Ticket') ? 'AED ' : ''}{item.value}</span>
</div>
</div>
))}
</div>
{/* Main Content Area */}
<div className="bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden">
<div className="p-6 border-b border-slate-100 flex flex-col md:flex-row md:items-center justify-between gap-4">
<div>
<h2 className="text-lg font-black text-slate-900 tracking-tight">Recent Transactions</h2>
<p className="text-xs text-slate-500 font-medium uppercase tracking-widest mt-1">Audit log of all employer subscription payments</p>
</div>
<div className="flex items-center space-x-3">
<div className="relative">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
<input
type="text"
placeholder="Search by Employer..."
className="pl-10 pr-4 py-2 bg-slate-50 border border-slate-100 rounded-lg text-xs font-bold focus:ring-4 focus:ring-teal-500/10 outline-none w-48 lg:w-64"
/>
</div>
<button className="p-2.5 bg-slate-50 text-slate-500 rounded-lg border border-slate-100 hover:bg-slate-100 transition-colors">
<Filter className="w-4 h-4" />
</button>
<button className="flex items-center space-x-2 px-4 py-2 bg-[#0F6E56] text-white rounded-lg text-xs font-bold uppercase tracking-widest hover:bg-[#085041] transition-all shadow-lg shadow-teal-500/10">
<Download className="w-4 h-4" />
<span>Export</span>
</button>
</div>
</div>
<Table>
<TableHeader>
<TableRow className="bg-slate-50/50 hover:bg-slate-50/50">
<TableHead className="font-bold text-slate-500 text-[10px] uppercase tracking-widest h-14 pl-8">Employer</TableHead>
<TableHead className="font-bold text-slate-500 text-[10px] uppercase tracking-widest h-14">Plan Name</TableHead>
<TableHead className="font-bold text-slate-500 text-[10px] uppercase tracking-widest h-14">Amount (AED)</TableHead>
<TableHead className="font-bold text-slate-500 text-[10px] uppercase tracking-widest h-14">Date</TableHead>
<TableHead className="font-bold text-slate-500 text-[10px] uppercase tracking-widest h-14">Status</TableHead>
<TableHead className="font-bold text-slate-500 text-[10px] uppercase tracking-widest h-14 text-right pr-8">Ref</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{payments.map((pay) => (
<TableRow
key={pay.id}
className="hover:bg-slate-50 transition-colors cursor-pointer group"
onClick={() => openDetails(pay)}
>
<TableCell className="py-5 pl-8">
<div className="flex items-center space-x-3">
<div className="w-8 h-8 rounded-lg bg-slate-100 flex items-center justify-center text-slate-400 group-hover:bg-teal-50 group-hover:text-teal-600 transition-colors">
<Building2 className="w-4 h-4" />
</div>
<span className="font-bold text-slate-900 text-sm">{pay.employer}</span>
</div>
</TableCell>
<TableCell>
<span className="px-2.5 py-1 bg-blue-50 text-blue-600 rounded-lg text-[10px] font-black uppercase tracking-tight">
{pay.plan}
</span>
</TableCell>
<TableCell className="font-black text-slate-900 tracking-tight">{pay.amount}</TableCell>
<TableCell className="text-xs font-bold text-slate-400">{pay.date}</TableCell>
<TableCell>
<div className="flex items-center space-x-2">
{pay.status === 'Completed' && <CheckCircle2 className="w-4 h-4 text-emerald-500" />}
{pay.status === 'Pending' && <Clock className="w-4 h-4 text-amber-500" />}
{pay.status === 'Failed' && <XCircle className="w-4 h-4 text-rose-500" />}
<span className={`text-[10px] font-black uppercase tracking-widest ${
pay.status === 'Completed' ? 'text-emerald-600' :
pay.status === 'Pending' ? 'text-amber-600' : 'text-rose-600'
}`}>
{pay.status}
</span>
</div>
</TableCell>
<TableCell className="text-right pr-8">
<span className="text-[10px] font-mono font-bold text-slate-300 uppercase">{pay.id}</span>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<div className="p-6 border-t border-slate-100 flex items-center justify-between bg-slate-50/30">
<p className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Showing 5 of 1,284 transactions</p>
<div className="flex items-center space-x-2">
<button className="px-4 py-2 bg-white border border-slate-200 rounded-lg text-[10px] font-black uppercase tracking-widest text-slate-500 hover:bg-slate-50 transition-colors">Previous</button>
<button className="px-4 py-2 bg-white border border-slate-200 rounded-lg text-[10px] font-black uppercase tracking-widest text-slate-500 hover:bg-slate-50 transition-colors">Next</button>
</div>
</div>
</div>
</div>
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<DialogContent className="max-w-2xl bg-white p-0 overflow-hidden rounded-[32px] border-none shadow-2xl">
<div className="bg-slate-900 p-8 text-white relative">
<div className="absolute top-0 right-0 p-8 opacity-10">
<BadgeDollarSign className="w-32 h-32" />
</div>
<div className="relative z-10 space-y-2">
<div className="flex items-center space-x-2 text-[10px] font-black uppercase tracking-[0.2em] text-teal-400">
<Zap className="w-3 h-3" />
<span>Transaction Details</span>
</div>
<h2 className="text-3xl font-black tracking-tight">{selectedPayment?.id}</h2>
<p className="text-slate-400 text-sm font-medium">{selectedPayment?.date} External Reference: TRX-99283-PL</p>
</div>
</div>
<div className="p-8 space-y-8">
<div className="grid grid-cols-2 gap-8">
<div className="space-y-4">
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Employer</label>
<div className="flex items-center space-x-2 text-sm font-bold text-slate-900">
<Building2 className="w-4 h-4 text-[#0F6E56]" />
<span>{selectedPayment?.employer}</span>
</div>
</div>
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Subscription Plan</label>
<div className="flex items-center space-x-2 text-sm font-bold text-slate-900">
<Zap className="w-4 h-4 text-amber-500" />
<span>{selectedPayment?.plan}</span>
</div>
</div>
</div>
<div className="space-y-4 text-right">
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Amount Paid</label>
<div className="text-2xl font-black text-slate-900">AED {selectedPayment?.amount}</div>
</div>
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Payment Status</label>
<div className={`text-xs font-black uppercase tracking-widest ${
selectedPayment?.status === 'Completed' ? 'text-emerald-600' :
selectedPayment?.status === 'Pending' ? 'text-amber-600' : 'text-rose-600'
}`}>
{selectedPayment?.status}
</div>
</div>
</div>
</div>
<div className="bg-slate-50 rounded-2xl p-6 border border-slate-100 grid grid-cols-2 gap-6">
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Billing Period</label>
<div className="text-xs font-bold text-slate-700 flex items-center space-x-2">
<Calendar className="w-3.5 h-3.5" />
<span>{selectedPayment?.period}</span>
</div>
</div>
<div className="space-y-1">
<label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Payment Method</label>
<div className="text-xs font-bold text-slate-700 flex items-center space-x-2">
<CreditCard className="w-3.5 h-3.5" />
<span>{selectedPayment?.method}</span>
</div>
</div>
</div>
<div className="flex items-center justify-between pt-4 border-t border-slate-100">
<div className="flex items-center space-x-2 text-[10px] font-bold text-slate-400 uppercase tracking-widest">
<Globe className="w-3.5 h-3.5" />
<span>IP: 192.168.1.1 (Dubai, UAE)</span>
</div>
<button className="text-[10px] font-black text-[#0F6E56] uppercase tracking-widest hover:underline flex items-center space-x-1">
<FileText className="w-3.5 h-3.5" />
<span>Download PDF Invoice</span>
</button>
</div>
</div>
</DialogContent>
</Dialog>
</AdminLayout>
);
}