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.

167 lines
11 KiB
TypeScript

"use client";
import { useState } from "react";
import { Card, CardHeader, CardTitle, CardContent, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
PieChart,
Plus,
Settings2,
AlertTriangle,
CheckCircle2,
ArrowRight,
Target,
BarChart,
Edit2
} from "lucide-react";
const initialBudgets = [
{ department: 'Engineering (IT)', limit: 250000, spent: 185000, status: 'Healthy', color: 'bg-indigo-600' },
{ department: 'Marketing', limit: 120000, spent: 115000, status: 'Warning', color: 'bg-rose-500' },
{ department: 'Human Resources', limit: 80000, spent: 42000, status: 'Healthy', color: 'bg-emerald-500' },
{ department: 'Customer Success', limit: 60000, spent: 58000, status: 'Critical', color: 'bg-amber-500' },
];
export default function BudgetingPage() {
const [budgets, setBudgets] = useState(initialBudgets);
return (
<div className="space-y-8 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-4">
<div>
<h2 className="text-3xl font-bold tracking-tight">Department Budgeting</h2>
<p className="text-neutral-500 mt-1 font-medium">Set and monitor expenditure limits across the organization.</p>
</div>
<Button className="bg-neutral-900 text-white hover:bg-black rounded-2xl h-14 px-8 font-black shadow-2xl transition-all active:scale-95 group">
<Plus className="w-5 h-5 mr-1 group-hover:rotate-180 transition-transform duration-500" />
Create Budget
</Button>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
<Card className="border-none shadow-2xl shadow-indigo-500/10 bg-white dark:bg-neutral-900 rounded-[3rem] p-10 overflow-hidden relative">
<div className="relative z-10 flex flex-col h-full">
<div className="flex items-center gap-4 mb-10">
<div className="w-16 h-16 bg-indigo-50 dark:bg-indigo-900/20 rounded-3xl flex items-center justify-center">
<Target className="w-8 h-8 text-indigo-600" />
</div>
<div>
<h3 className="text-2xl font-black text-neutral-900 dark:text-neutral-100 italic">Total Budget Allocation</h3>
<p className="font-bold text-neutral-400 uppercase tracking-widest text-xs mt-1">FY 2024 Q1 ACTIVE</p>
</div>
</div>
<div className="flex-1 flex flex-col justify-center gap-12">
<div>
<div className="flex justify-between items-end mb-4">
<p className="text-sm font-bold text-neutral-400 uppercase tracking-[0.2em]">Overall Utilization</p>
<p className="text-6xl font-black text-neutral-900 dark:text-neutral-100 tracking-tighter">78<span className="text-indigo-600 text-4xl">%</span></p>
</div>
<div className="h-6 w-full bg-neutral-50 dark:bg-neutral-800 rounded-full overflow-hidden p-1.5 border border-neutral-100 dark:border-neutral-800 shadow-inner">
<div className="h-full bg-gradient-to-r from-indigo-600 to-indigo-400 rounded-full shadow-[0_0_20px_rgba(79,70,229,0.3)]" style={{ width: '78%' }} />
</div>
</div>
<div className="grid grid-cols-2 gap-8">
<div className="space-y-1">
<p className="text-[10px] font-black text-neutral-400 uppercase tracking-widest">Total Limit</p>
<p className="text-2xl font-black text-neutral-900 dark:text-neutral-100">$510,000.00</p>
</div>
<div className="space-y-1">
<p className="text-[10px] font-black text-neutral-400 uppercase tracking-widest">Spent to Date</p>
<p className="text-2xl font-black text-indigo-600">$400,000.00</p>
</div>
</div>
</div>
</div>
{/* Decorative blobs */}
<div className="absolute top-[-10%] right-[-10%] w-[40%] h-[40%] bg-indigo-500/5 blur-[80px] rounded-full" />
</Card>
<Card className="border-none shadow-2xl shadow-black/5 bg-neutral-900 rounded-[3rem] p-10 text-white flex flex-col justify-center">
<div className="flex items-center gap-4 mb-8">
<div className="p-3 bg-white/10 rounded-2xl">
<AlertTriangle className="w-6 h-6 text-amber-500" />
</div>
<div>
<h3 className="text-xl font-bold">Budget Insights</h3>
<p className="text-neutral-400 text-sm">Automated analysis of current spend</p>
</div>
</div>
<div className="space-y-6">
<div className="p-6 bg-white/5 rounded-3xl border border-white/5 hover:bg-white/10 transition-colors group cursor-pointer">
<div className="flex justify-between items-start mb-2">
<span className="text-xs font-black text-rose-500 uppercase tracking-widest bg-rose-500/10 px-2 py-1 rounded-lg">Critical Alert</span>
<ArrowRight className="w-4 h-4 text-neutral-600 group-hover:text-white transition-colors" />
</div>
<p className="font-bold text-lg mb-1">Marketing Budget at 96%</p>
<p className="text-sm text-neutral-400 font-medium leading-relaxed">Marketing spend is significantly higher than projected. Approvals for non-essential spend restricted.</p>
</div>
<div className="p-6 bg-white/5 rounded-3xl border border-white/5 hover:bg-white/10 transition-colors group cursor-pointer">
<div className="flex justify-between items-start mb-2">
<span className="text-xs font-black text-emerald-500 uppercase tracking-widest bg-emerald-500/10 px-2 py-1 rounded-lg">Optimization</span>
<ArrowRight className="w-4 h-4 text-neutral-600 group-hover:text-white transition-colors" />
</div>
<p className="font-bold text-lg mb-1">HR Savings Opportunity</p>
<p className="text-sm text-neutral-400 font-medium leading-relaxed">Current HR spend is 45% below budget. Consider reallocating $15k to Engineering Q2.</p>
</div>
</div>
</Card>
</div>
<div className="grid grid-cols-1 gap-6">
<h3 className="text-xl font-black text-neutral-900 dark:text-neutral-100 flex items-center gap-3">
<BarChart className="w-6 h-6 text-indigo-600" />
Departmental Breakdown
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6">
{budgets.map((b, i) => {
const percent = (b.spent / b.limit) * 100;
return (
<Card key={i} className="border-none shadow-xl shadow-black/5 bg-white dark:bg-neutral-900 rounded-[2.5rem] p-8 flex flex-col justify-between group hover:scale-[1.03] transition-all duration-300">
<div>
<div className="flex justify-between items-start mb-6">
<div className={`p-3 rounded-2xl ${b.color} text-white shadow-lg shadow-black/5`}>
<Settings2 className="w-5 h-5" />
</div>
<Button variant="ghost" size="icon" className="rounded-full hover:bg-neutral-100">
<Edit2 className="w-4 h-4 text-neutral-400" />
</Button>
</div>
<h4 className="font-black text-xl mb-1 text-neutral-900 dark:text-neutral-100">{b.department}</h4>
<p className="text-[10px] font-black text-neutral-400 uppercase tracking-[0.2em] mb-4">Current Period</p>
<div className="space-y-4 mb-8">
<div className="flex justify-between text-sm font-bold">
<span className="text-neutral-500">Utilization</span>
<span className={percent > 90 ? 'text-rose-600' : 'text-neutral-900 dark:text-neutral-100'}>{percent.toFixed(0)}%</span>
</div>
<div className="h-2 w-full bg-neutral-50 dark:bg-neutral-800 rounded-full overflow-hidden">
<div className={`h-full ${b.color} rounded-full transition-all duration-1000 ease-out shadow-[0_0_10px_rgba(0,0,0,0.1)]`} style={{ width: `${percent}%` }} />
</div>
</div>
</div>
<div className="pt-6 border-t border-neutral-100 dark:border-neutral-800 space-y-2">
<div className="flex justify-between items-center">
<span className="text-xs font-bold text-neutral-400 uppercase tracking-tighter">Spent</span>
<span className="font-black text-neutral-900 dark:text-neutral-100 text-lg">${(b.spent / 1000).toFixed(0)}k</span>
</div>
<div className="flex justify-between items-center opacity-40">
<span className="text-xs font-bold text-neutral-400 uppercase tracking-tighter">Limit</span>
<span className="font-bold text-sm">${(b.limit / 1000).toFixed(0)}k</span>
</div>
</div>
</Card>
);
})}
</div>
</div>
</div>
);
}