EmberClone/apps/web/src/App.tsx

323 lines
7.8 KiB
TypeScript

import { createRootRoute, createRoute, createRouter, RouterProvider, Outlet, redirect, useLocation } from "@tanstack/react-router"
import Dashboard from "./pages/Dashboard"
import Login from "./pages/Login"
import ForgotPassword from "./pages/ForgotPassword"
import ResetPassword from "./pages/ResetPassword"
import TimeEntries from "./pages/TimeEntries"
import Customers from "./pages/Customers"
import CustomerDetail from "./pages/CustomerDetail"
import Projects from "./pages/Projects"
import ProjectDetail from "./pages/ProjectDetail"
import Profile from "./pages/Profile"
import AdminUsers from "./pages/AdminUsers"
import Settings from "./pages/Settings"
import Calendar from "./pages/Calendar"
import AuditLog from "./pages/AuditLog"
import Documents from "./pages/Documents"
import Webhooks from "./pages/Webhooks"
import TwoFactorAuth from "./pages/TwoFactorAuth"
import Billing from "./pages/Billing"
import Integrations from "./pages/Integrations"
import ProjectTemplates from "./pages/ProjectTemplates"
import TimeEntryTemplates from "./pages/TimeEntryTemplates"
import Invoices from "./pages/Invoices"
import ApiKeys from "./pages/ApiKeys"
import AcceptInvite from "./pages/AcceptInvite"
import Holidays from "./pages/Holidays"
import RolePermissions from "./pages/RolePermissions"
import NotFound from "./pages/NotFound"
import Nav from "./components/Nav"
import CommandPalette from "./components/CommandPalette"
import KeyboardHelp from "./components/KeyboardHelp"
import OnboardingTour from "./components/OnboardingTour"
import VersionBadge from "./components/VersionBadge"
import QuickAdd from "./components/QuickAdd"
import IdleDetector from "./components/IdleDetector"
import UndoStack from "./components/UndoStack"
import ApiErrorBanner from "./components/ApiErrorBanner"
import { ToastProvider } from "./components/Toast"
import ErrorBoundary from "./components/ErrorBoundary"
import { api } from "./lib/api"
const rootRoute = createRootRoute({
component: () => {
const location = useLocation()
return (
<ToastProvider>
<div className="min-h-screen flex flex-col bg-slate-50">
<div className="flex-grow">
<IdleDetector />
<Nav />
<ApiErrorBanner />
<CommandPalette />
<KeyboardHelp />
<OnboardingTour />
<QuickAdd />
<UndoStack />
<div className="page-enter" key={location.pathname}>
<Outlet />
</div>
</div>
<footer className="border-t bg-white py-2 text-center">
<VersionBadge />
</footer>
</div>
</ToastProvider>
)
}
})
const loginRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/login",
component: Login
})
const forgotPasswordRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/forgot-password",
component: ForgotPassword
})
const resetPasswordRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/reset-password",
component: ResetPassword
})
const acceptInviteRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/accept-invite",
component: AcceptInvite
})
const authCheck = async () => {
try {
await api.getMe()
} catch (error: any) {
if (error.status === 401) {
throw redirect({ to: "/login" })
}
}
}
const adminCheck = async () => {
try {
const user = await api.getMe()
if (user.role !== "admin") {
throw redirect({ to: "/" })
}
} catch (error: any) {
if (error.status === 401) {
throw redirect({ to: "/login" })
} else if (error.status === 302 || error.status === 403) {
throw error
}
throw redirect({ to: "/" })
}
}
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/",
beforeLoad: authCheck,
component: Dashboard
})
const timeEntriesRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/time-entries",
beforeLoad: authCheck,
component: TimeEntries
})
const timeEntryTemplatesRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/time-entry-templates",
beforeLoad: authCheck,
component: TimeEntryTemplates
})
const customersRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/customers",
beforeLoad: authCheck,
component: Customers
})
const customerDetailRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/customers/$customerId",
beforeLoad: authCheck,
component: CustomerDetail
})
const projectsRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/projects",
beforeLoad: authCheck,
component: Projects
})
const projectDetailRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/projects/$projectId",
beforeLoad: authCheck,
component: ProjectDetail
})
const projectTemplatesRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/project-templates",
beforeLoad: authCheck,
component: ProjectTemplates
})
const profileRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/profile",
beforeLoad: authCheck,
component: Profile
})
const settingsRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/settings",
beforeLoad: authCheck,
component: Settings
})
const twoFactorRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/settings/2fa",
beforeLoad: authCheck,
component: TwoFactorAuth
})
const apiKeysRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/settings/api-keys",
beforeLoad: authCheck,
component: ApiKeys
})
const calendarRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/calendar",
beforeLoad: authCheck,
component: Calendar
})
const holidaysRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/holidays",
beforeLoad: authCheck,
component: Holidays
})
const invoicesRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/invoices",
beforeLoad: authCheck,
component: Invoices
})
const billingRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/billing",
beforeLoad: authCheck,
component: Billing
})
const integrationsRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/integrations",
beforeLoad: authCheck,
component: Integrations
})
const documentsRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/documents",
beforeLoad: authCheck,
component: Documents
})
const webhooksRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/webhooks",
beforeLoad: authCheck,
component: Webhooks
})
const adminUsersRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/admin/users",
beforeLoad: adminCheck,
component: AdminUsers
})
const rolePermissionsRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/admin/permissions",
beforeLoad: adminCheck,
component: RolePermissions
})
const auditLogRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/admin/audit-log",
beforeLoad: adminCheck,
component: AuditLog
})
const notFoundRoute = createRoute({
getParentRoute: () => rootRoute,
path: "*",
component: NotFound
})
const routeTree = [
indexRoute,
loginRoute,
forgotPasswordRoute,
resetPasswordRoute,
acceptInviteRoute,
timeEntriesRoute,
timeEntryTemplatesRoute,
customersRoute,
customerDetailRoute,
projectsRoute,
projectDetailRoute,
projectTemplatesRoute,
profileRoute,
settingsRoute,
twoFactorRoute,
apiKeysRoute,
calendarRoute,
holidaysRoute,
invoicesRoute,
billingRoute,
integrationsRoute,
documentsRoute,
webhooksRoute,
adminUsersRoute,
rolePermissionsRoute,
auditLogRoute,
notFoundRoute
]
const router = createRouter({
routeTree,
defaultPreload: 'intent'
})
declare module "@tanstack/react-router" {
interface Register {
router: typeof router
}
}
export default function App() {
return <RouterProvider router={router} />
}