rules, bracket page

This commit is contained in:
yohlo
2025-09-18 18:17:56 -05:00
parent 285a33c488
commit 602e6e3473
15 changed files with 273 additions and 24 deletions

View File

@@ -36,7 +36,7 @@ const MatchCard = ({ match }: MatchCardProps) => {
color="red"
processing
position="top-end"
offset={2}
offset={24}
>
<Box style={{ position: "relative" }}>
<Paper

View File

@@ -0,0 +1,14 @@
import { Flex, Skeleton } from "@mantine/core";
const HeaderSkeleton = () => {
return (
<Flex h="10vh" px='xl' w='100%' align='self-end' gap='md'>
<Skeleton opacity={0} height={100} width={100} radius="50%" />
<Flex align='center' justify='center' gap={4} pb={20} w='100%'>
<Skeleton height={24} width={200} />
</Flex>
</Flex>
);
};
export default HeaderSkeleton;

View File

@@ -33,7 +33,7 @@ const Header = ({ player }: HeaderProps) => {
return (
<>
<Flex px='xl' w='100%' align='self-end' gap='md'>
<Flex h="10vh" px='xl' w='100%' align='self-end' gap='md'>
<Avatar name={name} size={100} />
<Flex align='center' justify='center' gap={4} pb={20} w='100%'>
<Title ta='center' style={{ fontSize, lineHeight: 1.2 }}>{name}</Title>

View File

@@ -0,0 +1,42 @@
import { Box, Flex, Loader } from "@mantine/core";
import Header from "./header";
import SwipeableTabs from "@/components/swipeable-tabs";
import { usePlayer, usePlayerMatches, usePlayerStats } from "../../queries";
import TeamList from "@/features/teams/components/team-list";
import StatsOverview from "@/shared/components/stats-overview";
import MatchList from "@/features/matches/components/match-list";
import HeaderSkeleton from "./header-skeleton";
const SkeletonLoader = () => (
<Flex h="30vh" w="100%" align="center" justify="center">
<Loader />
</Flex>
)
const ProfileSkeleton = () => {
const tabs = [
{
label: "Overview",
content: <SkeletonLoader />,
},
{
label: "Matches",
content: <SkeletonLoader />,
},
{
label: "Teams",
content: <SkeletonLoader />,
},
];
return (
<>
<HeaderSkeleton />
<Box mt="lg">
<SwipeableTabs tabs={tabs} />
</Box>
</>
);
};
export default ProfileSkeleton;

View File

@@ -87,9 +87,9 @@ const TeamForm = ({
const form = useForm(config);
const queryClient = useQueryClient();
const { mutate: createTournament, isPending: createPending } =
const { mutate: createTeam, isPending: createPending } =
useCreateTeam();
const { mutate: updateTournament, isPending: updatePending } = useUpdateTeam(
const { mutate: updateTeam, isPending: updatePending } = useUpdateTeam(
teamId!
);
@@ -99,7 +99,7 @@ const TeamForm = ({
async (values: TeamInput) => {
const { logo, ...teamData } = values;
const mutation = isEditMode ? updateTournament : createTournament;
const mutation = isEditMode ? updateTeam : createTeam;
const errorMessage = isEditMode
? "Failed to update team"
: "Failed to create team";
@@ -156,7 +156,7 @@ const TeamForm = ({
},
});
},
[isEditMode, createTournament, updateTournament, queryClient]
[isEditMode, createTeam, updateTeam, queryClient]
);
return (

View File

@@ -0,0 +1,44 @@
import {
Stack,
Button
} from "@mantine/core";
import { useState, useCallback } from "react";
import { useTournament } from "../queries";
import useUpdateTournament from "../hooks/use-update-tournament";
import { RichTextEditor } from "@/components/rich-text-editor";
interface EditRulesProps {
tournamentId: string;
onClose?: () => void
}
const EditRules = ({ tournamentId, onClose }: EditRulesProps) => {
const [search, setSearch] = useState("");
const { data: tournament, isLoading: tournamentLoading } =
useTournament(tournamentId);
const { mutate: updateTournament, isPending: updatePending } = useUpdateTournament(tournamentId);
const [value, setValue] = useState(tournament.rules);
const handleSubmit = useCallback(
(rules?: string) => {
updateTournament({ rules }, {
onSuccess: () => {
onClose?.();
}
});
},
[updateTournament, tournamentId]
);
return (
<Stack gap="xs" w="100%">
<RichTextEditor value={value || ""} onChange={setValue} />
<Button onClick={() => handleSubmit(value)}>Submit</Button>
<Button variant="subtle" color="red" onClick={onClose}>Cancel</Button>
</Stack>
);
};
export default EditRules;

View File

@@ -14,6 +14,7 @@ import EditEnrolledTeams from "./edit-enrolled-teams";
import ListLink from "@/components/list-link";
import { RichTextEditor } from "@/components/rich-text-editor";
import React from "react";
import EditRules from "./edit-rules";
interface ManageTournamentProps {
tournamentId: string;
@@ -90,9 +91,7 @@ const ManageTournament = ({ tournamentId }: ManageTournamentProps) => {
opened={editRulesOpened}
onChange={closeEditRules}
>
<RichTextEditor value={v} onChange={setV} />
{v}
<EditRules tournamentId={tournamentId} onClose={closeEditRules} />
</Sheet>
<Sheet

View File

@@ -5,7 +5,7 @@ import { Box, Button, Card, Divider, Group, Stack, Text } from "@mantine/core";
import Countdown from "@/components/countdown";
import ListLink from "@/components/list-link";
import ListButton from "@/components/list-button";
import { UsersIcon, ListIcon } from "@phosphor-icons/react";
import { TreeStructureIcon, UsersIcon } from "@phosphor-icons/react";
import EnrollTeam from "./enroll-team";
import EnrollFreeAgent from "./enroll-free-agent";
import TeamListButton from "./team-list-button";
@@ -16,6 +16,7 @@ import UpdateTeam from "./update-team";
import UnenrollTeam from "./unenroll-team";
import { useQueryClient } from "@tanstack/react-query";
import { tournamentKeys } from "../../queries";
import RulesListButton from "./rules-list-button";
const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
tournament,
@@ -42,8 +43,6 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
queryClient.invalidateQueries({ queryKey: tournamentKeys.current })
}
console.log(userTeam)
return (
<Stack gap="lg">
<Header tournament={tournament} />
@@ -102,7 +101,12 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
Icon={UsersIcon}
/>
)}
<ListButton label="View Rules" Icon={ListIcon} onClick={() => {}} />
<ListLink
label={`View Bracket`}
to={`/tournaments/${tournament.id}/bracket`}
Icon={TreeStructureIcon}
/>
<RulesListButton tournamentId={tournament.id} />
<TeamListButton teams={tournament.teams || []} />
</Box>
</Stack>

View File

@@ -0,0 +1,45 @@
import ListButton from "@/components/list-button"
import Sheet from "@/components/sheet/sheet"
import { useSheet } from "@/hooks/use-sheet"
import { ListIcon } from "@phosphor-icons/react"
import { useTournament } from "../../queries"
import { useEditor } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import { RichTextEditor } from '@mantine/tiptap';
import { Button, Stack } from "@mantine/core"
interface RulesListButtonProps {
tournamentId: string;
}
const RulesListButton: React.FC<RulesListButtonProps> = ({ tournamentId }) => {
const { data: tournament } = useTournament(tournamentId);
const { open, isOpen, toggle } = useSheet();
const editor = useEditor({
extensions: [StarterKit],
content: tournament?.rules || '',
editable: false,
});
return (
<>
<ListButton
label={`View Rules`}
Icon={ListIcon}
onClick={open}
/>
<Sheet title="Tournament Rules" opened={isOpen} onChange={toggle}>
<Stack gap="xs">
<RichTextEditor editor={editor}>
<RichTextEditor.Content />
</RichTextEditor>
<Button variant="subtle" c="red" onClick={toggle}>Close</Button>
</Stack>
</Sheet>
</>
)
}
export default RulesListButton;