import { HeadContent, Navigate, Outlet, Scripts, createRootRouteWithContext, } from "@tanstack/react-router"; import * as React from "react"; import { DefaultCatchBoundary } from "@/components/DefaultCatchBoundary"; import { type QueryClient } from "@tanstack/react-query"; import { ensureSuperTokensFrontend } from "@/lib/supertokens/client"; import { AuthContextType } from "@/contexts/auth-context"; import Providers from "@/features/core/components/providers"; import { SessionMonitor } from "@/components/session-monitor"; import { IOSInstallPrompt } from "@/components/ios-install-prompt"; import { ColorSchemeScript, mantineHtmlProps } from "@mantine/core"; import { HeaderConfig } from "@/features/core/types/header-config"; import { playerQueries } from "@/features/players/queries"; import { ensureServerQueryData } from "@/lib/tanstack-query/utils/ensure"; import FullScreenLoader from "@/components/full-screen-loader"; import mantineCssUrl from '@mantine/core/styles.css?url' import mantineDatesCssUrl from '@mantine/dates/styles.css?url' import mantineCarouselCssUrl from '@mantine/carousel/styles.css?url' import mantineTiptapCssUrl from '@mantine/tiptap/styles.css?url' export const Route = createRootRouteWithContext<{ queryClient: QueryClient; auth: AuthContextType; header: HeaderConfig; refresh: string[]; withPadding: boolean; fullWidth: boolean; }>()({ head: () => ({ title: "FLXN IX", meta: [ { charSet: "utf-8", }, { name: "viewport", content: "width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, interactive-widget=resizes-content", }, { name: 'description', content: 'Amicus meus madidus' }, { name: 'keywords', content: 'FLXN, beer pong, tournament, sports, statistics, pong' }, { name: 'theme-color', content: '#1e293b' }, { property: 'og:title', content: 'FLXN' }, { property: 'og:description', content: 'Amicus meus madidus' }, { property: 'og:url', content: 'https://flexxon.app' }, { property: 'og:type', content: 'website' }, { property: 'og:site_name', content: 'FLXN' }, { property: 'og:image', content: 'https://flexxon.app/favicon.png' }, { property: 'og:image:width', content: '512' }, { property: 'og:image:height', content: '512' }, { property: 'og:image:alt', content: 'FLXN logo' }, { property: 'og:locale', content: 'en_US' }, { name: 'twitter:card', content: 'summary' }, { name: 'twitter:title', content: 'FLXN' }, { name: 'twitter:description', content: 'Amicus meus madidus' }, { name: 'twitter:image', content: 'https://flexxon.app/favicon.png' }, { name: 'mobile-web-app-capable', content: 'yes' }, { name: 'apple-mobile-web-app-capable', content: 'yes' }, { name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent' }, { name: 'apple-mobile-web-app-title', content: 'FLXN' }, ], links: [ { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png", }, { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicon-32x32.png", }, { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicon-16x16.png", }, { rel: "manifest", href: "/site.webmanifest" }, { rel: "icon", href: "/favicon.ico" }, { rel: 'stylesheet', href: mantineCssUrl }, { rel: 'stylesheet', href: mantineCarouselCssUrl }, { rel: 'stylesheet', href: mantineDatesCssUrl }, { rel: 'stylesheet', href: mantineTiptapCssUrl }, { rel: "preconnect", href: "https://fonts.googleapis.com" }, { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "anonymous", }, { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=League+Spartan:wght@100..900&display=swap", } ], }), errorComponent: (props) => { return ( ); }, component: RootComponent, notFoundComponent: () => , beforeLoad: async ({ context, location }) => { const publicRoutes = ['/login', '/logout', '/refresh-session']; if (publicRoutes.some(route => location.pathname.startsWith(route))) { return {}; } try { const auth = await ensureServerQueryData( context.queryClient, playerQueries.auth() ); console.log('__root beforeLoad auth data:', auth); return { auth }; } catch (error: any) { if (error?.options?.to && error?.options?.statusCode) { console.log('__root beforeLoad: Re-throwing redirect', error.options); throw error; } console.error('__root beforeLoad error:', error); return {}; } }, pendingComponent: () => , }); function RootComponent() { React.useEffect(() => { ensureSuperTokensFrontend(); }, []); return ( ); } // todo: analytics -> process.env data-website-id function RootDocument({ children }: { children: React.ReactNode }) { return (
{children}
); }