From 3be2284da93be811f442b6bcd205f0b4ddc87243 Mon Sep 17 00:00:00 2001 From: yohlo Date: Sat, 13 Sep 2025 14:59:02 -0500 Subject: [PATCH] wip tournament list --- src/components/avatar.tsx | 2 +- .../components/tournament-card.tsx | 108 +++++++------ .../components/tournament-list.tsx | 149 +++++++++++++++--- 3 files changed, 183 insertions(+), 76 deletions(-) diff --git a/src/components/avatar.tsx b/src/components/avatar.tsx index 34186b8..39588a8 100644 --- a/src/components/avatar.tsx +++ b/src/components/avatar.tsx @@ -28,7 +28,7 @@ const Avatar = ({ color="initials" size={size} radius={radius} - w="fit-content" + w={size} styles={{ image: { objectFit: "contain", diff --git a/src/features/tournaments/components/tournament-card.tsx b/src/features/tournaments/components/tournament-card.tsx index 8bd1133..529b36f 100644 --- a/src/features/tournaments/components/tournament-card.tsx +++ b/src/features/tournaments/components/tournament-card.tsx @@ -1,8 +1,10 @@ -import { Badge, Card, Text, Image, Stack, Flex } from "@mantine/core"; +import { Badge, Card, Text, Stack, Group, Box, ThemeIcon } from "@mantine/core"; import { Tournament } from "@/features/tournaments/types"; import { useMemo } from "react"; -import { CaretRightIcon } from "@phosphor-icons/react"; +import { TrophyIcon, CalendarIcon, MapPinIcon, UsersIcon } from "@phosphor-icons/react"; import { useNavigate } from "@tanstack/react-router"; +import Avatar from "@/components/avatar"; +import { motion } from "framer-motion"; interface TournamentCardProps { tournament: Tournament; @@ -10,64 +12,68 @@ interface TournamentCardProps { export const TournamentCard = ({ tournament }: TournamentCardProps) => { const navigate = useNavigate(); + const displayDate = useMemo(() => { if (!tournament.start_time) return null; const date = new Date(tournament.start_time); if (isNaN(date.getTime())) return null; - return date.toLocaleDateString("en-US", { - year: "numeric", - month: "long", - day: "numeric", + return date.toLocaleDateString(undefined, { + month: 'short', + day: 'numeric', + year: 'numeric' }); }, [tournament.start_time]); + const enrollmentDeadline = tournament.enroll_time + ? new Date(tournament.enroll_time) + : new Date(tournament.start_time); + const isEnrollmentOpen = enrollmentDeadline > new Date(); + const enrolledTeamsCount = tournament.teams?.length || 0; + return ( - navigate({ to: `/tournaments/${tournament.id}` })} + - - - {tournament.name} - - - {tournament.name} + navigate({ to: `/tournaments/${tournament.id}` })} + onMouseEnter={(e) => { + e.currentTarget.style.boxShadow = "var(--mantine-shadow-md)"; + }} + onMouseLeave={(e) => { + e.currentTarget.style.boxShadow = "none"; + }} + > + + + + + + + + {tournament.name} - {displayDate && ( - - {displayDate} - - )} - - {/* TODO: Add medalists when data is available */} - - Longer Team Name Goes Here - - - Some Team - - - Medium Team Name - - - - - - + + + + ); }; diff --git a/src/features/tournaments/components/tournament-list.tsx b/src/features/tournaments/components/tournament-list.tsx index e7d6009..c32111d 100644 --- a/src/features/tournaments/components/tournament-list.tsx +++ b/src/features/tournaments/components/tournament-list.tsx @@ -1,8 +1,10 @@ -import { List, ListItem, Skeleton, Text } from "@mantine/core"; +import { Stack, Skeleton, Text, Group, Box, ThemeIcon } from "@mantine/core"; import { useNavigate } from "@tanstack/react-router"; import Avatar from "@/components/avatar"; import { TournamentInfo } from "../types"; import { useCallback } from "react"; +import { motion } from "framer-motion"; +import { TrophyIcon, CalendarIcon, MapPinIcon } from "@phosphor-icons/react"; interface TournamentListProps { tournaments: TournamentInfo[]; @@ -12,31 +14,130 @@ interface TournamentListProps { const TournamentList = ({ tournaments, loading = false }: TournamentListProps) => { const navigate = useNavigate(); - const handleClick = useCallback((tournamentId: string) => + const handleClick = useCallback((tournamentId: string) => navigate({ to: `/tournaments/${tournamentId}` }), [navigate]); - - if (loading) return - {Array.from({ length: 10 }).map((_, i) => ( - } - > - - - ))} - - return - {tournaments?.map((tournament) => ( - } - style={{ cursor: 'pointer' }} - onClick={() => handleClick(tournament.id)} - > - {`${tournament.name}`} - - ))} - + if (loading) { + return ( + + {Array.from({ length: 6 }).map((_, i) => ( + + + + + + + + + + + ))} + + ); + } + + if (!tournaments?.length) { + return ( + + + + + + No tournaments found + + + ); + } + + return ( + + {tournaments.map((tournament, index) => { + const startDate = tournament.start_time ? new Date(tournament.start_time) : null; + + return ( + + handleClick(tournament.id)} + onMouseEnter={(e) => { + e.currentTarget.style.backgroundColor = "var(--mantine-color-gray-0)"; + e.currentTarget.style.borderColor = "var(--mantine-primary-color-filled)"; + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = "transparent"; + e.currentTarget.style.borderColor = "var(--mantine-color-gray-3)"; + }} + > + + + + + + + + {tournament.name} + + + + {tournament.location && ( + + + + + + {tournament.location} + + + )} + + {startDate && !isNaN(startDate.getTime()) && ( + + + + + + {startDate.toLocaleDateString(undefined, { + month: 'short', + day: 'numeric', + year: 'numeric' + })} + + + )} + + + + + + ); + })} + + ); } export default TournamentList;