upcoming tournament page, minor changes
This commit is contained in:
57
src/components/countdown.tsx
Normal file
57
src/components/countdown.tsx
Normal 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;
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user