198 lines
9.5 KiB
TypeScript
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>
|
|
);
|
|
};
|
|
|