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.

112 lines
6.5 KiB
TypeScript

import { auth } from "@/auth";
import { prisma } from "@/lib/prisma";
import { OvertimeForm } from "./overtime-form";
import {
Clock,
Calendar,
CheckCircle2,
AlertCircle,
Zap
} from "lucide-react";
import { Card, CardHeader, CardTitle, CardContent, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
export default async function OvertimePage() {
const session = await auth();
const userId = (session?.user as any)?.id;
const logs = await prisma.overtime.findMany({
where: { userId },
orderBy: { date: 'desc' },
take: 10
});
const totalYTD = logs.reduce((acc, curr) => acc + curr.hours, 0);
return (
<div className="space-y-8 animate-in fade-in slide-in-from-bottom-2 duration-500">
<div>
<h2 className="text-3xl font-bold tracking-tight">Overtime Management</h2>
<p className="text-neutral-500 mt-1">Log your extra hours and track approval status.</p>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div className="lg:col-span-2 space-y-8">
<OvertimeForm />
<Card className="border-none shadow-2xl shadow-black/5 bg-white dark:bg-neutral-900 rounded-3xl overflow-hidden">
<div className="p-8 border-b border-neutral-100 dark:border-neutral-800 flex justify-between items-center">
<h3 className="text-xl font-bold">Recent Logs</h3>
<Button variant="ghost" className="text-indigo-600 font-semibold hover:bg-indigo-50 rounded-xl px-4 py-2 h-auto text-sm">
View History
</Button>
</div>
<div className="divide-y divide-neutral-100 dark:divide-neutral-800">
{logs.map((log, i) => (
<div key={log.id} className="p-8 hover:bg-neutral-50/50 transition-colors flex items-center justify-between group">
<div className="flex items-center gap-6">
<div className="hidden sm:flex flex-col items-center">
<span className="text-xs font-bold text-neutral-400 uppercase tracking-tighter">Day</span>
<span className="text-2xl font-black text-neutral-300 group-hover:text-indigo-200 transition-colors">
{new Date(log.date).getDate().toString().padStart(2, '0')}
</span>
</div>
<div>
<p className="font-bold text-neutral-900 dark:text-neutral-100">{log.reason}</p>
<div className="flex items-center gap-3 mt-1 text-sm text-neutral-500">
<span className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
{new Date(log.date).toLocaleDateString()}
</span>
<span className="flex items-center gap-1">
<Clock className="w-3 h-3" />
{log.hours} hours
</span>
</div>
</div>
</div>
<div className="flex flex-col items-end gap-2">
<span className={`text-[10px] font-bold uppercase px-2 py-1 rounded-full ${log.status === 'PAID' ? 'bg-emerald-100 text-emerald-700' :
log.status === 'APPROVED' ? 'bg-indigo-100 text-indigo-700' : 'bg-amber-100 text-amber-700'
}`}>
{log.status}
</span>
<p className="text-xs font-medium text-neutral-400">Payroll: Current Cycle</p>
</div>
</div>
))}
</div>
</Card>
</div>
<div className="space-y-8">
<Card className="border-none shadow-2xl shadow-indigo-500/10 bg-gradient-to-br from-indigo-600 to-violet-700 rounded-3xl p-8 text-white relative overflow-hidden">
<div className="relative z-10">
<div className="w-12 h-12 bg-white/20 rounded-2xl flex items-center justify-center mb-6 backdrop-blur-md">
<Clock className="w-6 h-6 text-white" />
</div>
<h3 className="text-xl font-bold mb-2">Total Overtime (YTD)</h3>
<p className="text-4xl font-black mb-4">{totalYTD}h</p>
<div className="w-full bg-white/10 rounded-full h-2 mb-2">
<div className="bg-white h-full rounded-full w-[65%]" style={{ width: `${Math.min(100, (totalYTD / 60) * 100)}%` }} />
</div>
<p className="text-xs text-indigo-100">Relative to monthly capacity</p>
</div>
<div className="absolute top-[-20%] right-[-20%] w-48 h-48 bg-white/5 rounded-full blur-3xl pointer-events-none" />
</Card>
<Card className="border-none shadow-2xl shadow-black/5 bg-white dark:bg-neutral-900 rounded-3xl p-8">
<h3 className="text-lg font-bold mb-4 flex items-center gap-2">
<AlertCircle className="w-5 h-5 text-amber-500" />
Important Note
</h3>
<p className="text-sm text-neutral-500 leading-relaxed">
Overtime logs must be submitted within 48 hours of completion. All logs are subject to manager approval before being processed for payroll.
</p>
</Card>
</div>
</div>
</div>
);
}