import { Component, useEffect, useState, type ErrorInfo, type ReactElement, type ReactNode } from "react";
import { NavLink, Navigate, Route, Routes, useLocation } from "react-router-dom";
import { WalkupProvider, useWalkupContext } from "./hooks/useWalkupContext";
import { useSession } from "./hooks/useSession";
import { DashboardPage } from "./pages/DashboardPage";
import { GamePage } from "./pages/GamePage";
import { LibraryPage } from "./pages/LibraryPage";
import { OperatorPage } from "./pages/OperatorPage";
import { ProfilePage } from "./pages/ProfilePage";
import { AdminPage } from "./pages/AdminPage";
import { SignInPage } from "./pages/SignInPage";
import { formatTeamLabel } from "./lib/teamsnapHelpers";
function getRouteDestinationLabel(pathname: string) {
switch (pathname) {
case "/":
return "your dashboard";
case "/library":
return "walkup clips";
case "/games":
return "game clips";
case "/operator":
return "the operator console";
default:
return "this page";
}
}
function ProtectedRoute({ children }: { children: ReactElement }) {
const location = useLocation();
const { data, isLoading } = useSession();
if (isLoading) {
return (
);
}
if (!data?.authenticated) {
return ;
}
return children;
}
function HomeRoute() {
const walkup = useWalkupContext();
if (walkup.sessionQuery.isLoading) {
return (
);
}
if (!walkup.sessionQuery.data?.authenticated) {
return ;
}
return (
);
}
function SignInRoute() {
const walkup = useWalkupContext();
if (walkup.sessionQuery.isLoading) {
return (
);
}
if (walkup.sessionQuery.data?.authenticated) {
return ;
}
return ;
}
function TeamSelectionRoute({ children }: { children: ReactElement }) {
return children;
}
function TeamSelectionModal() {
const location = useLocation();
const walkup = useWalkupContext();
if (!walkup.isTeamSnap || !walkup.teamsQuery.isFetched || walkup.hasSelectedTeam) {
return null;
}
return (
Step 2 of 2
Pick the team you want to use.
You are signed in with TeamSnap. Choose a team to continue to {getRouteDestinationLabel(location.pathname)}.
Available teams
{walkup.teamsQuery.isLoading ? (
Loading teams...
) : (
{walkup.teamsQuery.data?.map((team) => {
const teamId = String(team.id);
const selected = teamId === walkup.selectedTeamId;
return (
);
})}
{!walkup.teamsQuery.data?.length ? (
No teams were returned for this account.
) : null}
)}
What happens next
1. Sign in with TeamSnap.
2. Choose the team you want to manage.
3. Continue into the dashboard, walkup clips, or game tools.
);
}
class AppErrorBoundary extends Component<{ children: ReactNode }, { errorMessage: string | null }> {
state = { errorMessage: null };
static getDerivedStateFromError(error: unknown) {
return {
errorMessage: error instanceof Error ? error.message : "Unexpected render error",
};
}
componentDidCatch(error: unknown, errorInfo: ErrorInfo) {
console.error("Walkup render error", error, errorInfo);
}
render() {
if (this.state.errorMessage) {
return (
App Error
{this.state.errorMessage}
);
}
return this.props.children;
}
}
function ShellLayout() {
const [navOpen, setNavOpen] = useState(false);
const walkup = useWalkupContext();
const location = useLocation();
const showNavbar = walkup.sessionQuery.data?.authenticated === true;
const showTeamSelectionModal = walkup.isTeamSnap && walkup.teamsQuery.isFetched && !walkup.hasSelectedTeam;
const shellClassName = showNavbar ? "shell is-authenticated" : "shell is-authless";
useEffect(() => {
setNavOpen(false);
}, [location.pathname]);
useEffect(() => {
if (!showTeamSelectionModal) {
return;
}
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
return () => {
document.body.style.overflow = previousOverflow;
};
}, [showTeamSelectionModal]);
return (
{showNavbar ? (
) : null}
} />
} />
} />
} />
} />
} />
} />
{showTeamSelectionModal ?
: null}
);
}
export default function App() {
return (
);
}