AV: precise recolor to spec — warm dark backgrounds (#1c1815/#231d18/#26201a/#15110e) + gold #F0A623 / orange #D85A30 accents + warm text (#FBEFE0/#C9BBA8/#8a7e6e). 138 component files + 36 token swaps.
This commit is contained in:
@@ -84,7 +84,7 @@ export default function ExpensesPage() {
|
||||
setForm({ vendor: '', amount: '', category: 'other', description: '', expense_date: new Date().toISOString().split('T')[0], receipt_source: 'manual' });
|
||||
}
|
||||
|
||||
if (loading) return <div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#ffb800] border-t-transparent rounded-full animate-spin" /></div>;
|
||||
if (loading) return <div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#F0A623] border-t-transparent rounded-full animate-spin" /></div>;
|
||||
if (!user) return null;
|
||||
|
||||
return (
|
||||
@@ -95,7 +95,7 @@ export default function ExpensesPage() {
|
||||
<h1 className="text-xl font-bold">Expenses</h1>
|
||||
<Link href="/admin/accounting" className="text-xs text-[#555] hover:text-[#888]">← Accounting</Link>
|
||||
</div>
|
||||
<button onClick={() => setShowForm(true)} className="px-3 py-1.5 bg-[#ffb800] rounded text-xs font-medium hover:bg-blue-500">+ Log Expense</button>
|
||||
<button onClick={() => setShowForm(true)} className="px-3 py-1.5 bg-[#F0A623] rounded text-xs font-medium hover:bg-blue-500">+ Log Expense</button>
|
||||
</div>
|
||||
|
||||
{/* Success Toast */}
|
||||
@@ -107,11 +107,11 @@ export default function ExpensesPage() {
|
||||
)}
|
||||
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<select value={filterCat} onChange={e => setFilterCat(e.target.value)} className="px-2 py-1 bg-[#111] border border-[#252525] rounded text-xs text-[#888] focus:outline-none">
|
||||
<select value={filterCat} onChange={e => setFilterCat(e.target.value)} className="px-2 py-1 bg-[#111] border border-[#3a322b] rounded text-xs text-[#888] focus:outline-none">
|
||||
<option value="">All Categories</option>
|
||||
{CATEGORIES.map(c => <option key={c} value={c}>{c.replace(/_/g, ' ')}</option>)}
|
||||
</select>
|
||||
<select value={filterReconciled} onChange={e => setFilterReconciled(e.target.value)} className="px-2 py-1 bg-[#111] border border-[#252525] rounded text-xs text-[#888] focus:outline-none">
|
||||
<select value={filterReconciled} onChange={e => setFilterReconciled(e.target.value)} className="px-2 py-1 bg-[#111] border border-[#3a322b] rounded text-xs text-[#888] focus:outline-none">
|
||||
<option value="">All</option>
|
||||
<option value="true">Reconciled</option>
|
||||
<option value="false">Unreconciled</option>
|
||||
@@ -119,7 +119,7 @@ export default function ExpensesPage() {
|
||||
</div>
|
||||
|
||||
{showForm && (
|
||||
<form onSubmit={handleCreate} noValidate className="bg-[#111] border border-[#252525] rounded-lg p-4 space-y-3">
|
||||
<form onSubmit={handleCreate} noValidate className="bg-[#111] border border-[#3a322b] rounded-lg p-4 space-y-3">
|
||||
<h3 className="text-sm font-semibold">Log Expense</h3>
|
||||
|
||||
{errors._form && (
|
||||
@@ -132,40 +132,40 @@ export default function ExpensesPage() {
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-3">
|
||||
<div>
|
||||
<label className="text-xs text-[#888] block mb-1">Vendor</label>
|
||||
<input type="text" value={form.vendor} onChange={e => handleChange('vendor', e.target.value)} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#252525] rounded text-xs text-white focus:outline-none focus:border-[#ffb800]" />
|
||||
<input type="text" value={form.vendor} onChange={e => handleChange('vendor', e.target.value)} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none focus:border-[#F0A623]" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-[#888] block mb-1">Amount ($) <span className="text-red-400">*</span></label>
|
||||
<input type="number" step="0.01" value={form.amount} onChange={e => handleChange('amount', e.target.value)} className={`w-full px-2 py-1.5 bg-[#0a0a0a] border rounded text-xs text-white focus:outline-none focus:border-[#ffb800] ${errors.amount ? 'border-red-500/60' : 'border-[#252525]'}`} />
|
||||
<input type="number" step="0.01" value={form.amount} onChange={e => handleChange('amount', e.target.value)} className={`w-full px-2 py-1.5 bg-[#0a0a0a] border rounded text-xs text-white focus:outline-none focus:border-[#F0A623] ${errors.amount ? 'border-red-500/60' : 'border-[#3a322b]'}`} />
|
||||
{errors.amount && <p className="mt-1 text-xs text-red-400">{errors.amount}</p>}
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-[#888] block mb-1">Date <span className="text-red-400">*</span></label>
|
||||
<input type="date" value={form.expense_date} onChange={e => handleChange('expense_date', e.target.value)} className={`w-full px-2 py-1.5 bg-[#0a0a0a] border rounded text-xs text-white focus:outline-none focus:border-[#ffb800] ${errors.expense_date ? 'border-red-500/60' : 'border-[#252525]'}`} />
|
||||
<input type="date" value={form.expense_date} onChange={e => handleChange('expense_date', e.target.value)} className={`w-full px-2 py-1.5 bg-[#0a0a0a] border rounded text-xs text-white focus:outline-none focus:border-[#F0A623] ${errors.expense_date ? 'border-red-500/60' : 'border-[#3a322b]'}`} />
|
||||
{errors.expense_date && <p className="mt-1 text-xs text-red-400">{errors.expense_date}</p>}
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-[#888] block mb-1">Category</label>
|
||||
<select value={form.category} onChange={e => handleChange('category', e.target.value)} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#252525] rounded text-xs text-white focus:outline-none">
|
||||
<select value={form.category} onChange={e => handleChange('category', e.target.value)} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none">
|
||||
{CATEGORIES.map(c => <option key={c} value={c}>{c.replace(/_/g, ' ')}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<label className="text-xs text-[#888] block mb-1">Description</label>
|
||||
<input value={form.description} onChange={e => handleChange('description', e.target.value)} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#252525] rounded text-xs text-white focus:outline-none focus:border-[#ffb800]" />
|
||||
<input value={form.description} onChange={e => handleChange('description', e.target.value)} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none focus:border-[#F0A623]" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button type="submit" disabled={saving} className="px-3 py-1.5 bg-[#ffb800] rounded text-xs font-medium hover:bg-blue-500 disabled:opacity-50">{saving ? 'Saving…' : 'Log Expense'}</button>
|
||||
<button type="button" onClick={handleCancel} className="px-3 py-1.5 bg-[#1a1a1a] border border-[#252525] rounded text-xs text-[#888] hover:text-white">Cancel</button>
|
||||
<button type="submit" disabled={saving} className="px-3 py-1.5 bg-[#F0A623] rounded text-xs font-medium hover:bg-blue-500 disabled:opacity-50">{saving ? 'Saving…' : 'Log Expense'}</button>
|
||||
<button type="button" onClick={handleCancel} className="px-3 py-1.5 bg-[#231d18] border border-[#3a322b] rounded text-xs text-[#888] hover:text-white">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg overflow-x-auto">
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-[#1a1a1a]">
|
||||
<tr className="border-b border-[#231d18]">
|
||||
{['Date','Vendor','Amount','Category','Source','Reconciled','Description'].map(h => (
|
||||
<th key={h} className="px-3 py-2 text-left text-xs text-[#555] font-medium">{h}</th>
|
||||
))}
|
||||
@@ -177,7 +177,7 @@ export default function ExpensesPage() {
|
||||
) : expenses.length === 0 ? (
|
||||
<tr><td colSpan={7} className="px-4 py-8 text-center text-[#555] text-xs">No expenses found</td></tr>
|
||||
) : expenses.map((ex: any) => (
|
||||
<tr key={ex.id} className="border-b border-[#1a1a1a] hover:bg-[#161616]">
|
||||
<tr key={ex.id} className="border-b border-[#231d18] hover:bg-[#231d18]">
|
||||
<td className="px-3 py-2 text-[#888] text-xs">{ex.expense_date}</td>
|
||||
<td className="px-3 py-2 text-white text-xs">{ex.vendor ?? '—'}</td>
|
||||
<td className="px-3 py-2 text-red-400 text-xs">{ex.amount_cents ? fmt(ex.amount_cents) : '—'}</td>
|
||||
|
||||
Reference in New Issue
Block a user