diff --git a/src/pages/groups/Groups/SignInRequired.tsx b/src/pages/groups/Groups/SignInRequired.tsx
index e3a4e8a2..83fb0ea1 100644
--- a/src/pages/groups/Groups/SignInRequired.tsx
+++ b/src/pages/groups/Groups/SignInRequired.tsx
@@ -6,7 +6,7 @@ import {
CardContent,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
-import { Link } from "react-router-dom";
+import { Link } from "@tanstack/react-router";
export function SignInRequired() {
return (
diff --git a/src/pages/legal/CookiePolicy.tsx b/src/pages/legal/CookiePolicy.tsx
index 63a8e851..ef0753af 100644
--- a/src/pages/legal/CookiePolicy.tsx
+++ b/src/pages/legal/CookiePolicy.tsx
@@ -1,7 +1,7 @@
import { TopBar } from "@/components/layout/TopBar";
import { Button } from "@/components/ui/button";
import { ArrowLeft } from "lucide-react";
-import { Link } from "react-router-dom";
+import { Link } from "@tanstack/react-router";
function CookiePolicy() {
return (
diff --git a/src/pages/legal/PrivacyPolicy.tsx b/src/pages/legal/PrivacyPolicy.tsx
index e68a3cef..feccea57 100644
--- a/src/pages/legal/PrivacyPolicy.tsx
+++ b/src/pages/legal/PrivacyPolicy.tsx
@@ -1,7 +1,7 @@
import { TopBar } from "@/components/layout/TopBar";
import { Button } from "@/components/ui/button";
import { ArrowLeft } from "lucide-react";
-import { Link } from "react-router-dom";
+import { Link } from "@tanstack/react-router";
function PrivacyPolicy() {
return (
diff --git a/src/pages/legal/TermsOfService.tsx b/src/pages/legal/TermsOfService.tsx
index db287014..a62bd088 100644
--- a/src/pages/legal/TermsOfService.tsx
+++ b/src/pages/legal/TermsOfService.tsx
@@ -1,7 +1,7 @@
import { TopBar } from "@/components/layout/TopBar";
import { Button } from "@/components/ui/button";
import { ArrowLeft } from "lucide-react";
-import { Link } from "react-router-dom";
+import { Link } from "@tanstack/react-router";
function TermsOfService() {
return (
diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts
new file mode 100644
index 00000000..73c3e906
--- /dev/null
+++ b/src/routeTree.gen.ts
@@ -0,0 +1,790 @@
+/* eslint-disable */
+
+// @ts-nocheck
+
+// noinspection JSUnusedGlobalSymbols
+
+// This file was automatically generated by TanStack Router.
+// You should NOT make any changes in this file as it will be overwritten.
+// 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 TermsRouteImport } from "./routes/terms";
+import { Route as PrivacyRouteImport } from "./routes/privacy";
+import { Route as CookiesRouteImport } from "./routes/cookies";
+import { Route as AdminRouteImport } from "./routes/admin";
+import { Route as IndexRouteImport } from "./routes/index";
+import { Route as GroupsIndexRouteImport } from "./routes/groups/index";
+import { Route as GroupsGroupSlugRouteImport } from "./routes/groups/$groupSlug";
+import { Route as AdminFestivalsRouteImport } from "./routes/admin/festivals";
+import { Route as AdminArtistsRouteImport } from "./routes/admin/artists";
+import { Route as AdminAnalyticsRouteImport } from "./routes/admin/analytics";
+import { Route as AdminAdminsRouteImport } from "./routes/admin/admins";
+import { Route as FestivalsFestivalSlugIndexRouteImport } from "./routes/festivals/$festivalSlug/index";
+import { Route as AdminFestivalsImportRouteImport } from "./routes/admin/festivals/import";
+import { Route as AdminFestivalsFestivalSlugRouteImport } from "./routes/admin/festivals/$festivalSlug";
+import { Route as AdminArtistsDuplicatesRouteImport } from "./routes/admin/artists/duplicates";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugSocialRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/social";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugSetsRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/sets";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugScheduleRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/schedule";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugMapRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/map";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugInfoRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/info";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugExploreRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/explore";
+import { Route as AdminFestivalsFestivalSlugEditionsEditionSlugRouteImport } from "./routes/admin/festivals/$festivalSlug/editions/$editionSlug";
+import { Route as AdminFestivalsFestivalIdEditionIdImportRouteImport } from "./routes/admin/festivals/$festivalId.$editionId.import";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugSetsIndexRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/sets/index";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline";
+import { Route as FestivalsFestivalSlugEditionsEditionSlugScheduleListRouteImport } from "./routes/festivals/$festivalSlug/editions/$editionSlug/schedule/list";
+import { Route as AdminFestivalsFestivalSlugEditionsEditionSlugStagesRouteImport } from "./routes/admin/festivals/$festivalSlug/editions/$editionSlug/stages";
+import { Route as AdminFestivalsFestivalSlugEditionsEditionSlugSetsRouteImport } from "./routes/admin/festivals/$festivalSlug/editions/$editionSlug/sets";
+
+const TermsRoute = TermsRouteImport.update({
+ id: "/terms",
+ path: "/terms",
+ getParentRoute: () => rootRouteImport,
+} as any);
+const PrivacyRoute = PrivacyRouteImport.update({
+ id: "/privacy",
+ path: "/privacy",
+ getParentRoute: () => rootRouteImport,
+} as any);
+const CookiesRoute = CookiesRouteImport.update({
+ id: "/cookies",
+ path: "/cookies",
+ getParentRoute: () => rootRouteImport,
+} as any);
+const AdminRoute = AdminRouteImport.update({
+ id: "/admin",
+ path: "/admin",
+ getParentRoute: () => rootRouteImport,
+} as any);
+const IndexRoute = IndexRouteImport.update({
+ id: "/",
+ path: "/",
+ getParentRoute: () => rootRouteImport,
+} as any);
+const GroupsIndexRoute = GroupsIndexRouteImport.update({
+ id: "/groups/",
+ path: "/groups/",
+ getParentRoute: () => rootRouteImport,
+} as any);
+const GroupsGroupSlugRoute = GroupsGroupSlugRouteImport.update({
+ id: "/groups/$groupSlug",
+ path: "/groups/$groupSlug",
+ getParentRoute: () => rootRouteImport,
+} as any);
+const AdminFestivalsRoute = AdminFestivalsRouteImport.update({
+ id: "/festivals",
+ path: "/festivals",
+ getParentRoute: () => AdminRoute,
+} as any);
+const AdminArtistsRoute = AdminArtistsRouteImport.update({
+ id: "/artists",
+ path: "/artists",
+ getParentRoute: () => AdminRoute,
+} as any);
+const AdminAnalyticsRoute = AdminAnalyticsRouteImport.update({
+ id: "/analytics",
+ path: "/analytics",
+ getParentRoute: () => AdminRoute,
+} as any);
+const AdminAdminsRoute = AdminAdminsRouteImport.update({
+ id: "/admins",
+ path: "/admins",
+ getParentRoute: () => AdminRoute,
+} as any);
+const FestivalsFestivalSlugIndexRoute =
+ FestivalsFestivalSlugIndexRouteImport.update({
+ id: "/festivals/$festivalSlug/",
+ path: "/festivals/$festivalSlug/",
+ getParentRoute: () => rootRouteImport,
+ } as any);
+const AdminFestivalsImportRoute = AdminFestivalsImportRouteImport.update({
+ id: "/import",
+ path: "/import",
+ getParentRoute: () => AdminFestivalsRoute,
+} as any);
+const AdminFestivalsFestivalSlugRoute =
+ AdminFestivalsFestivalSlugRouteImport.update({
+ id: "/$festivalSlug",
+ path: "/$festivalSlug",
+ getParentRoute: () => AdminFestivalsRoute,
+ } as any);
+const AdminArtistsDuplicatesRoute = AdminArtistsDuplicatesRouteImport.update({
+ id: "/duplicates",
+ path: "/duplicates",
+ getParentRoute: () => AdminArtistsRoute,
+} as any);
+const FestivalsFestivalSlugEditionsEditionSlugRoute =
+ FestivalsFestivalSlugEditionsEditionSlugRouteImport.update({
+ id: "/festivals/$festivalSlug/editions/$editionSlug",
+ path: "/festivals/$festivalSlug/editions/$editionSlug",
+ getParentRoute: () => rootRouteImport,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugSocialRoute =
+ FestivalsFestivalSlugEditionsEditionSlugSocialRouteImport.update({
+ id: "/social",
+ path: "/social",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugSetsRoute =
+ FestivalsFestivalSlugEditionsEditionSlugSetsRouteImport.update({
+ id: "/sets",
+ path: "/sets",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugScheduleRoute =
+ FestivalsFestivalSlugEditionsEditionSlugScheduleRouteImport.update({
+ id: "/schedule",
+ path: "/schedule",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugMapRoute =
+ FestivalsFestivalSlugEditionsEditionSlugMapRouteImport.update({
+ id: "/map",
+ path: "/map",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugInfoRoute =
+ FestivalsFestivalSlugEditionsEditionSlugInfoRouteImport.update({
+ id: "/info",
+ path: "/info",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugExploreRoute =
+ FestivalsFestivalSlugEditionsEditionSlugExploreRouteImport.update({
+ id: "/explore",
+ path: "/explore",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+const AdminFestivalsFestivalSlugEditionsEditionSlugRoute =
+ AdminFestivalsFestivalSlugEditionsEditionSlugRouteImport.update({
+ id: "/editions/$editionSlug",
+ path: "/editions/$editionSlug",
+ getParentRoute: () => AdminFestivalsFestivalSlugRoute,
+ } as any);
+const AdminFestivalsFestivalIdEditionIdImportRoute =
+ AdminFestivalsFestivalIdEditionIdImportRouteImport.update({
+ id: "/$festivalId/$editionId/import",
+ path: "/$festivalId/$editionId/import",
+ getParentRoute: () => AdminFestivalsRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute =
+ FestivalsFestivalSlugEditionsEditionSlugSetsIndexRouteImport.update({
+ id: "/",
+ path: "/",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugSetsRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute =
+ FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRouteImport.update({
+ id: "/$setSlug",
+ path: "/$setSlug",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugSetsRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute =
+ FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRouteImport.update({
+ id: "/timeline",
+ path: "/timeline",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugScheduleRoute,
+ } as any);
+const FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute =
+ FestivalsFestivalSlugEditionsEditionSlugScheduleListRouteImport.update({
+ id: "/list",
+ path: "/list",
+ getParentRoute: () => FestivalsFestivalSlugEditionsEditionSlugScheduleRoute,
+ } as any);
+const AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute =
+ AdminFestivalsFestivalSlugEditionsEditionSlugStagesRouteImport.update({
+ id: "/stages",
+ path: "/stages",
+ getParentRoute: () => AdminFestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+const AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute =
+ AdminFestivalsFestivalSlugEditionsEditionSlugSetsRouteImport.update({
+ id: "/sets",
+ path: "/sets",
+ getParentRoute: () => AdminFestivalsFestivalSlugEditionsEditionSlugRoute,
+ } as any);
+
+export interface FileRoutesByFullPath {
+ "/": typeof IndexRoute;
+ "/admin": typeof AdminRouteWithChildren;
+ "/cookies": typeof CookiesRoute;
+ "/privacy": typeof PrivacyRoute;
+ "/terms": typeof TermsRoute;
+ "/admin/admins": typeof AdminAdminsRoute;
+ "/admin/analytics": typeof AdminAnalyticsRoute;
+ "/admin/artists": typeof AdminArtistsRouteWithChildren;
+ "/admin/festivals": typeof AdminFestivalsRouteWithChildren;
+ "/groups/$groupSlug": typeof GroupsGroupSlugRoute;
+ "/groups": typeof GroupsIndexRoute;
+ "/admin/artists/duplicates": typeof AdminArtistsDuplicatesRoute;
+ "/admin/festivals/$festivalSlug": typeof AdminFestivalsFestivalSlugRouteWithChildren;
+ "/admin/festivals/import": typeof AdminFestivalsImportRoute;
+ "/festivals/$festivalSlug": typeof FestivalsFestivalSlugIndexRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug": typeof FestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+ "/admin/festivals/$festivalId/$editionId/import": typeof AdminFestivalsFestivalIdEditionIdImportRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug": typeof AdminFestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/explore": typeof FestivalsFestivalSlugEditionsEditionSlugExploreRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/info": typeof FestivalsFestivalSlugEditionsEditionSlugInfoRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/map": typeof FestivalsFestivalSlugEditionsEditionSlugMapRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets": typeof FestivalsFestivalSlugEditionsEditionSlugSetsRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/social": typeof FestivalsFestivalSlugEditionsEditionSlugSocialRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/sets": typeof AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/stages": typeof AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/list": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug": typeof FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/": typeof FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute;
+}
+export interface FileRoutesByTo {
+ "/": typeof IndexRoute;
+ "/admin": typeof AdminRouteWithChildren;
+ "/cookies": typeof CookiesRoute;
+ "/privacy": typeof PrivacyRoute;
+ "/terms": typeof TermsRoute;
+ "/admin/admins": typeof AdminAdminsRoute;
+ "/admin/analytics": typeof AdminAnalyticsRoute;
+ "/admin/artists": typeof AdminArtistsRouteWithChildren;
+ "/admin/festivals": typeof AdminFestivalsRouteWithChildren;
+ "/groups/$groupSlug": typeof GroupsGroupSlugRoute;
+ "/groups": typeof GroupsIndexRoute;
+ "/admin/artists/duplicates": typeof AdminArtistsDuplicatesRoute;
+ "/admin/festivals/$festivalSlug": typeof AdminFestivalsFestivalSlugRouteWithChildren;
+ "/admin/festivals/import": typeof AdminFestivalsImportRoute;
+ "/festivals/$festivalSlug": typeof FestivalsFestivalSlugIndexRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug": typeof FestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+ "/admin/festivals/$festivalId/$editionId/import": typeof AdminFestivalsFestivalIdEditionIdImportRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug": typeof AdminFestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/explore": typeof FestivalsFestivalSlugEditionsEditionSlugExploreRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/info": typeof FestivalsFestivalSlugEditionsEditionSlugInfoRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/map": typeof FestivalsFestivalSlugEditionsEditionSlugMapRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/social": typeof FestivalsFestivalSlugEditionsEditionSlugSocialRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/sets": typeof AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/stages": typeof AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/list": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug": typeof FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets": typeof FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute;
+}
+export interface FileRoutesById {
+ __root__: typeof rootRouteImport;
+ "/": typeof IndexRoute;
+ "/admin": typeof AdminRouteWithChildren;
+ "/cookies": typeof CookiesRoute;
+ "/privacy": typeof PrivacyRoute;
+ "/terms": typeof TermsRoute;
+ "/admin/admins": typeof AdminAdminsRoute;
+ "/admin/analytics": typeof AdminAnalyticsRoute;
+ "/admin/artists": typeof AdminArtistsRouteWithChildren;
+ "/admin/festivals": typeof AdminFestivalsRouteWithChildren;
+ "/groups/$groupSlug": typeof GroupsGroupSlugRoute;
+ "/groups/": typeof GroupsIndexRoute;
+ "/admin/artists/duplicates": typeof AdminArtistsDuplicatesRoute;
+ "/admin/festivals/$festivalSlug": typeof AdminFestivalsFestivalSlugRouteWithChildren;
+ "/admin/festivals/import": typeof AdminFestivalsImportRoute;
+ "/festivals/$festivalSlug/": typeof FestivalsFestivalSlugIndexRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug": typeof FestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+ "/admin/festivals/$festivalId/$editionId/import": typeof AdminFestivalsFestivalIdEditionIdImportRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug": typeof AdminFestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/explore": typeof FestivalsFestivalSlugEditionsEditionSlugExploreRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/info": typeof FestivalsFestivalSlugEditionsEditionSlugInfoRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/map": typeof FestivalsFestivalSlugEditionsEditionSlugMapRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets": typeof FestivalsFestivalSlugEditionsEditionSlugSetsRouteWithChildren;
+ "/festivals/$festivalSlug/editions/$editionSlug/social": typeof FestivalsFestivalSlugEditionsEditionSlugSocialRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/sets": typeof AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute;
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/stages": typeof AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/list": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline": typeof FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug": typeof FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute;
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/": typeof FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute;
+}
+export interface FileRouteTypes {
+ fileRoutesByFullPath: FileRoutesByFullPath;
+ fullPaths:
+ | "/"
+ | "/admin"
+ | "/cookies"
+ | "/privacy"
+ | "/terms"
+ | "/admin/admins"
+ | "/admin/analytics"
+ | "/admin/artists"
+ | "/admin/festivals"
+ | "/groups/$groupSlug"
+ | "/groups"
+ | "/admin/artists/duplicates"
+ | "/admin/festivals/$festivalSlug"
+ | "/admin/festivals/import"
+ | "/festivals/$festivalSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug"
+ | "/admin/festivals/$festivalId/$editionId/import"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug/explore"
+ | "/festivals/$festivalSlug/editions/$editionSlug/info"
+ | "/festivals/$festivalSlug/editions/$editionSlug/map"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets"
+ | "/festivals/$festivalSlug/editions/$editionSlug/social"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug/sets"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug/stages"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule/list"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets/";
+ fileRoutesByTo: FileRoutesByTo;
+ to:
+ | "/"
+ | "/admin"
+ | "/cookies"
+ | "/privacy"
+ | "/terms"
+ | "/admin/admins"
+ | "/admin/analytics"
+ | "/admin/artists"
+ | "/admin/festivals"
+ | "/groups/$groupSlug"
+ | "/groups"
+ | "/admin/artists/duplicates"
+ | "/admin/festivals/$festivalSlug"
+ | "/admin/festivals/import"
+ | "/festivals/$festivalSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug"
+ | "/admin/festivals/$festivalId/$editionId/import"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug/explore"
+ | "/festivals/$festivalSlug/editions/$editionSlug/info"
+ | "/festivals/$festivalSlug/editions/$editionSlug/map"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule"
+ | "/festivals/$festivalSlug/editions/$editionSlug/social"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug/sets"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug/stages"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule/list"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets";
+ id:
+ | "__root__"
+ | "/"
+ | "/admin"
+ | "/cookies"
+ | "/privacy"
+ | "/terms"
+ | "/admin/admins"
+ | "/admin/analytics"
+ | "/admin/artists"
+ | "/admin/festivals"
+ | "/groups/$groupSlug"
+ | "/groups/"
+ | "/admin/artists/duplicates"
+ | "/admin/festivals/$festivalSlug"
+ | "/admin/festivals/import"
+ | "/festivals/$festivalSlug/"
+ | "/festivals/$festivalSlug/editions/$editionSlug"
+ | "/admin/festivals/$festivalId/$editionId/import"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug/explore"
+ | "/festivals/$festivalSlug/editions/$editionSlug/info"
+ | "/festivals/$festivalSlug/editions/$editionSlug/map"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets"
+ | "/festivals/$festivalSlug/editions/$editionSlug/social"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug/sets"
+ | "/admin/festivals/$festivalSlug/editions/$editionSlug/stages"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule/list"
+ | "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug"
+ | "/festivals/$festivalSlug/editions/$editionSlug/sets/";
+ fileRoutesById: FileRoutesById;
+}
+export interface RootRouteChildren {
+ IndexRoute: typeof IndexRoute;
+ AdminRoute: typeof AdminRouteWithChildren;
+ CookiesRoute: typeof CookiesRoute;
+ PrivacyRoute: typeof PrivacyRoute;
+ TermsRoute: typeof TermsRoute;
+ GroupsGroupSlugRoute: typeof GroupsGroupSlugRoute;
+ GroupsIndexRoute: typeof GroupsIndexRoute;
+ FestivalsFestivalSlugIndexRoute: typeof FestivalsFestivalSlugIndexRoute;
+ FestivalsFestivalSlugEditionsEditionSlugRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+}
+
+declare module "@tanstack/react-router" {
+ interface FileRoutesByPath {
+ "/terms": {
+ id: "/terms";
+ path: "/terms";
+ fullPath: "/terms";
+ preLoaderRoute: typeof TermsRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/privacy": {
+ id: "/privacy";
+ path: "/privacy";
+ fullPath: "/privacy";
+ preLoaderRoute: typeof PrivacyRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/cookies": {
+ id: "/cookies";
+ path: "/cookies";
+ fullPath: "/cookies";
+ preLoaderRoute: typeof CookiesRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/admin": {
+ id: "/admin";
+ path: "/admin";
+ fullPath: "/admin";
+ preLoaderRoute: typeof AdminRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/": {
+ id: "/";
+ path: "/";
+ fullPath: "/";
+ preLoaderRoute: typeof IndexRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/groups/": {
+ id: "/groups/";
+ path: "/groups";
+ fullPath: "/groups";
+ preLoaderRoute: typeof GroupsIndexRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/groups/$groupSlug": {
+ id: "/groups/$groupSlug";
+ path: "/groups/$groupSlug";
+ fullPath: "/groups/$groupSlug";
+ preLoaderRoute: typeof GroupsGroupSlugRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/admin/festivals": {
+ id: "/admin/festivals";
+ path: "/festivals";
+ fullPath: "/admin/festivals";
+ preLoaderRoute: typeof AdminFestivalsRouteImport;
+ parentRoute: typeof AdminRoute;
+ };
+ "/admin/artists": {
+ id: "/admin/artists";
+ path: "/artists";
+ fullPath: "/admin/artists";
+ preLoaderRoute: typeof AdminArtistsRouteImport;
+ parentRoute: typeof AdminRoute;
+ };
+ "/admin/analytics": {
+ id: "/admin/analytics";
+ path: "/analytics";
+ fullPath: "/admin/analytics";
+ preLoaderRoute: typeof AdminAnalyticsRouteImport;
+ parentRoute: typeof AdminRoute;
+ };
+ "/admin/admins": {
+ id: "/admin/admins";
+ path: "/admins";
+ fullPath: "/admin/admins";
+ preLoaderRoute: typeof AdminAdminsRouteImport;
+ parentRoute: typeof AdminRoute;
+ };
+ "/festivals/$festivalSlug/": {
+ id: "/festivals/$festivalSlug/";
+ path: "/festivals/$festivalSlug";
+ fullPath: "/festivals/$festivalSlug";
+ preLoaderRoute: typeof FestivalsFestivalSlugIndexRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/admin/festivals/import": {
+ id: "/admin/festivals/import";
+ path: "/import";
+ fullPath: "/admin/festivals/import";
+ preLoaderRoute: typeof AdminFestivalsImportRouteImport;
+ parentRoute: typeof AdminFestivalsRoute;
+ };
+ "/admin/festivals/$festivalSlug": {
+ id: "/admin/festivals/$festivalSlug";
+ path: "/$festivalSlug";
+ fullPath: "/admin/festivals/$festivalSlug";
+ preLoaderRoute: typeof AdminFestivalsFestivalSlugRouteImport;
+ parentRoute: typeof AdminFestivalsRoute;
+ };
+ "/admin/artists/duplicates": {
+ id: "/admin/artists/duplicates";
+ path: "/duplicates";
+ fullPath: "/admin/artists/duplicates";
+ preLoaderRoute: typeof AdminArtistsDuplicatesRouteImport;
+ parentRoute: typeof AdminArtistsRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug";
+ path: "/festivals/$festivalSlug/editions/$editionSlug";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRouteImport;
+ parentRoute: typeof rootRouteImport;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/social": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/social";
+ path: "/social";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/social";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSocialRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/sets": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/sets";
+ path: "/sets";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/sets";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/schedule";
+ path: "/schedule";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/schedule";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/map": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/map";
+ path: "/map";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/map";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugMapRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/info": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/info";
+ path: "/info";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/info";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugInfoRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/explore": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/explore";
+ path: "/explore";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/explore";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugExploreRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ "/admin/festivals/$festivalSlug/editions/$editionSlug": {
+ id: "/admin/festivals/$festivalSlug/editions/$editionSlug";
+ path: "/editions/$editionSlug";
+ fullPath: "/admin/festivals/$festivalSlug/editions/$editionSlug";
+ preLoaderRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugRouteImport;
+ parentRoute: typeof AdminFestivalsFestivalSlugRoute;
+ };
+ "/admin/festivals/$festivalId/$editionId/import": {
+ id: "/admin/festivals/$festivalId/$editionId/import";
+ path: "/$festivalId/$editionId/import";
+ fullPath: "/admin/festivals/$festivalId/$editionId/import";
+ preLoaderRoute: typeof AdminFestivalsFestivalIdEditionIdImportRouteImport;
+ parentRoute: typeof AdminFestivalsRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/sets/";
+ path: "/";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/sets/";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsIndexRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug";
+ path: "/$setSlug";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline";
+ path: "/timeline";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleRoute;
+ };
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/list": {
+ id: "/festivals/$festivalSlug/editions/$editionSlug/schedule/list";
+ path: "/list";
+ fullPath: "/festivals/$festivalSlug/editions/$editionSlug/schedule/list";
+ preLoaderRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleListRouteImport;
+ parentRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleRoute;
+ };
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/stages": {
+ id: "/admin/festivals/$festivalSlug/editions/$editionSlug/stages";
+ path: "/stages";
+ fullPath: "/admin/festivals/$festivalSlug/editions/$editionSlug/stages";
+ preLoaderRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugStagesRouteImport;
+ parentRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/sets": {
+ id: "/admin/festivals/$festivalSlug/editions/$editionSlug/sets";
+ path: "/sets";
+ fullPath: "/admin/festivals/$festivalSlug/editions/$editionSlug/sets";
+ preLoaderRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugSetsRouteImport;
+ parentRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugRoute;
+ };
+ }
+}
+
+interface AdminArtistsRouteChildren {
+ AdminArtistsDuplicatesRoute: typeof AdminArtistsDuplicatesRoute;
+}
+
+const AdminArtistsRouteChildren: AdminArtistsRouteChildren = {
+ AdminArtistsDuplicatesRoute: AdminArtistsDuplicatesRoute,
+};
+
+const AdminArtistsRouteWithChildren = AdminArtistsRoute._addFileChildren(
+ AdminArtistsRouteChildren,
+);
+
+interface AdminFestivalsFestivalSlugEditionsEditionSlugRouteChildren {
+ AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute;
+ AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute;
+}
+
+const AdminFestivalsFestivalSlugEditionsEditionSlugRouteChildren: AdminFestivalsFestivalSlugEditionsEditionSlugRouteChildren =
+ {
+ AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute:
+ AdminFestivalsFestivalSlugEditionsEditionSlugSetsRoute,
+ AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute:
+ AdminFestivalsFestivalSlugEditionsEditionSlugStagesRoute,
+ };
+
+const AdminFestivalsFestivalSlugEditionsEditionSlugRouteWithChildren =
+ AdminFestivalsFestivalSlugEditionsEditionSlugRoute._addFileChildren(
+ AdminFestivalsFestivalSlugEditionsEditionSlugRouteChildren,
+ );
+
+interface AdminFestivalsFestivalSlugRouteChildren {
+ AdminFestivalsFestivalSlugEditionsEditionSlugRoute: typeof AdminFestivalsFestivalSlugEditionsEditionSlugRouteWithChildren;
+}
+
+const AdminFestivalsFestivalSlugRouteChildren: AdminFestivalsFestivalSlugRouteChildren =
+ {
+ AdminFestivalsFestivalSlugEditionsEditionSlugRoute:
+ AdminFestivalsFestivalSlugEditionsEditionSlugRouteWithChildren,
+ };
+
+const AdminFestivalsFestivalSlugRouteWithChildren =
+ AdminFestivalsFestivalSlugRoute._addFileChildren(
+ AdminFestivalsFestivalSlugRouteChildren,
+ );
+
+interface AdminFestivalsRouteChildren {
+ AdminFestivalsFestivalSlugRoute: typeof AdminFestivalsFestivalSlugRouteWithChildren;
+ AdminFestivalsImportRoute: typeof AdminFestivalsImportRoute;
+ AdminFestivalsFestivalIdEditionIdImportRoute: typeof AdminFestivalsFestivalIdEditionIdImportRoute;
+}
+
+const AdminFestivalsRouteChildren: AdminFestivalsRouteChildren = {
+ AdminFestivalsFestivalSlugRoute: AdminFestivalsFestivalSlugRouteWithChildren,
+ AdminFestivalsImportRoute: AdminFestivalsImportRoute,
+ AdminFestivalsFestivalIdEditionIdImportRoute:
+ AdminFestivalsFestivalIdEditionIdImportRoute,
+};
+
+const AdminFestivalsRouteWithChildren = AdminFestivalsRoute._addFileChildren(
+ AdminFestivalsRouteChildren,
+);
+
+interface AdminRouteChildren {
+ AdminAdminsRoute: typeof AdminAdminsRoute;
+ AdminAnalyticsRoute: typeof AdminAnalyticsRoute;
+ AdminArtistsRoute: typeof AdminArtistsRouteWithChildren;
+ AdminFestivalsRoute: typeof AdminFestivalsRouteWithChildren;
+}
+
+const AdminRouteChildren: AdminRouteChildren = {
+ AdminAdminsRoute: AdminAdminsRoute,
+ AdminAnalyticsRoute: AdminAnalyticsRoute,
+ AdminArtistsRoute: AdminArtistsRouteWithChildren,
+ AdminFestivalsRoute: AdminFestivalsRouteWithChildren,
+};
+
+const AdminRouteWithChildren = AdminRoute._addFileChildren(AdminRouteChildren);
+
+interface FestivalsFestivalSlugEditionsEditionSlugScheduleRouteChildren {
+ FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute;
+ FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute;
+}
+
+const FestivalsFestivalSlugEditionsEditionSlugScheduleRouteChildren: FestivalsFestivalSlugEditionsEditionSlugScheduleRouteChildren =
+ {
+ FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute:
+ FestivalsFestivalSlugEditionsEditionSlugScheduleListRoute,
+ FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute:
+ FestivalsFestivalSlugEditionsEditionSlugScheduleTimelineRoute,
+ };
+
+const FestivalsFestivalSlugEditionsEditionSlugScheduleRouteWithChildren =
+ FestivalsFestivalSlugEditionsEditionSlugScheduleRoute._addFileChildren(
+ FestivalsFestivalSlugEditionsEditionSlugScheduleRouteChildren,
+ );
+
+interface FestivalsFestivalSlugEditionsEditionSlugSetsRouteChildren {
+ FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute;
+ FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute;
+}
+
+const FestivalsFestivalSlugEditionsEditionSlugSetsRouteChildren: FestivalsFestivalSlugEditionsEditionSlugSetsRouteChildren =
+ {
+ FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute:
+ FestivalsFestivalSlugEditionsEditionSlugSetsSetSlugRoute,
+ FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute:
+ FestivalsFestivalSlugEditionsEditionSlugSetsIndexRoute,
+ };
+
+const FestivalsFestivalSlugEditionsEditionSlugSetsRouteWithChildren =
+ FestivalsFestivalSlugEditionsEditionSlugSetsRoute._addFileChildren(
+ FestivalsFestivalSlugEditionsEditionSlugSetsRouteChildren,
+ );
+
+interface FestivalsFestivalSlugEditionsEditionSlugRouteChildren {
+ FestivalsFestivalSlugEditionsEditionSlugExploreRoute: typeof FestivalsFestivalSlugEditionsEditionSlugExploreRoute;
+ FestivalsFestivalSlugEditionsEditionSlugInfoRoute: typeof FestivalsFestivalSlugEditionsEditionSlugInfoRoute;
+ FestivalsFestivalSlugEditionsEditionSlugMapRoute: typeof FestivalsFestivalSlugEditionsEditionSlugMapRoute;
+ FestivalsFestivalSlugEditionsEditionSlugScheduleRoute: typeof FestivalsFestivalSlugEditionsEditionSlugScheduleRouteWithChildren;
+ FestivalsFestivalSlugEditionsEditionSlugSetsRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSetsRouteWithChildren;
+ FestivalsFestivalSlugEditionsEditionSlugSocialRoute: typeof FestivalsFestivalSlugEditionsEditionSlugSocialRoute;
+}
+
+const FestivalsFestivalSlugEditionsEditionSlugRouteChildren: FestivalsFestivalSlugEditionsEditionSlugRouteChildren =
+ {
+ FestivalsFestivalSlugEditionsEditionSlugExploreRoute:
+ FestivalsFestivalSlugEditionsEditionSlugExploreRoute,
+ FestivalsFestivalSlugEditionsEditionSlugInfoRoute:
+ FestivalsFestivalSlugEditionsEditionSlugInfoRoute,
+ FestivalsFestivalSlugEditionsEditionSlugMapRoute:
+ FestivalsFestivalSlugEditionsEditionSlugMapRoute,
+ FestivalsFestivalSlugEditionsEditionSlugScheduleRoute:
+ FestivalsFestivalSlugEditionsEditionSlugScheduleRouteWithChildren,
+ FestivalsFestivalSlugEditionsEditionSlugSetsRoute:
+ FestivalsFestivalSlugEditionsEditionSlugSetsRouteWithChildren,
+ FestivalsFestivalSlugEditionsEditionSlugSocialRoute:
+ FestivalsFestivalSlugEditionsEditionSlugSocialRoute,
+ };
+
+const FestivalsFestivalSlugEditionsEditionSlugRouteWithChildren =
+ FestivalsFestivalSlugEditionsEditionSlugRoute._addFileChildren(
+ FestivalsFestivalSlugEditionsEditionSlugRouteChildren,
+ );
+
+const rootRouteChildren: RootRouteChildren = {
+ IndexRoute: IndexRoute,
+ AdminRoute: AdminRouteWithChildren,
+ CookiesRoute: CookiesRoute,
+ PrivacyRoute: PrivacyRoute,
+ TermsRoute: TermsRoute,
+ GroupsGroupSlugRoute: GroupsGroupSlugRoute,
+ GroupsIndexRoute: GroupsIndexRoute,
+ FestivalsFestivalSlugIndexRoute: FestivalsFestivalSlugIndexRoute,
+ FestivalsFestivalSlugEditionsEditionSlugRoute:
+ FestivalsFestivalSlugEditionsEditionSlugRouteWithChildren,
+};
+export const routeTree = rootRouteImport
+ ._addFileChildren(rootRouteChildren)
+ ._addFileTypes
();
diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx
new file mode 100644
index 00000000..f1d624ae
--- /dev/null
+++ b/src/routes/__root.tsx
@@ -0,0 +1,127 @@
+import {
+ createRootRouteWithContext,
+ Outlet,
+ useSearch,
+} from "@tanstack/react-router";
+import { SpeedInsights } from "@vercel/speed-insights/react";
+import { Toaster } from "@/components/ui/toaster";
+import { Toaster as Sonner } from "@/components/ui/sonner";
+import { TooltipProvider } from "@/components/ui/tooltip";
+import { CookieConsentBanner } from "@/components/layout/legal/CookieConsentBanner";
+import { OfflineIndicator } from "@/components/ui/OfflineIndicator";
+import { AppFooter } from "@/components/layout/AppFooter";
+import { TanStackRouterDevtools } from "@tanstack/router-devtools";
+import { HelmetProvider } from "react-helmet-async";
+import { AuthProvider } from "@/contexts/AuthContext";
+import { FestivalEditionProvider } from "@/contexts/FestivalEditionContext";
+import { useAuth } from "@/contexts/AuthContext";
+import { useInviteValidation } from "@/components/invite/useInviteValidation";
+import { InviteLandingPage } from "@/components/invite/InviteLandingPage";
+import { OnboardingDialog } from "@/components/onboarding/OnboardingDialog";
+import { useProfileQuery } from "@/hooks/queries/auth/useProfile";
+import { useMemo, useEffect } from "react";
+import { shouldRedirectFromWww, getNonWwwRedirectUrl } from "@/lib/subdomain";
+import { z } from "zod";
+import type { QueryClient } from "@tanstack/react-query";
+
+const rootSearchSchema = z.object({
+ invite: z.string().optional(),
+});
+
+interface RouterContext {
+ queryClient: QueryClient;
+}
+
+export const Route = createRootRouteWithContext()({
+ component: RootComponent,
+ validateSearch: rootSearchSchema,
+});
+
+function RootComponent() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {import.meta.env.DEV && }
+
+
+ );
+}
+
+function RootContent() {
+ const { user, loading: authLoading, needsOnboarding } = useAuth();
+ const search = useSearch({ from: "__root__" });
+ const { inviteValidation, isValidating, hasValidInvite } =
+ useInviteValidation(search.invite);
+
+ const { isLoading: profileLoading } = useProfileQuery(user?.id);
+
+ const showOnboarding = useMemo(() => {
+ return !!user && !authLoading && !profileLoading && needsOnboarding;
+ }, [user, authLoading, profileLoading, needsOnboarding]);
+
+ useEffect(() => {
+ if (shouldRedirectFromWww()) {
+ window.location.href = getNonWwwRedirectUrl();
+ }
+ }, []);
+
+ if (isValidating) {
+ return (
+
+ );
+ }
+
+ if (hasValidInvite && !user && inviteValidation) {
+ return (
+ {}}
+ />
+ );
+ }
+
+ if (inviteValidation && !inviteValidation.is_valid) {
+ return (
+
+
+
Invalid Invite
+
This invite link is no longer valid.
+
(window.location.href = "/")}
+ className="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded"
+ >
+ Continue to App
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+ {user && (
+
{}}
+ />
+ )}
+
+ );
+}
diff --git a/src/routes/admin.tsx b/src/routes/admin.tsx
new file mode 100644
index 00000000..79599dbc
--- /dev/null
+++ b/src/routes/admin.tsx
@@ -0,0 +1,14 @@
+import { createFileRoute, redirect } from "@tanstack/react-router";
+import AdminLayout from "@/pages/admin/AdminLayout";
+
+export const Route = createFileRoute("/admin")({
+ component: AdminLayout,
+ beforeLoad: ({ location }) => {
+ if (location.pathname === "/admin" || location.pathname === "/admin/") {
+ throw redirect({
+ to: "/admin/artists",
+ search: location.search,
+ });
+ }
+ },
+});
diff --git a/src/routes/admin/admins.tsx b/src/routes/admin/admins.tsx
new file mode 100644
index 00000000..971af9ea
--- /dev/null
+++ b/src/routes/admin/admins.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { AdminRolesTable } from "@/pages/admin/Roles/AdminRolesTable";
+
+export const Route = createFileRoute("/admin/admins")({
+ component: AdminRolesTable,
+});
diff --git a/src/routes/admin/analytics.tsx b/src/routes/admin/analytics.tsx
new file mode 100644
index 00000000..6a942779
--- /dev/null
+++ b/src/routes/admin/analytics.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import AdminAnalytics from "@/pages/admin/Analytics/AdminAnalytics";
+
+export const Route = createFileRoute("/admin/analytics")({
+ component: AdminAnalytics,
+});
diff --git a/src/routes/admin/artists.tsx b/src/routes/admin/artists.tsx
new file mode 100644
index 00000000..3442a2c1
--- /dev/null
+++ b/src/routes/admin/artists.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { ArtistBulkEditor } from "@/pages/admin/ArtistsManagement/ArtistBulkEditor";
+
+export const Route = createFileRoute("/admin/artists")({
+ component: ArtistBulkEditor,
+});
diff --git a/src/routes/admin/artists/duplicates.tsx b/src/routes/admin/artists/duplicates.tsx
new file mode 100644
index 00000000..e9edf8af
--- /dev/null
+++ b/src/routes/admin/artists/duplicates.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { DuplicateArtistsPage } from "@/pages/admin/ArtistsManagement/DuplicateArtistsPage";
+
+export const Route = createFileRoute("/admin/artists/duplicates")({
+ component: DuplicateArtistsPage,
+});
diff --git a/src/routes/admin/festivals.tsx b/src/routes/admin/festivals.tsx
new file mode 100644
index 00000000..a2c1c642
--- /dev/null
+++ b/src/routes/admin/festivals.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import AdminFestivals from "@/pages/admin/festivals/AdminFestivals";
+
+export const Route = createFileRoute("/admin/festivals")({
+ component: AdminFestivals,
+});
diff --git a/src/routes/admin/festivals/$festivalId.$editionId.import.tsx b/src/routes/admin/festivals/$festivalId.$editionId.import.tsx
new file mode 100644
index 00000000..90715693
--- /dev/null
+++ b/src/routes/admin/festivals/$festivalId.$editionId.import.tsx
@@ -0,0 +1,14 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { z } from "zod";
+import { CSVImportPage } from "@/pages/admin/festivals/CSVImportPage";
+
+const importSearchSchema = z.object({
+ tab: z.enum(["stages", "sets"]).optional(),
+});
+
+export const Route = createFileRoute(
+ "/admin/festivals/$festivalId/$editionId/import",
+)({
+ component: CSVImportPage,
+ validateSearch: importSearchSchema,
+});
diff --git a/src/routes/admin/festivals/$festivalSlug.tsx b/src/routes/admin/festivals/$festivalSlug.tsx
new file mode 100644
index 00000000..001dac62
--- /dev/null
+++ b/src/routes/admin/festivals/$festivalSlug.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import FestivalDetail from "@/pages/admin/festivals/FestivalDetail";
+
+export const Route = createFileRoute("/admin/festivals/$festivalSlug")({
+ component: FestivalDetail,
+});
diff --git a/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug.tsx b/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug.tsx
new file mode 100644
index 00000000..28c69915
--- /dev/null
+++ b/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug.tsx
@@ -0,0 +1,71 @@
+import { createFileRoute, redirect } from "@tanstack/react-router";
+import FestivalEdition from "@/pages/admin/festivals/FestivalEdition";
+import { editionsKeys } from "@/hooks/queries/festivals/editions/types";
+import type { QueryClient } from "@tanstack/react-query";
+
+async function fetchFestivalEditionBySlug({
+ festivalSlug,
+ editionSlug,
+}: {
+ festivalSlug: string;
+ editionSlug: string;
+}) {
+ const { supabase } = await import("@/integrations/supabase/client");
+
+ // First get the festival ID from the slug
+ const { data: festival, error: festivalError } = await supabase
+ .from("festivals")
+ .select("*")
+ .eq("archived", false)
+ .eq("slug", festivalSlug)
+ .single();
+
+ if (festivalError) {
+ throw new Error("Failed to load festival");
+ }
+
+ const { data, error } = await supabase
+ .from("festival_editions")
+ .select("*")
+ .eq("archived", false)
+ .eq("festival_id", festival.id)
+ .eq("slug", editionSlug)
+ .single();
+
+ if (error) {
+ throw new Error("Failed to load festival edition");
+ }
+
+ return data;
+}
+
+export const Route = createFileRoute(
+ "/admin/festivals/$festivalSlug/editions/$editionSlug",
+)({
+ component: FestivalEdition,
+ beforeLoad: async ({ params, location, context }) => {
+ if (params?.editionSlug && location.pathname.endsWith(params.editionSlug)) {
+ throw redirect({
+ to: "/admin/festivals/$festivalSlug/editions/$editionSlug/stages",
+ params,
+ search: location.search as Record,
+ });
+ }
+
+ const queryClient = (context as { queryClient: QueryClient }).queryClient;
+ await queryClient.ensureQueryData({
+ queryKey: editionsKeys.bySlug(params.festivalSlug, params.editionSlug),
+ queryFn: () =>
+ fetchFestivalEditionBySlug({
+ festivalSlug: params.festivalSlug,
+ editionSlug: params.editionSlug,
+ }),
+ });
+
+ return {
+ ...context,
+ festivalSlug: params.festivalSlug,
+ editionSlug: params.editionSlug,
+ };
+ },
+});
diff --git a/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/sets.tsx b/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/sets.tsx
new file mode 100644
index 00000000..64ab930b
--- /dev/null
+++ b/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/sets.tsx
@@ -0,0 +1,8 @@
+import { createFileRoute } from "@tanstack/react-router";
+import FestivalSets from "@/pages/admin/festivals/FestivalSets";
+
+export const Route = createFileRoute(
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/sets",
+)({
+ component: FestivalSets,
+});
diff --git a/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/stages.tsx b/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/stages.tsx
new file mode 100644
index 00000000..f7f0ad5c
--- /dev/null
+++ b/src/routes/admin/festivals/$festivalSlug/editions/$editionSlug/stages.tsx
@@ -0,0 +1,8 @@
+import { createFileRoute } from "@tanstack/react-router";
+import FestivalStages from "@/pages/admin/festivals/FestivalStages";
+
+export const Route = createFileRoute(
+ "/admin/festivals/$festivalSlug/editions/$editionSlug/stages",
+)({
+ component: FestivalStages,
+});
diff --git a/src/routes/admin/festivals/import.tsx b/src/routes/admin/festivals/import.tsx
new file mode 100644
index 00000000..d7071bc0
--- /dev/null
+++ b/src/routes/admin/festivals/import.tsx
@@ -0,0 +1,12 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { CSVImportPage } from "@/pages/admin/festivals/CSVImportPage";
+import { z } from "zod";
+
+const importSearchSchema = z.object({
+ tab: z.enum(["sets", "stages"]).optional(),
+});
+
+export const Route = createFileRoute("/admin/festivals/import")({
+ component: CSVImportPage,
+ validateSearch: importSearchSchema,
+});
diff --git a/src/routes/cookies.tsx b/src/routes/cookies.tsx
new file mode 100644
index 00000000..deb75940
--- /dev/null
+++ b/src/routes/cookies.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import CookiePolicy from "@/pages/legal/CookiePolicy";
+
+export const Route = createFileRoute("/cookies")({
+ component: CookiePolicy,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug.tsx
new file mode 100644
index 00000000..69253782
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug.tsx
@@ -0,0 +1,17 @@
+import { createFileRoute, redirect } from "@tanstack/react-router";
+import EditionLayout from "@/pages/EditionView/EditionLayout";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug",
+)({
+ component: EditionLayout,
+ beforeLoad: ({ params, location }) => {
+ if (params?.editionSlug && location.pathname.endsWith(params.editionSlug)) {
+ throw redirect({
+ to: "/festivals/$festivalSlug/editions/$editionSlug/sets",
+ params,
+ search: location.search as Record,
+ });
+ }
+ },
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/explore.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/explore.tsx
new file mode 100644
index 00000000..c1350468
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/explore.tsx
@@ -0,0 +1,8 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { ExploreSetPage } from "@/pages/ExploreSetPage/ExploreSetPage";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/explore",
+)({
+ component: ExploreSetPage,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/info.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/info.tsx
new file mode 100644
index 00000000..dea13545
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/info.tsx
@@ -0,0 +1,8 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { InfoTab } from "@/pages/EditionView/tabs/InfoTab";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/info",
+)({
+ component: InfoTab,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/map.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/map.tsx
new file mode 100644
index 00000000..0b06ebba
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/map.tsx
@@ -0,0 +1,8 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { MapTab } from "@/pages/EditionView/tabs/MapTab";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/map",
+)({
+ component: MapTab,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule.tsx
new file mode 100644
index 00000000..8d3baf0c
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute, redirect } from "@tanstack/react-router";
+import { ScheduleTab } from "@/pages/EditionView/tabs/ScheduleTab";
+import { filterSortSearchSchema } from "@/lib/searchSchemas";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule",
+)({
+ component: ScheduleTab,
+ validateSearch: filterSortSearchSchema,
+ beforeLoad: ({ params, location }) => {
+ if (location.pathname.endsWith("/schedule")) {
+ throw redirect({
+ to: "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline",
+ params,
+ search: location.search as Record,
+ });
+ }
+ },
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/list.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/list.tsx
new file mode 100644
index 00000000..095f5d61
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/list.tsx
@@ -0,0 +1,10 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { ScheduleTabList } from "@/pages/EditionView/tabs/ScheduleTab/list/ListTab";
+import { timelineSearchSchema } from "@/lib/searchSchemas";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/list",
+)({
+ component: ScheduleTabList,
+ validateSearch: timelineSearchSchema,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline.tsx
new file mode 100644
index 00000000..cfd15d06
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline.tsx
@@ -0,0 +1,10 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { ScheduleTabTimeline } from "@/pages/EditionView/tabs/ScheduleTab/TimelineTab";
+import { timelineSearchSchema } from "@/lib/searchSchemas";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline",
+)({
+ component: ScheduleTabTimeline,
+ validateSearch: timelineSearchSchema,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets.tsx
new file mode 100644
index 00000000..cebaabf0
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets.tsx
@@ -0,0 +1,9 @@
+import { createFileRoute, Outlet } from "@tanstack/react-router";
+import { filterSortSearchSchema } from "@/lib/searchSchemas";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/sets",
+)({
+ component: () => ,
+ validateSearch: filterSortSearchSchema,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug.tsx
new file mode 100644
index 00000000..4f92ec3e
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug.tsx
@@ -0,0 +1,10 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { SetDetails } from "@/pages/SetDetails";
+import { filterSortSearchSchema } from "@/lib/searchSchemas";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/$setSlug",
+)({
+ component: SetDetails,
+ validateSearch: filterSortSearchSchema,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets/index.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets/index.tsx
new file mode 100644
index 00000000..9aa92e30
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/sets/index.tsx
@@ -0,0 +1,10 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { ArtistsTab } from "@/pages/EditionView/tabs/ArtistsTab/ArtistsTab";
+import { filterSortSearchSchema } from "@/lib/searchSchemas";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/sets/",
+)({
+ component: ArtistsTab,
+ validateSearch: filterSortSearchSchema,
+});
diff --git a/src/routes/festivals/$festivalSlug/editions/$editionSlug/social.tsx b/src/routes/festivals/$festivalSlug/editions/$editionSlug/social.tsx
new file mode 100644
index 00000000..6516ca98
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/editions/$editionSlug/social.tsx
@@ -0,0 +1,8 @@
+import { createFileRoute } from "@tanstack/react-router";
+import { SocialTab } from "@/pages/EditionView/tabs/SocialTab";
+
+export const Route = createFileRoute(
+ "/festivals/$festivalSlug/editions/$editionSlug/social",
+)({
+ component: SocialTab,
+});
diff --git a/src/routes/festivals/$festivalSlug/index.tsx b/src/routes/festivals/$festivalSlug/index.tsx
new file mode 100644
index 00000000..229cb57f
--- /dev/null
+++ b/src/routes/festivals/$festivalSlug/index.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import EditionSelection from "@/pages/EditionSelection";
+
+export const Route = createFileRoute("/festivals/$festivalSlug/")({
+ component: EditionSelection,
+});
diff --git a/src/routes/groups/$groupSlug.tsx b/src/routes/groups/$groupSlug.tsx
new file mode 100644
index 00000000..0ba2e6c3
--- /dev/null
+++ b/src/routes/groups/$groupSlug.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import GroupDetail from "@/pages/groups/GroupDetail";
+
+export const Route = createFileRoute("/groups/$groupSlug")({
+ component: GroupDetail,
+});
diff --git a/src/routes/groups/index.tsx b/src/routes/groups/index.tsx
new file mode 100644
index 00000000..1b657ccf
--- /dev/null
+++ b/src/routes/groups/index.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import Groups from "@/pages/groups/Groups";
+
+export const Route = createFileRoute("/groups/")({
+ component: Groups,
+});
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
new file mode 100644
index 00000000..9490df64
--- /dev/null
+++ b/src/routes/index.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import FestivalSelection from "@/pages/FestivalSelection";
+
+export const Route = createFileRoute("/")({
+ component: FestivalSelection,
+});
diff --git a/src/routes/privacy.tsx b/src/routes/privacy.tsx
new file mode 100644
index 00000000..a5e572f9
--- /dev/null
+++ b/src/routes/privacy.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import PrivacyPolicy from "@/pages/legal/PrivacyPolicy";
+
+export const Route = createFileRoute("/privacy")({
+ component: PrivacyPolicy,
+});
diff --git a/src/routes/terms.tsx b/src/routes/terms.tsx
new file mode 100644
index 00000000..97cf3683
--- /dev/null
+++ b/src/routes/terms.tsx
@@ -0,0 +1,6 @@
+import { createFileRoute } from "@tanstack/react-router";
+import TermsOfService from "@/pages/legal/TermsOfService";
+
+export const Route = createFileRoute("/terms")({
+ component: TermsOfService,
+});
diff --git a/vite.config.ts b/vite.config.ts
index 0a0672f2..74be376c 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -2,6 +2,7 @@ import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import path from "path";
import { VitePWA } from "vite-plugin-pwa";
+import { TanStackRouterVite } from "@tanstack/router-vite-plugin";
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
@@ -11,6 +12,7 @@ export default defineConfig(({ mode }) => ({
},
plugins: [
react(),
+ TanStackRouterVite(),
VitePWA({
registerType: "autoUpdate",
devOptions: {