diff --git a/src/evently.client/src/lib/services/auth-service.ts b/src/evently.client/src/lib/services/auth-service.ts index e50276b..64514ec 100644 --- a/src/evently.client/src/lib/services/auth-service.ts +++ b/src/evently.client/src/lib/services/auth-service.ts @@ -1,3 +1,4 @@ +import { redirect } from "@tanstack/react-router"; import axios from "axios"; import { Account } from "~/lib/domains/entities"; @@ -23,3 +24,22 @@ export async function getAccount(): Promise { } return null; } + +/** + * Validate against the user's `Account` in the route context. + * Redirect to login page if authentication fails. + * Tightly coupled with TanStack framework + * @param account + * @param currentHref + */ +export async function guardRoute(account: Account | null, currentHref: string): Promise { + if (account == null) { + throw redirect({ + to: "/login", + replace: true, + search: { + redirect: currentHref + } + }); + } +} diff --git a/src/evently.client/src/routeTree.gen.ts b/src/evently.client/src/routeTree.gen.ts index c3c8e8c..c81683f 100644 --- a/src/evently.client/src/routeTree.gen.ts +++ b/src/evently.client/src/routeTree.gen.ts @@ -9,20 +9,24 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' +import { Route as AuthRouteImport } from './routes/_auth' import { Route as IndexRouteImport } from './routes/index' import { Route as LoginIndexRouteImport } from './routes/login/index' import { Route as HealthcheckIndexRouteImport } from './routes/healthcheck/index' import { Route as GatheringsIndexRouteImport } from './routes/gatherings/index' -import { Route as authGatheringsRouteRouteImport } from './routes/(auth)/gatherings/route' -import { Route as authBookingsRouteRouteImport } from './routes/(auth)/bookings/route' +import { Route as BookingsauthRouteRouteImport } from './routes/bookings/(auth)/route' import { Route as GatheringsGatheringIdIndexRouteImport } from './routes/gatherings/$gatheringId/index' -import { Route as authGatheringsCreateRouteImport } from './routes/(auth)/gatherings/create' -import { Route as authBookingsHostingIndexRouteImport } from './routes/(auth)/bookings/hosting/index' -import { Route as authBookingsAttendingIndexRouteImport } from './routes/(auth)/bookings/attending/index' -import { Route as authGatheringsGatheringIdUpdateRouteImport } from './routes/(auth)/gatherings/$gatheringId/update' -import { Route as authBookingsHostingGatheringIdDashboardIndexRouteImport } from './routes/(auth)/bookings/hosting/$gatheringId/dashboard.index' -import { Route as authBookingsHostingGatheringIdDashboardScanRouteImport } from './routes/(auth)/bookings/hosting/$gatheringId/dashboard.scan' +import { Route as GatheringsauthCreateRouteImport } from './routes/gatherings/(auth).create' +import { Route as BookingsauthHostingIndexRouteImport } from './routes/bookings/(auth)/hosting/index' +import { Route as BookingsauthAttendingIndexRouteImport } from './routes/bookings/(auth)/attending/index' +import { Route as GatheringsGatheringIdauthUpdateRouteImport } from './routes/gatherings/$gatheringId/(auth).update' +import { Route as BookingsauthHostingGatheringIdDashboardIndexRouteImport } from './routes/bookings/(auth)/hosting/$gatheringId/dashboard.index' +import { Route as BookingsauthHostingGatheringIdDashboardScanRouteImport } from './routes/bookings/(auth)/hosting/$gatheringId/dashboard.scan' +const AuthRoute = AuthRouteImport.update({ + id: '/_auth', + getParentRoute: () => rootRouteImport, +} as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', @@ -43,14 +47,9 @@ const GatheringsIndexRoute = GatheringsIndexRouteImport.update({ path: '/gatherings/', getParentRoute: () => rootRouteImport, } as any) -const authGatheringsRouteRoute = authGatheringsRouteRouteImport.update({ - id: '/(auth)/gatherings', - path: '/gatherings', - getParentRoute: () => rootRouteImport, -} as any) -const authBookingsRouteRoute = authBookingsRouteRouteImport.update({ - id: '/(auth)/bookings', - path: '/bookings', +const BookingsauthRouteRoute = BookingsauthRouteRouteImport.update({ + id: '/bookings/(auth)', + path: '/bookings/', getParentRoute: () => rootRouteImport, } as any) const GatheringsGatheringIdIndexRoute = @@ -59,85 +58,85 @@ const GatheringsGatheringIdIndexRoute = path: '/gatherings/$gatheringId/', getParentRoute: () => rootRouteImport, } as any) -const authGatheringsCreateRoute = authGatheringsCreateRouteImport.update({ - id: '/create', - path: '/create', - getParentRoute: () => authGatheringsRouteRoute, +const GatheringsauthCreateRoute = GatheringsauthCreateRouteImport.update({ + id: '/gatherings/(auth)/create', + path: '/gatherings/create', + getParentRoute: () => rootRouteImport, } as any) -const authBookingsHostingIndexRoute = - authBookingsHostingIndexRouteImport.update({ +const BookingsauthHostingIndexRoute = + BookingsauthHostingIndexRouteImport.update({ id: '/hosting/', path: '/hosting/', - getParentRoute: () => authBookingsRouteRoute, + getParentRoute: () => BookingsauthRouteRoute, } as any) -const authBookingsAttendingIndexRoute = - authBookingsAttendingIndexRouteImport.update({ +const BookingsauthAttendingIndexRoute = + BookingsauthAttendingIndexRouteImport.update({ id: '/attending/', path: '/attending/', - getParentRoute: () => authBookingsRouteRoute, + getParentRoute: () => BookingsauthRouteRoute, } as any) -const authGatheringsGatheringIdUpdateRoute = - authGatheringsGatheringIdUpdateRouteImport.update({ - id: '/$gatheringId/update', - path: '/$gatheringId/update', - getParentRoute: () => authGatheringsRouteRoute, +const GatheringsGatheringIdauthUpdateRoute = + GatheringsGatheringIdauthUpdateRouteImport.update({ + id: '/gatherings/$gatheringId/(auth)/update', + path: '/gatherings/$gatheringId/update', + getParentRoute: () => rootRouteImport, } as any) -const authBookingsHostingGatheringIdDashboardIndexRoute = - authBookingsHostingGatheringIdDashboardIndexRouteImport.update({ +const BookingsauthHostingGatheringIdDashboardIndexRoute = + BookingsauthHostingGatheringIdDashboardIndexRouteImport.update({ id: '/hosting/$gatheringId/dashboard/', path: '/hosting/$gatheringId/dashboard/', - getParentRoute: () => authBookingsRouteRoute, + getParentRoute: () => BookingsauthRouteRoute, } as any) -const authBookingsHostingGatheringIdDashboardScanRoute = - authBookingsHostingGatheringIdDashboardScanRouteImport.update({ +const BookingsauthHostingGatheringIdDashboardScanRoute = + BookingsauthHostingGatheringIdDashboardScanRouteImport.update({ id: '/hosting/$gatheringId/dashboard/scan', path: '/hosting/$gatheringId/dashboard/scan', - getParentRoute: () => authBookingsRouteRoute, + getParentRoute: () => BookingsauthRouteRoute, } as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute - '/bookings': typeof authBookingsRouteRouteWithChildren + '/bookings': typeof BookingsauthRouteRouteWithChildren '/gatherings': typeof GatheringsIndexRoute '/healthcheck': typeof HealthcheckIndexRoute '/login': typeof LoginIndexRoute - '/gatherings/create': typeof authGatheringsCreateRoute + '/gatherings/create': typeof GatheringsauthCreateRoute '/gatherings/$gatheringId': typeof GatheringsGatheringIdIndexRoute - '/gatherings/$gatheringId/update': typeof authGatheringsGatheringIdUpdateRoute - '/bookings/attending': typeof authBookingsAttendingIndexRoute - '/bookings/hosting': typeof authBookingsHostingIndexRoute - '/bookings/hosting/$gatheringId/dashboard/scan': typeof authBookingsHostingGatheringIdDashboardScanRoute - '/bookings/hosting/$gatheringId/dashboard': typeof authBookingsHostingGatheringIdDashboardIndexRoute + '/gatherings/$gatheringId/update': typeof GatheringsGatheringIdauthUpdateRoute + '/bookings/attending': typeof BookingsauthAttendingIndexRoute + '/bookings/hosting': typeof BookingsauthHostingIndexRoute + '/bookings/hosting/$gatheringId/dashboard/scan': typeof BookingsauthHostingGatheringIdDashboardScanRoute + '/bookings/hosting/$gatheringId/dashboard': typeof BookingsauthHostingGatheringIdDashboardIndexRoute } export interface FileRoutesByTo { '/': typeof IndexRoute - '/bookings': typeof authBookingsRouteRouteWithChildren + '/bookings': typeof BookingsauthRouteRouteWithChildren '/gatherings': typeof GatheringsIndexRoute '/healthcheck': typeof HealthcheckIndexRoute '/login': typeof LoginIndexRoute - '/gatherings/create': typeof authGatheringsCreateRoute + '/gatherings/create': typeof GatheringsauthCreateRoute '/gatherings/$gatheringId': typeof GatheringsGatheringIdIndexRoute - '/gatherings/$gatheringId/update': typeof authGatheringsGatheringIdUpdateRoute - '/bookings/attending': typeof authBookingsAttendingIndexRoute - '/bookings/hosting': typeof authBookingsHostingIndexRoute - '/bookings/hosting/$gatheringId/dashboard/scan': typeof authBookingsHostingGatheringIdDashboardScanRoute - '/bookings/hosting/$gatheringId/dashboard': typeof authBookingsHostingGatheringIdDashboardIndexRoute + '/gatherings/$gatheringId/update': typeof GatheringsGatheringIdauthUpdateRoute + '/bookings/attending': typeof BookingsauthAttendingIndexRoute + '/bookings/hosting': typeof BookingsauthHostingIndexRoute + '/bookings/hosting/$gatheringId/dashboard/scan': typeof BookingsauthHostingGatheringIdDashboardScanRoute + '/bookings/hosting/$gatheringId/dashboard': typeof BookingsauthHostingGatheringIdDashboardIndexRoute } export interface FileRoutesById { __root__: typeof rootRouteImport '/': typeof IndexRoute - '/(auth)/bookings': typeof authBookingsRouteRouteWithChildren - '/(auth)/gatherings': typeof authGatheringsRouteRouteWithChildren + '/_auth': typeof AuthRoute + '/bookings/(auth)': typeof BookingsauthRouteRouteWithChildren '/gatherings/': typeof GatheringsIndexRoute '/healthcheck/': typeof HealthcheckIndexRoute '/login/': typeof LoginIndexRoute - '/(auth)/gatherings/create': typeof authGatheringsCreateRoute + '/gatherings/(auth)/create': typeof GatheringsauthCreateRoute '/gatherings/$gatheringId/': typeof GatheringsGatheringIdIndexRoute - '/(auth)/gatherings/$gatheringId/update': typeof authGatheringsGatheringIdUpdateRoute - '/(auth)/bookings/attending/': typeof authBookingsAttendingIndexRoute - '/(auth)/bookings/hosting/': typeof authBookingsHostingIndexRoute - '/(auth)/bookings/hosting/$gatheringId/dashboard/scan': typeof authBookingsHostingGatheringIdDashboardScanRoute - '/(auth)/bookings/hosting/$gatheringId/dashboard/': typeof authBookingsHostingGatheringIdDashboardIndexRoute + '/gatherings/$gatheringId/(auth)/update': typeof GatheringsGatheringIdauthUpdateRoute + '/bookings/(auth)/attending/': typeof BookingsauthAttendingIndexRoute + '/bookings/(auth)/hosting/': typeof BookingsauthHostingIndexRoute + '/bookings/(auth)/hosting/$gatheringId/dashboard/scan': typeof BookingsauthHostingGatheringIdDashboardScanRoute + '/bookings/(auth)/hosting/$gatheringId/dashboard/': typeof BookingsauthHostingGatheringIdDashboardIndexRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath @@ -171,32 +170,41 @@ export interface FileRouteTypes { id: | '__root__' | '/' - | '/(auth)/bookings' - | '/(auth)/gatherings' + | '/_auth' + | '/bookings/(auth)' | '/gatherings/' | '/healthcheck/' | '/login/' - | '/(auth)/gatherings/create' + | '/gatherings/(auth)/create' | '/gatherings/$gatheringId/' - | '/(auth)/gatherings/$gatheringId/update' - | '/(auth)/bookings/attending/' - | '/(auth)/bookings/hosting/' - | '/(auth)/bookings/hosting/$gatheringId/dashboard/scan' - | '/(auth)/bookings/hosting/$gatheringId/dashboard/' + | '/gatherings/$gatheringId/(auth)/update' + | '/bookings/(auth)/attending/' + | '/bookings/(auth)/hosting/' + | '/bookings/(auth)/hosting/$gatheringId/dashboard/scan' + | '/bookings/(auth)/hosting/$gatheringId/dashboard/' fileRoutesById: FileRoutesById } export interface RootRouteChildren { IndexRoute: typeof IndexRoute - authBookingsRouteRoute: typeof authBookingsRouteRouteWithChildren - authGatheringsRouteRoute: typeof authGatheringsRouteRouteWithChildren + AuthRoute: typeof AuthRoute + BookingsauthRouteRoute: typeof BookingsauthRouteRouteWithChildren GatheringsIndexRoute: typeof GatheringsIndexRoute HealthcheckIndexRoute: typeof HealthcheckIndexRoute LoginIndexRoute: typeof LoginIndexRoute + GatheringsauthCreateRoute: typeof GatheringsauthCreateRoute GatheringsGatheringIdIndexRoute: typeof GatheringsGatheringIdIndexRoute + GatheringsGatheringIdauthUpdateRoute: typeof GatheringsGatheringIdauthUpdateRoute } declare module '@tanstack/react-router' { interface FileRoutesByPath { + '/_auth': { + id: '/_auth' + path: '' + fullPath: '' + preLoaderRoute: typeof AuthRouteImport + parentRoute: typeof rootRouteImport + } '/': { id: '/' path: '/' @@ -225,18 +233,11 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof GatheringsIndexRouteImport parentRoute: typeof rootRouteImport } - '/(auth)/gatherings': { - id: '/(auth)/gatherings' - path: '/gatherings' - fullPath: '/gatherings' - preLoaderRoute: typeof authGatheringsRouteRouteImport - parentRoute: typeof rootRouteImport - } - '/(auth)/bookings': { - id: '/(auth)/bookings' + '/bookings/(auth)': { + id: '/bookings/(auth)' path: '/bookings' fullPath: '/bookings' - preLoaderRoute: typeof authBookingsRouteRouteImport + preLoaderRoute: typeof BookingsauthRouteRouteImport parentRoute: typeof rootRouteImport } '/gatherings/$gatheringId/': { @@ -246,91 +247,80 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof GatheringsGatheringIdIndexRouteImport parentRoute: typeof rootRouteImport } - '/(auth)/gatherings/create': { - id: '/(auth)/gatherings/create' - path: '/create' + '/gatherings/(auth)/create': { + id: '/gatherings/(auth)/create' + path: '/gatherings/create' fullPath: '/gatherings/create' - preLoaderRoute: typeof authGatheringsCreateRouteImport - parentRoute: typeof authGatheringsRouteRoute + preLoaderRoute: typeof GatheringsauthCreateRouteImport + parentRoute: typeof rootRouteImport } - '/(auth)/bookings/hosting/': { - id: '/(auth)/bookings/hosting/' + '/bookings/(auth)/hosting/': { + id: '/bookings/(auth)/hosting/' path: '/hosting' fullPath: '/bookings/hosting' - preLoaderRoute: typeof authBookingsHostingIndexRouteImport - parentRoute: typeof authBookingsRouteRoute + preLoaderRoute: typeof BookingsauthHostingIndexRouteImport + parentRoute: typeof BookingsauthRouteRoute } - '/(auth)/bookings/attending/': { - id: '/(auth)/bookings/attending/' + '/bookings/(auth)/attending/': { + id: '/bookings/(auth)/attending/' path: '/attending' fullPath: '/bookings/attending' - preLoaderRoute: typeof authBookingsAttendingIndexRouteImport - parentRoute: typeof authBookingsRouteRoute + preLoaderRoute: typeof BookingsauthAttendingIndexRouteImport + parentRoute: typeof BookingsauthRouteRoute } - '/(auth)/gatherings/$gatheringId/update': { - id: '/(auth)/gatherings/$gatheringId/update' - path: '/$gatheringId/update' + '/gatherings/$gatheringId/(auth)/update': { + id: '/gatherings/$gatheringId/(auth)/update' + path: '/gatherings/$gatheringId/update' fullPath: '/gatherings/$gatheringId/update' - preLoaderRoute: typeof authGatheringsGatheringIdUpdateRouteImport - parentRoute: typeof authGatheringsRouteRoute + preLoaderRoute: typeof GatheringsGatheringIdauthUpdateRouteImport + parentRoute: typeof rootRouteImport } - '/(auth)/bookings/hosting/$gatheringId/dashboard/': { - id: '/(auth)/bookings/hosting/$gatheringId/dashboard/' + '/bookings/(auth)/hosting/$gatheringId/dashboard/': { + id: '/bookings/(auth)/hosting/$gatheringId/dashboard/' path: '/hosting/$gatheringId/dashboard' fullPath: '/bookings/hosting/$gatheringId/dashboard' - preLoaderRoute: typeof authBookingsHostingGatheringIdDashboardIndexRouteImport - parentRoute: typeof authBookingsRouteRoute + preLoaderRoute: typeof BookingsauthHostingGatheringIdDashboardIndexRouteImport + parentRoute: typeof BookingsauthRouteRoute } - '/(auth)/bookings/hosting/$gatheringId/dashboard/scan': { - id: '/(auth)/bookings/hosting/$gatheringId/dashboard/scan' + '/bookings/(auth)/hosting/$gatheringId/dashboard/scan': { + id: '/bookings/(auth)/hosting/$gatheringId/dashboard/scan' path: '/hosting/$gatheringId/dashboard/scan' fullPath: '/bookings/hosting/$gatheringId/dashboard/scan' - preLoaderRoute: typeof authBookingsHostingGatheringIdDashboardScanRouteImport - parentRoute: typeof authBookingsRouteRoute + preLoaderRoute: typeof BookingsauthHostingGatheringIdDashboardScanRouteImport + parentRoute: typeof BookingsauthRouteRoute } } } -interface authBookingsRouteRouteChildren { - authBookingsAttendingIndexRoute: typeof authBookingsAttendingIndexRoute - authBookingsHostingIndexRoute: typeof authBookingsHostingIndexRoute - authBookingsHostingGatheringIdDashboardScanRoute: typeof authBookingsHostingGatheringIdDashboardScanRoute - authBookingsHostingGatheringIdDashboardIndexRoute: typeof authBookingsHostingGatheringIdDashboardIndexRoute -} - -const authBookingsRouteRouteChildren: authBookingsRouteRouteChildren = { - authBookingsAttendingIndexRoute: authBookingsAttendingIndexRoute, - authBookingsHostingIndexRoute: authBookingsHostingIndexRoute, - authBookingsHostingGatheringIdDashboardScanRoute: - authBookingsHostingGatheringIdDashboardScanRoute, - authBookingsHostingGatheringIdDashboardIndexRoute: - authBookingsHostingGatheringIdDashboardIndexRoute, -} - -const authBookingsRouteRouteWithChildren = - authBookingsRouteRoute._addFileChildren(authBookingsRouteRouteChildren) - -interface authGatheringsRouteRouteChildren { - authGatheringsCreateRoute: typeof authGatheringsCreateRoute - authGatheringsGatheringIdUpdateRoute: typeof authGatheringsGatheringIdUpdateRoute +interface BookingsauthRouteRouteChildren { + BookingsauthAttendingIndexRoute: typeof BookingsauthAttendingIndexRoute + BookingsauthHostingIndexRoute: typeof BookingsauthHostingIndexRoute + BookingsauthHostingGatheringIdDashboardScanRoute: typeof BookingsauthHostingGatheringIdDashboardScanRoute + BookingsauthHostingGatheringIdDashboardIndexRoute: typeof BookingsauthHostingGatheringIdDashboardIndexRoute } -const authGatheringsRouteRouteChildren: authGatheringsRouteRouteChildren = { - authGatheringsCreateRoute: authGatheringsCreateRoute, - authGatheringsGatheringIdUpdateRoute: authGatheringsGatheringIdUpdateRoute, +const BookingsauthRouteRouteChildren: BookingsauthRouteRouteChildren = { + BookingsauthAttendingIndexRoute: BookingsauthAttendingIndexRoute, + BookingsauthHostingIndexRoute: BookingsauthHostingIndexRoute, + BookingsauthHostingGatheringIdDashboardScanRoute: + BookingsauthHostingGatheringIdDashboardScanRoute, + BookingsauthHostingGatheringIdDashboardIndexRoute: + BookingsauthHostingGatheringIdDashboardIndexRoute, } -const authGatheringsRouteRouteWithChildren = - authGatheringsRouteRoute._addFileChildren(authGatheringsRouteRouteChildren) +const BookingsauthRouteRouteWithChildren = + BookingsauthRouteRoute._addFileChildren(BookingsauthRouteRouteChildren) const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, - authBookingsRouteRoute: authBookingsRouteRouteWithChildren, - authGatheringsRouteRoute: authGatheringsRouteRouteWithChildren, + AuthRoute: AuthRoute, + BookingsauthRouteRoute: BookingsauthRouteRouteWithChildren, GatheringsIndexRoute: GatheringsIndexRoute, HealthcheckIndexRoute: HealthcheckIndexRoute, LoginIndexRoute: LoginIndexRoute, + GatheringsauthCreateRoute: GatheringsauthCreateRoute, GatheringsGatheringIdIndexRoute: GatheringsGatheringIdIndexRoute, + GatheringsGatheringIdauthUpdateRoute: GatheringsGatheringIdauthUpdateRoute, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/src/evently.client/src/routes/(auth)/gatherings/route.tsx b/src/evently.client/src/routes/(auth)/gatherings/route.tsx deleted file mode 100644 index 7d3282b..0000000 --- a/src/evently.client/src/routes/(auth)/gatherings/route.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { createFileRoute, Outlet, redirect } from "@tanstack/react-router"; - -export const Route = createFileRoute("/(auth)/gatherings")({ - beforeLoad: ({ context }) => { - if (context.account == null) { - throw redirect({ - to: "/login", - replace: true, - search: { - redirect: location.href - } - }); - } - }, - component: AuthLayout -}); - -function AuthLayout() { - return ( - <> - - - ); -} diff --git a/src/evently.client/src/routes/(auth)/bookings/route.tsx b/src/evently.client/src/routes/_auth.tsx similarity index 85% rename from src/evently.client/src/routes/(auth)/bookings/route.tsx rename to src/evently.client/src/routes/_auth.tsx index 60942be..38f6b19 100644 --- a/src/evently.client/src/routes/(auth)/bookings/route.tsx +++ b/src/evently.client/src/routes/_auth.tsx @@ -1,6 +1,6 @@ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router"; -export const Route = createFileRoute("/(auth)/bookings")({ +export const Route = createFileRoute("/_auth")({ beforeLoad: ({ context }) => { if (context.account == null) { throw redirect({ diff --git a/src/evently.client/src/routes/(auth)/bookings/attending/index.tsx b/src/evently.client/src/routes/bookings/(auth)/attending/index.tsx similarity index 97% rename from src/evently.client/src/routes/(auth)/bookings/attending/index.tsx rename to src/evently.client/src/routes/bookings/(auth)/attending/index.tsx index 9d0db30..520c60b 100644 --- a/src/evently.client/src/routes/(auth)/bookings/attending/index.tsx +++ b/src/evently.client/src/routes/bookings/(auth)/attending/index.tsx @@ -6,7 +6,7 @@ import { Card, Tabs, TabState } from "~/lib/components"; import cloneDeep from "lodash.clonedeep"; import { useQuery } from "@tanstack/react-query"; -export const Route = createFileRoute("/(auth)/bookings/attending/")({ +export const Route = createFileRoute("/bookings/(auth)/attending/")({ loader: ({ context }) => ({ account: context.account }), component: GetBookingsPage, pendingComponent: () => ( diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/bookings-table.tsx b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/bookings-table.tsx similarity index 100% rename from src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/bookings-table.tsx rename to src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/bookings-table.tsx diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/index.ts b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/index.ts similarity index 100% rename from src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/index.ts rename to src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/index.ts diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/jumbotron.tsx b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/jumbotron.tsx similarity index 100% rename from src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/jumbotron.tsx rename to src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/jumbotron.tsx diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/scanner.tsx b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/scanner.tsx similarity index 100% rename from src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/scanner.tsx rename to src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/scanner.tsx diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/stats-card.tsx b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/stats-card.tsx similarity index 100% rename from src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/-components/stats-card.tsx rename to src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/-components/stats-card.tsx diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/dashboard.index.tsx b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/dashboard.index.tsx similarity index 98% rename from src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/dashboard.index.tsx rename to src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/dashboard.index.tsx index d8fcb4e..eceaa69 100644 --- a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/dashboard.index.tsx +++ b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/dashboard.index.tsx @@ -12,7 +12,7 @@ import { BookingsTable, Jumbotron, StatsCard } from "./-components"; import { useInterval } from "usehooks-ts"; import type { PageResult } from "~/lib/domains/interfaces"; -export const Route = createFileRoute("/(auth)/bookings/hosting/$gatheringId/dashboard/")({ +export const Route = createFileRoute("/bookings/(auth)/hosting/$gatheringId/dashboard/")({ loader: async ({ params }) => { const gatheringId: number = parseInt(params.gatheringId); const gathering: Gathering = (await getGathering(gatheringId)) ?? new Gathering(); diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/dashboard.scan.tsx b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/dashboard.scan.tsx similarity index 98% rename from src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/dashboard.scan.tsx rename to src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/dashboard.scan.tsx index e5142f2..5eaa85b 100644 --- a/src/evently.client/src/routes/(auth)/bookings/hosting/$gatheringId/dashboard.scan.tsx +++ b/src/evently.client/src/routes/bookings/(auth)/hosting/$gatheringId/dashboard.scan.tsx @@ -7,7 +7,7 @@ import { ToastContent, ToastStatus, toastStyles } from "~/lib/domains/models"; import { useForm } from "@tanstack/react-form"; import { FieldErrMsg as FieldInfo } from "~/lib/components"; -export const Route = createFileRoute("/(auth)/bookings/hosting/$gatheringId/dashboard/scan")({ +export const Route = createFileRoute("/bookings/(auth)/hosting/$gatheringId/dashboard/scan")({ component: RouteComponent }); diff --git a/src/evently.client/src/routes/(auth)/bookings/hosting/index.tsx b/src/evently.client/src/routes/bookings/(auth)/hosting/index.tsx similarity index 97% rename from src/evently.client/src/routes/(auth)/bookings/hosting/index.tsx rename to src/evently.client/src/routes/bookings/(auth)/hosting/index.tsx index 571ce53..e788c6e 100644 --- a/src/evently.client/src/routes/(auth)/bookings/hosting/index.tsx +++ b/src/evently.client/src/routes/bookings/(auth)/hosting/index.tsx @@ -6,7 +6,7 @@ import { Card, Tabs, TabState } from "~/lib/components"; import { useQuery } from "@tanstack/react-query"; import cloneDeep from "lodash.clonedeep"; -export const Route = createFileRoute("/(auth)/bookings/hosting/")({ +export const Route = createFileRoute("/bookings/(auth)/hosting/")({ component: GetHostedGatheringsPage, pendingComponent: () => (
diff --git a/src/evently.client/src/routes/bookings/(auth)/route.tsx b/src/evently.client/src/routes/bookings/(auth)/route.tsx new file mode 100644 index 0000000..e7c6114 --- /dev/null +++ b/src/evently.client/src/routes/bookings/(auth)/route.tsx @@ -0,0 +1,11 @@ +import { createFileRoute, Outlet } from "@tanstack/react-router"; +import { guardRoute } from "~/lib/services"; + +export const Route = createFileRoute("/bookings/(auth)")({ + beforeLoad: ({ context }) => guardRoute(context.account, window.location.href), + component: AuthLayout +}); + +function AuthLayout() { + return ; +} diff --git a/src/evently.client/src/routes/(auth)/gatherings/$gatheringId/update.tsx b/src/evently.client/src/routes/gatherings/$gatheringId/(auth).update.tsx similarity index 84% rename from src/evently.client/src/routes/(auth)/gatherings/$gatheringId/update.tsx rename to src/evently.client/src/routes/gatherings/$gatheringId/(auth).update.tsx index 1b2c602..ceee85a 100644 --- a/src/evently.client/src/routes/(auth)/gatherings/$gatheringId/update.tsx +++ b/src/evently.client/src/routes/gatherings/$gatheringId/(auth).update.tsx @@ -1,15 +1,23 @@ import { createFileRoute } from "@tanstack/react-router"; import { Category, Gathering } from "~/lib/domains/entities"; import { useEffect, useState, type JSX } from "react"; -import { fetchFile, getCategories, getGathering, sleep, updateGathering } from "~/lib/services"; +import { + fetchFile, + getCategories, + getGathering, + guardRoute, + sleep, + updateGathering +} from "~/lib/services"; import { useGatheringForm, type GatheringForm as IGatheringForm -} from "~/routes/(auth)/gatherings/-services"; +} from "~/routes/gatherings/-services"; import { GatheringReqDto, ToastContent } from "~/lib/domains/models"; -import { GatheringForm } from "~/routes/(auth)/gatherings/-components"; +import { GatheringForm } from "~/routes/gatherings/-components"; -export const Route = createFileRoute("/(auth)/gatherings/$gatheringId/update")({ +export const Route = createFileRoute("/gatherings/$gatheringId/(auth)/update")({ + beforeLoad: ({ context }) => guardRoute(context.account, window.location.href), loader: async ({ params }) => { const gatheringId: number = parseInt(params.gatheringId); let gathering: Gathering | null = await getGathering(gatheringId); diff --git a/src/evently.client/src/routes/(auth)/gatherings/create.tsx b/src/evently.client/src/routes/gatherings/(auth).create.tsx similarity index 85% rename from src/evently.client/src/routes/(auth)/gatherings/create.tsx rename to src/evently.client/src/routes/gatherings/(auth).create.tsx index b2c3abf..a54014f 100644 --- a/src/evently.client/src/routes/(auth)/gatherings/create.tsx +++ b/src/evently.client/src/routes/gatherings/(auth).create.tsx @@ -1,12 +1,13 @@ import { createFileRoute } from "@tanstack/react-router"; import { Category, Gathering } from "~/lib/domains/entities"; import { useState, type JSX } from "react"; -import { createGathering, getCategories, sleep } from "~/lib/services"; +import { createGathering, getCategories, guardRoute, sleep } from "~/lib/services"; import { useGatheringForm, type GatheringForm as IGatheringForm } from "./-services"; import { GatheringReqDto, ToastContent } from "~/lib/domains/models"; -import { GatheringForm } from "~/routes/(auth)/gatherings/-components"; +import { GatheringForm } from "~/routes/gatherings/-components"; -export const Route = createFileRoute("/(auth)/gatherings/create")({ +export const Route = createFileRoute("/gatherings/(auth)/create")({ + beforeLoad: ({ context }) => guardRoute(context.account, window.location.href), loader: async () => { const categories: Category[] = await getCategories(); return { categories }; diff --git a/src/evently.client/src/routes/(auth)/gatherings/-components/gathering-form.tsx b/src/evently.client/src/routes/gatherings/-components/gathering-form.tsx similarity index 100% rename from src/evently.client/src/routes/(auth)/gatherings/-components/gathering-form.tsx rename to src/evently.client/src/routes/gatherings/-components/gathering-form.tsx diff --git a/src/evently.client/src/routes/(auth)/gatherings/-components/index.ts b/src/evently.client/src/routes/gatherings/-components/index.ts similarity index 100% rename from src/evently.client/src/routes/(auth)/gatherings/-components/index.ts rename to src/evently.client/src/routes/gatherings/-components/index.ts diff --git a/src/evently.client/src/routes/(auth)/gatherings/-services/file-service.ts b/src/evently.client/src/routes/gatherings/-services/file-service.ts similarity index 100% rename from src/evently.client/src/routes/(auth)/gatherings/-services/file-service.ts rename to src/evently.client/src/routes/gatherings/-services/file-service.ts diff --git a/src/evently.client/src/routes/(auth)/gatherings/-services/index.ts b/src/evently.client/src/routes/gatherings/-services/index.ts similarity index 100% rename from src/evently.client/src/routes/(auth)/gatherings/-services/index.ts rename to src/evently.client/src/routes/gatherings/-services/index.ts diff --git a/src/evently.client/src/routes/(auth)/gatherings/-services/use-gathering-form.ts b/src/evently.client/src/routes/gatherings/-services/use-gathering-form.ts similarity index 100% rename from src/evently.client/src/routes/(auth)/gatherings/-services/use-gathering-form.ts rename to src/evently.client/src/routes/gatherings/-services/use-gathering-form.ts