165 lines
4.3 KiB
TypeScript
165 lines
4.3 KiB
TypeScript
import { lazy, Suspense } from "react";
|
|
import {
|
|
Box,
|
|
Button,
|
|
Flex,
|
|
Loader,
|
|
SimpleGrid,
|
|
Stack,
|
|
Text,
|
|
UnstyledButton,
|
|
} from "@mantine/core";
|
|
import { Icon } from "@phosphor-icons/react";
|
|
import {
|
|
ListDashes,
|
|
ListIcon,
|
|
TreeStructureIcon,
|
|
UsersIcon,
|
|
} from "@phosphor-icons/react";
|
|
import { useNavigate } from "@tanstack/react-router";
|
|
import Sheet from "@/components/sheet/sheet";
|
|
import { useSheet } from "@/hooks/use-sheet";
|
|
import TeamList from "@/features/teams/components/team-list";
|
|
import WizardOrbIcon from "@/components/wizard-orb-icon";
|
|
import { Tournament } from "../../../types";
|
|
import classes from "./nav-grid.module.css";
|
|
|
|
const RulesContent = lazy(
|
|
() => import("../../upcoming-tournament/rules-content")
|
|
);
|
|
|
|
interface NavTileProps {
|
|
label: string;
|
|
Icon: Icon;
|
|
onClick: () => void;
|
|
}
|
|
|
|
/** A single square-ish nav tile with icon-over-label and press feedback. */
|
|
const NavTile = ({ label, Icon, onClick }: NavTileProps) => (
|
|
<UnstyledButton className={classes.tile} onClick={onClick}>
|
|
<span className={classes.icon}>
|
|
<Icon size={22} weight="bold" />
|
|
</span>
|
|
<Text size="xs" fw={600} lineClamp={2} lh={1.2}>
|
|
{label}
|
|
</Text>
|
|
</UnstyledButton>
|
|
);
|
|
|
|
interface NavGridProps {
|
|
tournament: Tournament;
|
|
isAdmin: boolean;
|
|
hasGroupStage: boolean;
|
|
isPredictable: boolean;
|
|
predictionsLocked: boolean;
|
|
hasSubmitted: boolean;
|
|
}
|
|
|
|
/**
|
|
* Consolidates the old stack of full-width ListLinks into a compact icon grid
|
|
* so it no longer dominates the page. Every original destination stays
|
|
* reachable with identical conditional visibility. Teams and Rules open sheets;
|
|
* everything else navigates.
|
|
*/
|
|
const NavGrid = ({
|
|
tournament,
|
|
isAdmin,
|
|
hasGroupStage,
|
|
isPredictable,
|
|
predictionsLocked,
|
|
hasSubmitted,
|
|
}: NavGridProps) => {
|
|
const navigate = useNavigate();
|
|
const teamsSheet = useSheet();
|
|
const rulesSheet = useSheet();
|
|
|
|
return (
|
|
<Box px="md">
|
|
<SimpleGrid cols={3} spacing="sm" verticalSpacing="sm">
|
|
{isAdmin && (
|
|
<NavTile
|
|
label="Manage"
|
|
Icon={UsersIcon}
|
|
onClick={() =>
|
|
navigate({ to: `/admin/tournaments/${tournament.id}` })
|
|
}
|
|
/>
|
|
)}
|
|
{hasGroupStage && (
|
|
<NavTile
|
|
label="Groups"
|
|
Icon={ListDashes}
|
|
onClick={() =>
|
|
navigate({ to: `/tournaments/${tournament.id}/groups` })
|
|
}
|
|
/>
|
|
)}
|
|
<NavTile
|
|
label="Bracket"
|
|
Icon={TreeStructureIcon}
|
|
onClick={() =>
|
|
navigate({ to: `/tournaments/${tournament.id}/bracket` })
|
|
}
|
|
/>
|
|
{isPredictable && !predictionsLocked && (
|
|
<NavTile
|
|
label={hasSubmitted ? "Edit Prediction" : "Make Prediction"}
|
|
Icon={WizardOrbIcon}
|
|
onClick={() =>
|
|
navigate({ to: `/tournaments/${tournament.id}/predictions/make` })
|
|
}
|
|
/>
|
|
)}
|
|
{isPredictable && (predictionsLocked || hasSubmitted) && (
|
|
<NavTile
|
|
label="Predictions"
|
|
Icon={WizardOrbIcon}
|
|
onClick={() =>
|
|
navigate({ to: `/tournaments/${tournament.id}/predictions` })
|
|
}
|
|
/>
|
|
)}
|
|
<NavTile
|
|
label={`Teams${
|
|
tournament.teams ? ` (${tournament.teams.length})` : ""
|
|
}`}
|
|
Icon={UsersIcon}
|
|
onClick={teamsSheet.open}
|
|
/>
|
|
<NavTile label="Rules" Icon={ListIcon} onClick={rulesSheet.open} />
|
|
</SimpleGrid>
|
|
|
|
<Sheet title="Enrolled Teams" {...teamsSheet.props}>
|
|
<TeamList
|
|
teams={tournament.teams || []}
|
|
isRegional={tournament.regional}
|
|
/>
|
|
</Sheet>
|
|
|
|
<Sheet title="Tournament Rules" {...rulesSheet.props}>
|
|
<Stack gap="xs">
|
|
<Suspense
|
|
fallback={
|
|
<Flex
|
|
justify="center"
|
|
align="center"
|
|
w="100%"
|
|
style={{ minHeight: "25vh" }}
|
|
>
|
|
<Loader size="lg" />
|
|
</Flex>
|
|
}
|
|
>
|
|
<RulesContent content={tournament.rules || ""} />
|
|
</Suspense>
|
|
<Button variant="subtle" c="red" onClick={rulesSheet.close}>
|
|
Close
|
|
</Button>
|
|
</Stack>
|
|
</Sheet>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default NavGrid;
|