MyMidas/frontend/src/App.tsx
megaproxy 61a7884ee5 Initial commit: MyMidas personal finance tracker
Full-stack self-hosted finance app with FastAPI backend and React frontend.

Features:
- Accounts, transactions, budgets, investments with GBP base currency
- CSV import with auto-detection for 10 UK bank formats
- ML predictions: spending forecast, net worth projection, Monte Carlo
- 7 selectable themes (Obsidian, Arctic, Midnight, Vault, Terminal, Synthwave, Ledger)
- Receipt/document attachments on transactions (JPEG, PNG, WebP, PDF)
- AES-256-GCM field encryption, RS256 JWT, TOTP 2FA, RLS, audit log
- Encrypted nightly backups + key rotation script
- Mobile-responsive layout with bottom nav

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:56:10 +00:00

67 lines
2.9 KiB
TypeScript

import { useEffect } from "react";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import { useAuthStore } from "@/store/authStore";
import { useUiStore } from "@/store/uiStore";
import AppShell from "@/components/layout/AppShell";
import LoginPage from "@/pages/auth/Login";
import TwoFactorSetupPage from "@/pages/auth/TwoFactorSetup";
import Dashboard from "@/pages/dashboard/Dashboard";
import AccountList from "@/pages/accounts/AccountList";
import AccountDetail from "@/pages/accounts/AccountDetail";
import TransactionList from "@/pages/transactions/TransactionList";
import TransactionImport from "@/pages/transactions/TransactionImport";
import BudgetPage from "@/pages/budgets/BudgetPage";
import ReportsPage from "@/pages/reports/ReportsPage";
import PortfolioPage from "@/pages/investments/PortfolioPage";
import AssetDetail from "@/pages/investments/AssetDetail";
import PredictionsPage from "@/pages/predictions/PredictionsPage";
import SettingsPage from "@/pages/settings/SettingsPage";
function PrivateRoute({ children }: { children: React.ReactNode }) {
const token = useAuthStore((s) => s.token);
return token ? <>{children}</> : <Navigate to="/login" replace />;
}
export default function App() {
const theme = useUiStore((s) => s.theme);
// Apply theme class to <html> so CSS variables cascade to body and all children
useEffect(() => {
const html = document.documentElement;
html.classList.forEach(c => { if (c.startsWith("theme-")) html.classList.remove(c); });
html.classList.add(`theme-${theme}`);
}, [theme]);
return (
<div className="min-h-screen bg-background text-foreground">
<BrowserRouter>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route
path="/*"
element={
<PrivateRoute>
<AppShell>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/security/totp" element={<TwoFactorSetupPage />} />
<Route path="/accounts" element={<AccountList />} />
<Route path="/accounts/:accountId" element={<AccountDetail />} />
<Route path="/transactions" element={<TransactionList />} />
<Route path="/transactions/import" element={<TransactionImport />} />
<Route path="/budgets" element={<BudgetPage />} />
<Route path="/reports" element={<ReportsPage />} />
<Route path="/investments" element={<PortfolioPage />} />
<Route path="/investments/:assetId" element={<AssetDetail />} />
<Route path="/predictions" element={<PredictionsPage />} />
<Route path="/settings" element={<SettingsPage />} />
</Routes>
</AppShell>
</PrivateRoute>
}
/>
</Routes>
</BrowserRouter>
</div>
);
}