You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
8.5 KiB
TypeScript
135 lines
8.5 KiB
TypeScript
import { auth } from "@/auth";
|
|
import { prisma } from "@/lib/prisma";
|
|
import {
|
|
FileText,
|
|
Download,
|
|
Eye,
|
|
Search,
|
|
ChevronRight,
|
|
CreditCard
|
|
} from "lucide-react";
|
|
import { Card } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { formatCurrency } from "@/lib/utils";
|
|
|
|
export default async function PayslipsPage() {
|
|
const session = await auth();
|
|
const userId = (session?.user as any)?.id;
|
|
|
|
const payslips = await prisma.payslip.findMany({
|
|
where: { userId },
|
|
orderBy: [
|
|
{ year: 'desc' },
|
|
{ month: 'desc' }
|
|
]
|
|
});
|
|
|
|
return (
|
|
<div className="space-y-10 animate-in fade-in slide-in-from-bottom-2 duration-500">
|
|
<div className="flex flex-col md:flex-row md:items-center justify-between gap-6">
|
|
<div>
|
|
<h2 className="text-4xl font-extrabold tracking-tight">My Payslips</h2>
|
|
<p className="text-neutral-500 mt-2 font-medium">Securely access and download your past salary statements.</p>
|
|
</div>
|
|
<Button className="bg-indigo-600 hover:bg-indigo-700 text-white rounded-2xl h-14 px-8 font-black shadow-2xl shadow-indigo-100 dark:shadow-none transition-all active:scale-95 flex items-center gap-2">
|
|
<Download className="w-5 h-5" />
|
|
Download All (2024)
|
|
</Button>
|
|
</div>
|
|
|
|
<Card className="border-none shadow-2xl shadow-black/5 bg-white dark:bg-neutral-900 rounded-[2.5rem] overflow-hidden">
|
|
<div className="p-8 border-b border-neutral-100 dark:border-neutral-800 flex flex-col md:flex-row md:items-center justify-between gap-6">
|
|
<div className="relative flex-1 max-w-md">
|
|
<Search className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400" />
|
|
<Input placeholder="Search payslips..." className="pl-12 h-14 rounded-2xl bg-neutral-50 dark:bg-neutral-800 border-none shadow-none text-base" />
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<Button variant="outline" className="rounded-2xl border-neutral-200 h-14 px-6 font-bold hover:bg-white transition-all">
|
|
2024
|
|
</Button>
|
|
<Button variant="outline" className="rounded-2xl border-neutral-200 h-14 px-6 font-bold hover:bg-white transition-all">
|
|
All Years
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full text-left">
|
|
<thead>
|
|
<tr className="border-b border-neutral-100 dark:border-neutral-800 bg-neutral-50/50 dark:bg-neutral-800/50">
|
|
<th className="p-8 text-xs font-black uppercase tracking-[0.2em] text-neutral-400">Statement Ref</th>
|
|
<th className="p-8 text-xs font-black uppercase tracking-[0.2em] text-neutral-400">Period</th>
|
|
<th className="p-8 text-xs font-black uppercase tracking-[0.2em] text-neutral-400">Net Pay</th>
|
|
<th className="p-8 text-xs font-black uppercase tracking-[0.2em] text-neutral-400">Date Issued</th>
|
|
<th className="p-8 text-xs font-black uppercase tracking-[0.2em] text-neutral-400 text-right">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y divide-neutral-100 dark:divide-neutral-800">
|
|
{payslips.map((slip) => (
|
|
<tr key={slip.id} className="hover:bg-neutral-50/50 transition-all group">
|
|
<td className="p-8">
|
|
<div className="flex items-center gap-4">
|
|
<div className="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-900/20 flex items-center justify-center">
|
|
<FileText className="w-6 h-6 text-indigo-600 dark:text-indigo-400" />
|
|
</div>
|
|
<div>
|
|
<p className="font-bold text-neutral-900 dark:text-neutral-100">PAY-{slip.year}-{slip.month.substring(0, 3).toUpperCase()}</p>
|
|
<p className="text-[10px] font-black text-neutral-400 uppercase tracking-tighter">PDF Statement</p>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td className="p-8">
|
|
<p className="font-bold text-neutral-900 dark:text-neutral-100">{slip.month} {slip.year}</p>
|
|
</td>
|
|
<td className="p-8">
|
|
<span className="text-xl font-black text-indigo-600">
|
|
{formatCurrency(slip.amount.toString())}
|
|
</span>
|
|
</td>
|
|
<td className="p-8 text-neutral-500 font-medium">
|
|
{new Date(slip.createdAt).toLocaleDateString()}
|
|
</td>
|
|
<td className="p-8 flex justify-end gap-3 px-8">
|
|
<Button variant="ghost" className="rounded-2xl w-14 h-14 p-0 text-neutral-400 hover:text-indigo-600 hover:bg-white transition-all shadow-sm border border-transparent hover:border-neutral-100">
|
|
<Eye className="w-6 h-6" />
|
|
</Button>
|
|
<Button variant="ghost" className="rounded-2xl w-14 h-14 p-0 text-neutral-400 hover:text-emerald-600 hover:bg-white transition-all shadow-sm border border-transparent hover:border-neutral-100">
|
|
<Download className="w-6 h-6" />
|
|
</Button>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
{payslips.length === 0 && (
|
|
<div className="p-20 text-center">
|
|
<div className="w-20 h-20 bg-neutral-100 dark:bg-neutral-800 rounded-full flex items-center justify-center mx-auto mb-6">
|
|
<FileText className="w-10 h-10 text-neutral-300" />
|
|
</div>
|
|
<h3 className="text-xl font-black mb-2">No Payslips Yet</h3>
|
|
<p className="text-neutral-500 font-medium">Your payslips will appear here once issued by payroll.</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
|
|
<Card className="border-none shadow-2xl shadow-indigo-500/5 bg-gradient-to-br from-white to-indigo-50/30 dark:from-neutral-900 dark:to-indigo-950/10 rounded-[2.5rem] p-10 flex flex-col md:flex-row items-center gap-8 border border-indigo-100/50">
|
|
<div className="w-20 h-20 bg-indigo-600 rounded-3xl flex items-center justify-center shrink-0 shadow-2xl shadow-indigo-200">
|
|
<CreditCard className="w-10 h-10 text-white" />
|
|
</div>
|
|
<div className="flex-1 text-center md:text-left">
|
|
<h3 className="text-2xl font-black mb-2">Payroll Information</h3>
|
|
<p className="text-neutral-500 font-medium leading-relaxed">
|
|
Your salary is deposited into your primary bank account ending in <span className="text-indigo-600 font-bold font-mono">****4590</span> on the last business day of each month.
|
|
</p>
|
|
</div>
|
|
<Button variant="outline" className="rounded-2xl h-14 px-8 border-neutral-200 font-bold hover:bg-white shrink-0 group">
|
|
Update Banking
|
|
<ChevronRight className="w-4 h-4 ml-2 group-hover:translate-x-1 transition-transform" />
|
|
</Button>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|