Files
SubSplit/src/components/Header.tsx
T

198 lines
9.5 KiB
TypeScript

import React from 'react';
import { CreditCard, Users, RefreshCw, Share2, Plus, Sparkles, Receipt, DollarSign } from 'lucide-react';
interface HeaderProps {
activeTab: 'dashboard' | 'subscriptions' | 'one-off' | 'members' | 'settlements';
setActiveTab: (tab: 'dashboard' | 'subscriptions' | 'one-off' | 'members' | 'settlements') => void;
totalActiveSubs: number;
totalOneOffCount?: number;
totalMonthlyCost: number;
onOpenAddSub: () => void;
onOpenAddExpense?: () => void;
onOpenRecordSettlement?: () => void;
onOpenShareReport: () => void;
onResetData: () => void;
}
export const Header: React.FC<HeaderProps> = ({
activeTab,
setActiveTab,
totalActiveSubs,
totalOneOffCount = 0,
totalMonthlyCost,
onOpenAddSub,
onOpenAddExpense,
onOpenRecordSettlement,
onOpenShareReport,
onResetData,
}) => {
return (
<header className="bg-slate-900 text-white border-b border-slate-800/80 sticky top-0 z-30 shadow-md backdrop-blur-md bg-slate-900/95">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-col md:flex-row md:items-center md:justify-between py-3.5 gap-4">
{/* Logo & Brand */}
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-indigo-500 via-indigo-600 to-violet-700 flex items-center justify-center shadow-md shadow-indigo-500/25 ring-1 ring-white/20">
<CreditCard className="w-5 h-5 text-white" />
</div>
<div>
<div className="flex items-center space-x-2">
<h1 className="text-xl font-extrabold tracking-tight text-white">SubSplit</h1>
<span className="px-2.5 py-0.5 text-[11px] font-semibold bg-indigo-500/20 text-indigo-300 border border-indigo-500/30 rounded-full flex items-center gap-1">
<Sparkles className="w-3 h-3 text-indigo-400" /> Multi-Family
</span>
</div>
<p className="text-[11px] text-slate-400 font-medium">Shared Subscription & One-Off Charges Engine</p>
</div>
</div>
{/* Quick Actions Mobile */}
<div className="flex md:hidden items-center space-x-1.5">
{onOpenRecordSettlement && (
<button
onClick={onOpenRecordSettlement}
className="p-2 bg-emerald-600 hover:bg-emerald-500 text-white rounded-xl transition text-xs font-semibold flex items-center shadow-xs"
title="Record Settlement"
>
<DollarSign className="w-4 h-4" />
</button>
)}
{onOpenAddExpense && (
<button
onClick={onOpenAddExpense}
className="p-2 bg-amber-600 hover:bg-amber-500 text-white rounded-xl transition text-xs font-semibold flex items-center shadow-xs"
title="Add One-Off Charge"
>
<Receipt className="w-4 h-4" />
</button>
)}
<button
onClick={onOpenAddSub}
className="p-2 bg-indigo-600 hover:bg-indigo-500 text-white rounded-xl transition text-xs font-semibold flex items-center shadow-xs"
title="Add Subscription"
>
<Plus className="w-4 h-4" />
</button>
</div>
</div>
{/* Quick Metrics Bar */}
<div className="flex items-center justify-between md:justify-end space-x-3.5 bg-slate-800/90 p-2 sm:p-2.5 rounded-xl border border-slate-700/70 text-xs sm:text-sm shadow-inner">
<div className="px-3 border-r border-slate-700/80">
<span className="text-slate-400 block text-[10px] uppercase tracking-wider font-semibold">Active Subs</span>
<span className="font-bold text-white text-base leading-tight">{totalActiveSubs}</span>
</div>
<div className="px-3 border-r border-slate-700/80">
<span className="text-slate-400 block text-[10px] uppercase tracking-wider font-semibold">Total Outlay</span>
<span className="font-bold text-emerald-400 text-base leading-tight">${totalMonthlyCost.toFixed(2)}<span className="text-xs text-slate-400 font-normal">/mo</span></span>
</div>
<div className="flex items-center space-x-2 pl-1">
<button
onClick={onOpenShareReport}
className="px-3 py-1.5 bg-slate-700/80 hover:bg-slate-700 text-slate-200 hover:text-white rounded-lg text-xs font-semibold transition flex items-center gap-1.5 border border-slate-600/50"
title="Share Chat Balance Report"
>
<Share2 className="w-3.5 h-3.5 text-indigo-400" />
<span className="hidden sm:inline">Export Report</span>
</button>
<button
onClick={onResetData}
className="p-1.5 text-slate-400 hover:text-slate-200 hover:bg-slate-700/70 rounded-lg transition"
title="Reset to Seed Data"
>
<RefreshCw className="w-4 h-4" />
</button>
{onOpenRecordSettlement && (
<button
onClick={onOpenRecordSettlement}
className="hidden md:flex px-3 py-1.5 bg-emerald-600 hover:bg-emerald-500 active:scale-[0.98] text-white rounded-lg text-xs font-semibold transition items-center gap-1.5 shadow-sm shadow-emerald-600/20"
>
<DollarSign className="w-3.5 h-3.5" />
<span>Record Settlement</span>
</button>
)}
{onOpenAddExpense && (
<button
onClick={onOpenAddExpense}
className="hidden md:flex px-3 py-1.5 bg-amber-600 hover:bg-amber-500 active:scale-[0.98] text-white rounded-lg text-xs font-semibold transition items-center gap-1.5 shadow-sm shadow-amber-600/20"
>
<Plus className="w-3.5 h-3.5" />
<span>Log One-Off</span>
</button>
)}
<button
onClick={onOpenAddSub}
className="hidden md:flex px-3.5 py-1.5 bg-indigo-600 hover:bg-indigo-500 active:scale-[0.98] text-white rounded-lg text-xs font-semibold transition items-center gap-1.5 shadow-sm shadow-indigo-600/30"
>
<Plus className="w-4 h-4" />
<span>Add Sub</span>
</button>
</div>
</div>
</div>
{/* Navigation Tabs */}
<div className="flex space-x-1 border-t border-slate-800/80 pt-2 overflow-x-auto">
<button
onClick={() => setActiveTab('dashboard')}
className={`px-4 py-2.5 text-xs sm:text-sm font-semibold rounded-t-xl transition flex items-center gap-2 whitespace-nowrap ${
activeTab === 'dashboard'
? 'bg-slate-800 text-indigo-400 border-t-2 border-indigo-500 shadow-xs'
: 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/50'
}`}
>
<CreditCard className="w-4 h-4" />
<span>Dashboard & Balances</span>
</button>
<button
onClick={() => setActiveTab('subscriptions')}
className={`px-4 py-2.5 text-xs sm:text-sm font-semibold rounded-t-xl transition flex items-center gap-2 whitespace-nowrap ${
activeTab === 'subscriptions'
? 'bg-slate-800 text-indigo-400 border-t-2 border-indigo-500 shadow-xs'
: 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/50'
}`}
>
<CreditCard className="w-4 h-4" />
<span>Subscriptions ({totalActiveSubs})</span>
</button>
<button
onClick={() => setActiveTab('one-off')}
className={`px-4 py-2.5 text-xs sm:text-sm font-semibold rounded-t-xl transition flex items-center gap-2 whitespace-nowrap ${
activeTab === 'one-off'
? 'bg-slate-800 text-amber-400 border-t-2 border-amber-500 shadow-xs'
: 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/50'
}`}
>
<Receipt className="w-4 h-4 text-amber-400" />
<span>One-Off Charges ({totalOneOffCount})</span>
</button>
<button
onClick={() => setActiveTab('members')}
className={`px-4 py-2.5 text-xs sm:text-sm font-semibold rounded-t-xl transition flex items-center gap-2 whitespace-nowrap ${
activeTab === 'members'
? 'bg-slate-800 text-indigo-400 border-t-2 border-indigo-500 shadow-xs'
: 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/50'
}`}
>
<Users className="w-4 h-4" />
<span>Members & Families</span>
</button>
<button
onClick={() => setActiveTab('settlements')}
className={`px-4 py-2.5 text-xs sm:text-sm font-semibold rounded-t-xl transition flex items-center gap-2 whitespace-nowrap ${
activeTab === 'settlements'
? 'bg-slate-800 text-indigo-400 border-t-2 border-indigo-500 shadow-xs'
: 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/50'
}`}
>
<RefreshCw className="w-4 h-4" />
<span>Settlement Log</span>
</button>
</div>
</div>
</header>
);
};