2026-05-28 22:06:15 -05:00
|
|
|
import React, { useState, useEffect, useCallback } from 'react';
|
2026-05-03 19:51:57 -05:00
|
|
|
import { api } from '@/api';
|
2026-05-28 22:06:15 -05:00
|
|
|
import BankSyncSection from '@/components/data/BankSyncSection';
|
refactor: component splits, PWA support, CommandPalette
Component Splits:
- AdminPage.jsx: 1,906 -> 82 lines (logic moved to client/components/admin/ — 9 files)
- DataPage.jsx: 3,132 -> 60 lines (logic moved to client/components/data/ — 8 files)
- TrackerPage.jsx: 2,566 -> 2,132 lines (MonthlyStateDialog, StartingAmountsEditDialog, PaymentModal)
PWA:
- vite-plugin-pwa installed with NetworkFirst caching for API routes
- Square PWA icons (192x192, 512x512, apple-touch-icon)
- theme-color, apple meta tags, touch icon in index.html
- Build generates dist/sw.js + Workbox runtime
CommandPalette:
- Navigation commands, Add bill action, month jumps
- Grouped results with empty/filtered states
2026-05-28 20:53:22 -05:00
|
|
|
import ImportTransactionCsvSection from '@/components/data/ImportTransactionCsvSection';
|
|
|
|
|
import TransactionMatchingSection from '@/components/data/TransactionMatchingSection';
|
|
|
|
|
import ImportSpreadsheetSection from '@/components/data/ImportSpreadsheetSection';
|
|
|
|
|
import ImportMyDataSection from '@/components/data/ImportMyDataSection';
|
|
|
|
|
import SeedDemoDataSection from '@/components/data/SeedDemoDataSection';
|
|
|
|
|
import DownloadMyDataSection from '@/components/data/DownloadMyDataSection';
|
|
|
|
|
import ImportHistorySection from '@/components/data/ImportHistorySection';
|
2026-05-09 13:03:36 -05:00
|
|
|
|
2026-05-03 19:51:57 -05:00
|
|
|
export default function DataPage() {
|
2026-05-28 22:06:15 -05:00
|
|
|
const [history, setHistory] = useState(null);
|
2026-05-04 23:34:24 -05:00
|
|
|
const [historyLoading, setHistoryLoading] = useState(true);
|
2026-05-16 21:36:04 -05:00
|
|
|
const [transactionRefreshKey, setTransactionRefreshKey] = useState(0);
|
2026-05-28 22:06:15 -05:00
|
|
|
const [simplefinConn, setSimplefinConn] = useState(null);
|
2026-05-04 23:34:24 -05:00
|
|
|
|
|
|
|
|
const loadHistory = async () => {
|
|
|
|
|
setHistoryLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
const { history } = await api.importHistory();
|
|
|
|
|
setHistory(history);
|
|
|
|
|
} catch {
|
|
|
|
|
setHistory([]);
|
|
|
|
|
} finally {
|
|
|
|
|
setHistoryLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => { loadHistory(); }, []);
|
|
|
|
|
|
2026-05-16 21:36:04 -05:00
|
|
|
const handleTransactionImportComplete = () => {
|
|
|
|
|
loadHistory();
|
|
|
|
|
setTransactionRefreshKey(key => key + 1);
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-28 22:06:15 -05:00
|
|
|
// Called by BankSyncSection when connection state changes (connect/sync/disconnect)
|
|
|
|
|
const handleConnectionChange = useCallback((conn) => {
|
|
|
|
|
setSimplefinConn(conn || null);
|
|
|
|
|
setTransactionRefreshKey(key => key + 1);
|
|
|
|
|
}, []);
|
|
|
|
|
|
2026-05-04 23:34:24 -05:00
|
|
|
return (
|
|
|
|
|
<div className="mx-auto w-full max-w-6xl space-y-5">
|
|
|
|
|
<div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
|
|
|
|
|
<div>
|
|
|
|
|
<h1 className="text-2xl font-bold tracking-tight">Data</h1>
|
|
|
|
|
<p className="text-sm text-muted-foreground mt-0.5">
|
|
|
|
|
Import, export, and review your user-owned bill tracker records.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="rounded-full border border-border/70 bg-card/80 px-3 py-1.5 text-xs font-medium text-muted-foreground">
|
|
|
|
|
User data only
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-15 01:36:56 -05:00
|
|
|
<div className="space-y-5">
|
2026-05-28 22:06:15 -05:00
|
|
|
<BankSyncSection onConnectionChange={handleConnectionChange} />
|
2026-05-16 21:36:04 -05:00
|
|
|
<ImportTransactionCsvSection onHistoryRefresh={handleTransactionImportComplete} />
|
2026-05-28 22:06:15 -05:00
|
|
|
<TransactionMatchingSection refreshKey={transactionRefreshKey} simplefinConn={simplefinConn} />
|
2026-05-04 23:34:24 -05:00
|
|
|
<ImportSpreadsheetSection onHistoryRefresh={loadHistory} />
|
|
|
|
|
<ImportMyDataSection onHistoryRefresh={loadHistory} />
|
|
|
|
|
</div>
|
2026-05-09 13:03:36 -05:00
|
|
|
<SeedDemoDataSection onSeeded={loadHistory} />
|
2026-05-04 23:34:24 -05:00
|
|
|
<DownloadMyDataSection />
|
|
|
|
|
<ImportHistorySection history={history} loading={historyLoading} onRefresh={loadHistory} />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2026-05-03 19:51:57 -05:00
|
|
|
}
|