upcoming tournament page, minor changes

This commit is contained in:
yohlo
2025-09-09 23:20:19 -05:00
parent c5d69f1a19
commit c74da09bde
29 changed files with 1125 additions and 46 deletions

View File

@@ -0,0 +1,57 @@
import useNow from '@/hooks/use-now';
import { Text, Group } from '@mantine/core';
import { useMemo } from 'react';
interface CountdownProps {
date: Date;
label?: string;
color?: string;
}
interface TimeLeft {
days: number;
hours: number;
minutes: number;
seconds: number;
}
function calculateTimeLeft(targetDate: Date, currentTime = new Date()): TimeLeft {
const difference = targetDate.getTime() - currentTime.getTime();
if (difference <= 0) {
return { days: 0, hours: 0, minutes: 0, seconds: 0 };
}
return {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60)
};
}
export function Countdown({ date, label, color }: CountdownProps) {
const now = useNow();
const timeLeft = useMemo(() => calculateTimeLeft(date, now), [date, now]);
const formatTime = () => {
const pad = (num: number) => num.toString().padStart(2, '0');
if (timeLeft.days > 0) {
return `${timeLeft.days}d ${pad(timeLeft.hours)}:${pad(timeLeft.minutes)}:${pad(timeLeft.seconds)}`;
} else {
return `${pad(timeLeft.hours)}:${pad(timeLeft.minutes)}:${pad(timeLeft.seconds)}`;
}
};
return (
<Group gap="xs">
{label && <Text size='sm' fw={500}>{label}:</Text>}
<Text size='sm' fw={600} c={color} ff="monospace">
{formatTime()}
</Text>
</Group>
);
}
export default Countdown;

View File

@@ -1,8 +1,8 @@
import { Box, Container, useComputedColorScheme } from "@mantine/core";
import { PropsWithChildren, useEffect } from "react";
import { Box, Container, Flex, Loader, useComputedColorScheme } from "@mantine/core";
import { PropsWithChildren, Suspense, useEffect } from "react";
import { Drawer as VaulDrawer } from "vaul";
import { useMantineColorScheme } from "@mantine/core";
import styles from "./styles.module.css";
import FullScreenLoader from "../full-screen-loader";
interface DrawerProps extends PropsWithChildren {
title?: string;
@@ -76,7 +76,13 @@ const Drawer: React.FC<DrawerProps> = ({
/>
<Container mah="fit-content" mx="auto" maw="28rem" px={0}>
<VaulDrawer.Title>{title}</VaulDrawer.Title>
{children}
<Suspense fallback={
<Flex justify='center' align='center' w='100%' h={400}>
<Loader size='lg' />
</Flex>
}>
{children}
</Suspense>
</Container>
</Container>
</VaulDrawer.Content>

View File

@@ -1,5 +1,5 @@
import { Modal as MantineModal, Title } from "@mantine/core";
import { PropsWithChildren } from "react";
import { Flex, Loader, Modal as MantineModal, Title } from "@mantine/core";
import { PropsWithChildren, Suspense } from "react";
interface ModalProps extends PropsWithChildren {
title?: string;
@@ -13,7 +13,15 @@ const Modal: React.FC<ModalProps> = ({ title, children, opened, onClose }) => (
onClose={onClose}
title={<Title order={3}>{title}</Title>}
>
{children}
<Suspense
fallback={
<Flex justify="center" align="center" w="100%" h={400}>
<Loader size="lg" />
</Flex>
}
>
{children}
</Suspense>
</MantineModal>
);

View File

@@ -17,6 +17,7 @@ interface SlidePanelProps {
onCancel?: () => void;
submitText?: string;
cancelText?: string;
cancelColor?: string;
maxHeight?: string;
formProps?: Record<string, any>;
loading?: boolean;
@@ -28,6 +29,7 @@ const SlidePanel = ({
onCancel,
submitText = "Submit",
cancelText = "Cancel",
cancelColor = "red",
maxHeight = "70vh",
formProps = {},
loading = false,
@@ -114,7 +116,7 @@ const SlidePanel = ({
{onCancel && (
<Button
variant="subtle"
color="red"
color={cancelColor}
fullWidth
onClick={onCancel}
type="button"