Files
pulse-web/src/App.jsx
Cosmo 8baddf1914
Some checks failed
CI / ci (push) Has been cancelled
feat: unified navigation hub + categories tab + mobile scroll fix
- Navigation: 4 items (Home, Tracker, Finance, Settings)
- Tracker page: tabs for Habits, Tasks, Stats
- Finance: added Categories tab (CRUD)
- AddTransactionModal: fixed mobile scroll with sticky button
- Home: added finance balance widget
- Legacy routes (/habits, /tasks, /stats) redirect to /tracker
2026-03-01 04:34:59 +00:00

158 lines
3.6 KiB
JavaScript

import { useEffect } from "react"
import { Routes, Route, Navigate } from "react-router-dom"
import { useAuthStore } from "./store/auth"
import Login from "./pages/Login"
import Register from "./pages/Register"
import Home from "./pages/Home"
import Habits from "./pages/Habits"
import Tasks from "./pages/Tasks"
import Savings from "./pages/Savings"
import VerifyEmail from "./pages/VerifyEmail"
import ResetPassword from "./pages/ResetPassword"
import ForgotPassword from "./pages/ForgotPassword"
import Stats from "./pages/Stats"
import Settings from "./pages/Settings"
import Finance from "./pages/Finance"
import Tracker from "./pages/Tracker"
function ProtectedRoute({ children }) {
const { isAuthenticated, isLoading } = useAuthStore()
if (isLoading) {
return (
<div className="min-h-screen flex items-center justify-center bg-surface-50">
<div className="w-10 h-10 border-4 border-primary-500 border-t-transparent rounded-full animate-spin" />
</div>
)
}
if (!isAuthenticated) {
return <Navigate to="/login" replace />
}
return children
}
function PublicRoute({ children }) {
const { isAuthenticated, isLoading } = useAuthStore()
if (isLoading) {
return (
<div className="min-h-screen flex items-center justify-center bg-surface-50">
<div className="w-10 h-10 border-4 border-primary-500 border-t-transparent rounded-full animate-spin" />
</div>
)
}
if (isAuthenticated) {
return <Navigate to="/" replace />
}
return children
}
export default function App() {
const initialize = useAuthStore((s) => s.initialize)
useEffect(() => {
initialize()
}, [initialize])
return (
<Routes>
<Route
path="/login"
element={
<PublicRoute>
<Login />
</PublicRoute>
}
/>
<Route
path="/register"
element={
<PublicRoute>
<Register />
</PublicRoute>
}
/>
<Route
path="/forgot-password"
element={
<PublicRoute>
<ForgotPassword />
</PublicRoute>
}
/>
<Route path="/verify-email" element={<VerifyEmail />} />
<Route path="/reset-password" element={<ResetPassword />} />
<Route
path="/"
element={
<ProtectedRoute>
<Home />
</ProtectedRoute>
}
/>
<Route
path="/tracker"
element={
<ProtectedRoute>
<Tracker />
</ProtectedRoute>
}
/>
{/* Legacy routes redirect to tracker */}
<Route
path="/habits"
element={
<ProtectedRoute>
<Navigate to="/tracker" replace />
</ProtectedRoute>
}
/>
<Route
path="/tasks"
element={
<ProtectedRoute>
<Navigate to="/tracker" replace />
</ProtectedRoute>
}
/>
<Route
path="/stats"
element={
<ProtectedRoute>
<Navigate to="/tracker" replace />
</ProtectedRoute>
}
/>
<Route
path="/savings"
element={
<ProtectedRoute>
<Savings />
</ProtectedRoute>
}
/>
<Route
path="/finance"
element={
<ProtectedRoute>
<Finance />
</ProtectedRoute>
}
/>
<Route
path="/settings"
element={
<ProtectedRoute>
<Settings />
</ProtectedRoute>
}
/>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
)
}