various improvements, edit tournament, etc
This commit is contained in:
@@ -4,11 +4,12 @@ import {
|
||||
useMatch,
|
||||
useRouter,
|
||||
useNavigate,
|
||||
redirect,
|
||||
} from '@tanstack/react-router'
|
||||
import type { ErrorComponentProps } from '@tanstack/react-router'
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Button as MantineButton,
|
||||
Text,
|
||||
Title,
|
||||
Stack,
|
||||
@@ -23,6 +24,7 @@ import { useEffect } from 'react'
|
||||
import toast from '@/lib/sonner'
|
||||
import { logger } from '@/lib/logger'
|
||||
import { ExclamationMarkIcon, XCircleIcon } from '@phosphor-icons/react'
|
||||
import Button from './button'
|
||||
|
||||
export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
|
||||
const router = useRouter()
|
||||
@@ -41,8 +43,8 @@ export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
|
||||
|
||||
if (errorMessage.toLowerCase().includes('unauthenticated')) {
|
||||
toast.error('You\'ve been logged out')
|
||||
navigate({ to: '/login' })
|
||||
return
|
||||
router.history.push('/login')
|
||||
throw redirect({ to: '/login' })
|
||||
}
|
||||
}, [error, errorMessage, navigate])
|
||||
|
||||
@@ -73,13 +75,13 @@ export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
|
||||
>
|
||||
Go Back
|
||||
</Button>
|
||||
<Button
|
||||
<MantineButton
|
||||
component={Link}
|
||||
to="/"
|
||||
variant="filled"
|
||||
>
|
||||
Home
|
||||
</Button>
|
||||
</MantineButton>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
@@ -137,13 +139,13 @@ export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
|
||||
Try Again
|
||||
</Button>
|
||||
{isRoot ? (
|
||||
<Button
|
||||
<MantineButton
|
||||
component={Link}
|
||||
to="/"
|
||||
variant="filled"
|
||||
>
|
||||
Home
|
||||
</Button>
|
||||
</MantineButton>
|
||||
) : (
|
||||
<Button
|
||||
variant="filled"
|
||||
|
||||
@@ -4,11 +4,14 @@ interface AvatarProps extends Omit<MantineAvatarProps, 'radius' | 'color' | 'siz
|
||||
name: string;
|
||||
size?: number;
|
||||
radius?: string | number;
|
||||
withBorder?: boolean;
|
||||
}
|
||||
|
||||
const Avatar = ({ name, size = 35, radius = '100%', ...props }: AvatarProps) => {
|
||||
return <Paper p={size / 20} radius={radius} withBorder>
|
||||
<MantineAvatar alt={name} key={name} name={name} color='initials' size={size} radius={radius} {...props} />
|
||||
const Avatar = ({ name, size = 35, radius = '100%', withBorder = true, ...props }: AvatarProps) => {
|
||||
return <Paper p={size / 20} radius={radius} withBorder={withBorder}>
|
||||
<MantineAvatar alt={name} key={name} name={name} color='initials' size={size} radius={radius} w='fit-content' styles={{ image: {
|
||||
objectFit: 'contain'
|
||||
} }} {...props} />
|
||||
</Paper>
|
||||
}
|
||||
|
||||
|
||||
11
src/components/button.tsx
Normal file
11
src/components/button.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Button as MantineButton, ButtonProps as MantineButtonProps } from '@mantine/core';
|
||||
import { forwardRef, ComponentPropsWithoutRef } from 'react';
|
||||
|
||||
type ButtonProps = MantineButtonProps & ComponentPropsWithoutRef<'button'>;
|
||||
|
||||
const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
|
||||
return <MantineButton fullWidth ref={ref} {...props} />;
|
||||
});
|
||||
|
||||
Button.displayName = 'Button';
|
||||
export default Button;
|
||||
78
src/components/date-input.tsx
Normal file
78
src/components/date-input.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import { TextInput, Flex, Box, Button } from "@mantine/core";
|
||||
import { CalendarIcon } from "@phosphor-icons/react";
|
||||
import { useSheet } from "@/hooks/use-sheet";
|
||||
import Sheet from "@/components/sheet/sheet";
|
||||
import { DateTimePicker } from "../features/admin/components/date-time-picker";
|
||||
|
||||
interface DateInputProps {
|
||||
label: string;
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
withAsterisk?: boolean;
|
||||
error?: React.ReactNode;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
// Date input that opens a sheet with mantine date time picker when clicked
|
||||
export const DateInputSheet = ({
|
||||
label,
|
||||
value,
|
||||
onChange,
|
||||
withAsterisk,
|
||||
error,
|
||||
placeholder
|
||||
}: DateInputProps) => {
|
||||
const sheet = useSheet();
|
||||
|
||||
const formatDisplayValue = (dateString: string) => {
|
||||
if (!dateString) return '';
|
||||
const date = new Date(dateString);
|
||||
if (isNaN(date.getTime())) return '';
|
||||
return date.toLocaleDateString('en-US', {
|
||||
weekday: 'short',
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hour12: true
|
||||
});
|
||||
};
|
||||
|
||||
const handleDateChange = (newValue: string | null) => {
|
||||
onChange(newValue || '');
|
||||
sheet.close();
|
||||
};
|
||||
|
||||
const dateValue = value ? new Date(value) : null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextInput
|
||||
label={label}
|
||||
value={formatDisplayValue(value)}
|
||||
onClick={sheet.open}
|
||||
readOnly
|
||||
withAsterisk={withAsterisk}
|
||||
error={error}
|
||||
placeholder={placeholder || "Click to select date"}
|
||||
rightSection={<CalendarIcon size={16} />}
|
||||
style={{ cursor: 'pointer' }}
|
||||
/>
|
||||
|
||||
<Sheet {...sheet.props} title={`Select ${label}`}>
|
||||
<Flex gap='xs' direction='column' justify='center' p="md">
|
||||
<Box mx='auto'>
|
||||
<DateTimePicker
|
||||
value={dateValue}
|
||||
onChange={handleDateChange}
|
||||
/>
|
||||
</Box>
|
||||
<Button onClick={sheet.close} variant="subtle">
|
||||
Close
|
||||
</Button>
|
||||
</Flex>
|
||||
</Sheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
import { AuthProvider } from "@/contexts/auth-context"
|
||||
import MantineProvider from "@/lib/mantine/mantine-provider"
|
||||
import { Toaster } from "sonner"
|
||||
|
||||
const Providers = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<AuthProvider>
|
||||
<MantineProvider>
|
||||
<Toaster position='top-center' />
|
||||
{children}
|
||||
</MantineProvider>
|
||||
</AuthProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default Providers;
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Box, Text, Group, ActionIcon, Button, ScrollArea, Divider } from "@mantine/core";
|
||||
import { Box, Text, Group, ActionIcon, ScrollArea, Divider } from "@mantine/core";
|
||||
import { ArrowLeftIcon, CheckIcon } from "@phosphor-icons/react";
|
||||
import { useState, ReactNode} from "react";
|
||||
import { SlidePanelContext, type PanelConfig } from "./slide-panel-context";
|
||||
import Button from "@/components/button";
|
||||
|
||||
interface SlidePanelProps {
|
||||
children: ReactNode;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FloatingIndicator, UnstyledButton, Box, Text } from "@mantine/core";
|
||||
import { FloatingIndicator, UnstyledButton, Box, Text, ScrollArea } from "@mantine/core";
|
||||
import { Carousel } from "@mantine/carousel";
|
||||
import { useState, useEffect, ReactNode } from "react";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user