feat: finance page overhaul — pie charts, month nav, tab improvements
- Overview tab: 3 donut pie charts (expenses by category, sub payments, invoiced) each with independent month navigation arrows - Expenses tab: big red total in category sidebar, left-aligned category column, white text - Subcontractors tab: big gold total in sidebar, pending/paid breakdown with gold highlight - Invoices tab: big green total in companies sidebar, dashboard-inline-link for invoice# and company, StatusBadge with Invoiced/Paid labels, column widths tuned - StatusBadge: add optional label prop for custom display text - Layout/style polish across tabs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+4
-18
@@ -109,13 +109,6 @@ function TasksPageShell({ statsTasks = [], projects = [], onAddProject = null, c
|
||||
if (s === 'cancelled' || s === 'archived') return 0;
|
||||
return 35;
|
||||
};
|
||||
const tabBtnStyle = (active) => ({
|
||||
fontFamily: "Fourge, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
||||
fontSize: 13, fontWeight: 500, letterSpacing: 0.2, padding: '2px 0 5px', margin: '0 8px',
|
||||
borderRadius: 0, border: 'none', borderBottom: active ? '2px solid var(--accent)' : '2px solid transparent',
|
||||
cursor: 'pointer', background: 'transparent',
|
||||
color: active ? 'var(--text-primary)' : 'var(--text-secondary)', transition: 'all 160ms',
|
||||
});
|
||||
return (
|
||||
<div style={{ minWidth: 0, flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
|
||||
<TasksStatsRow tasks={statsTasks} />
|
||||
@@ -126,7 +119,7 @@ function TasksPageShell({ statsTasks = [], projects = [], onAddProject = null, c
|
||||
<div style={{ flex: '0 0 calc(30% - 24px)', minWidth: 0, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 10, flexShrink: 0 }}>
|
||||
{projectTabs.map(t => (
|
||||
<button key={t.id} onClick={() => setProjTab(t.id)} style={tabBtnStyle(projTab === t.id)}>{t.label}</button>
|
||||
<button key={t.id} onClick={() => setProjTab(t.id)} className={`section-tab-btn${projTab === t.id ? ' is-active' : ''}`}>{t.label}</button>
|
||||
))}
|
||||
{onAddProject && (
|
||||
<div style={{ marginLeft: 'auto' }}>
|
||||
@@ -521,13 +514,6 @@ export default function RequestsPage() {
|
||||
).values()];
|
||||
}, [isExternal, allRows, projects]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const tabBtnStyle = (active) => ({
|
||||
fontFamily: "Fourge, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
||||
fontSize: 13, fontWeight: 500, letterSpacing: 0.2, padding: '2px 0 5px', margin: '0 8px',
|
||||
borderRadius: 0, border: 'none', borderBottom: active ? '2px solid var(--accent)' : '2px solid transparent',
|
||||
cursor: 'pointer', background: 'transparent',
|
||||
color: active ? 'var(--text-primary)' : 'var(--text-secondary)', transition: 'all 160ms',
|
||||
});
|
||||
|
||||
const renderRow = (row) => {
|
||||
const project = projects.find(p => p.id === row.projectId);
|
||||
@@ -639,7 +625,7 @@ export default function RequestsPage() {
|
||||
{/* Controls bar: tabs left, filters + actions right */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 10, flexShrink: 0 }}>
|
||||
{tabs.map(t => (
|
||||
<button key={t.id} onClick={() => setActiveTab(t.id)} style={tabBtnStyle(activeTab === t.id)}>
|
||||
<button key={t.id} onClick={() => setActiveTab(t.id)} className={`section-tab-btn${activeTab === t.id ? ' is-active' : ''}`}>
|
||||
{t.label}
|
||||
</button>
|
||||
))}
|
||||
@@ -650,7 +636,7 @@ export default function RequestsPage() {
|
||||
className="btn btn-outline"
|
||||
aria-label="Filter projects" title="Filter projects"
|
||||
onClick={() => setProjectFilterMenuOpen(o => !o)}
|
||||
style={{ width: 30, minWidth: 30, padding: 0, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}
|
||||
style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}
|
||||
>
|
||||
<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M2 4h12M4 8h8M6 12h4" />
|
||||
@@ -672,7 +658,7 @@ export default function RequestsPage() {
|
||||
className="btn btn-outline"
|
||||
aria-label="Filter companies" title="Filter companies"
|
||||
onClick={() => setCompanyFilterMenuOpen(o => !o)}
|
||||
style={{ width: 30, minWidth: 30, padding: 0, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}
|
||||
style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}
|
||||
>
|
||||
<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M2 4h12M4 8h8M6 12h4" />
|
||||
|
||||
Reference in New Issue
Block a user