social overhaul
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user