Create stages from template

This commit is contained in:
Erik Vroon
2025-05-11 18:11:01 +02:00
parent 00323a8e84
commit 2dd15df4d9
3 changed files with 163 additions and 16 deletions

View File

@@ -0,0 +1,35 @@
.socialLink {
padding: 1rem;
border-radius: 1rem;
text-align: center;
font-size: 30px;
font-weight: bold;
text-decoration: none;
display: block;
border: 3px solid #333;
}
.socialLink:hover {
border: 3px solid #8545c7;
}
.title {
font-family:
Greycliff CF,
var(--mantine-font-family);
text-align: center;
font-weight: 900;
font-size: rem(38px);
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
@media (max-width: $mantine-breakpoint-sm) {
font-size: rem(32px);
}
}
.description {
max-width: rem(1000px);
margin: auto;
margin-top: var(--mantine-spacing-xl);
margin-bottom: calc(var(--mantine-spacing-xl) * 1.5);
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
}

View File

@@ -1,4 +1,17 @@
import { Button } from '@mantine/core';
import {
Button,
Card,
Center,
Container, Divider,
Flex,
Grid,
Group,
Image,
Stack,
Text,
Title,
UnstyledButton
} from '@mantine/core';
import { GoPlus } from '@react-icons/all-files/go/GoPlus';
import { useTranslation } from 'next-i18next';
import React from 'react';
@@ -6,6 +19,8 @@ import { SWRResponse } from 'swr';
import { Tournament } from '../../interfaces/tournament';
import { createStage } from '../../services/stage';
import {Translator} from "../utils/types";
import classes from './create_stage.module.css';
export default function CreateStageButton({
tournament,
@@ -49,18 +64,114 @@ export function CreateStageButtonLarge({
const { t } = useTranslation();
return (
<Button
variant="outline"
color="green"
size="lg"
style={{ marginRight: 10 }}
onClick={async () => {
await createStage(tournament.id);
await swrStagesResponse.mutate();
}}
leftSection={<GoPlus size={24} />}
>
{t('add_stage_button')}
</Button>
<>
<Title mt="2rem" className={classes.title}>{t('no_matches_title')}</Title>
<Text size="lg" ta="center" className={classes.description} inherit>
{t('no_matches_description')}
</Text>
<CreateStagesFromTemplateButtons t={t}/>
</>
);
}
function StageSelectCard({
title,
descriptions,
images,
onClick,
}: {
title: string;
descriptions: string[];
images: string[];
onClick: () => void;
}) {
const image_components = images.map((image) => (<Image src={image} fit="scale-down"></Image>));
const description_components = descriptions.map((description) => (<>{description}<br/></>));
return (
<UnstyledButton onClick={onClick} w="100%">
<Card
shadow="sm"
padding="lg"
radius="lg"
h="22rem"
withBorder
className={classes.socialLink}
>
<Card.Section style={{ backgroundColor: '#dde' }}>
<Flex direction="horizontal" justify="center" h={200} style={{ padding: '1.75rem' }}>
{image_components}
</Flex>
</Card.Section>
<Text fw={800} size="xl" mt="md" lineClamp={1} >
{title}
</Text>
<Text mt="xs" c="dimmed" size="md" lineClamp={3}>
{description_components}
</Text>
</Card>
</UnstyledButton>
);
}
export function CreateStagesFromTemplateButtons({
t,
}: {
t: Translator;
}) {
return (
<>
<Title>1 Stage</Title>
<Grid maw="80rem">
<Grid.Col span={{ base: 12, xl: 4, md: 6 }}>
<StageSelectCard
title={t('round_robin_label')}
descriptions={[t('round_robin_description')]}
images={["/icons/group-stage-item.svg"]}
onClick={() => {
}}
/>
</Grid.Col>
<Grid.Col span={{ base: 12, xl: 4, md: 6 }}>
<StageSelectCard
title={t('single_elimination_label')}
descriptions={[t('single_elimination_description')]}
images={["/icons/single-elimination-stage-item.svg"]}
onClick={() => {
}}
/>
</Grid.Col>
<Grid.Col span={{ base: 12, xl: 4, md: 6 }}>
<StageSelectCard
title={t('swiss_label')}
descriptions={[t('swiss_description')]}
images={["/icons/swiss-stage-item.svg"]}
onClick={() => {
}}
/>
</Grid.Col>
</Grid>
<Title>2 Stages</Title>
<Grid maw="80rem">
<Grid.Col span={{ base: 12, lg: 6 }}>
<StageSelectCard
title={t('round_robin_label') + ' + ' + t('single_elimination_label')}
descriptions={[t('round_robin_label') + ': ' + t('round_robin_description'), t('single_elimination_label') + ': ' + t('single_elimination_description')]}
images={["/icons/group-stage-item.svg", "/icons/single-elimination-stage-item.svg"]}
onClick={() => {
}}
/>
</Grid.Col>
<Grid.Col span={{ base: 12, lg: 6 }}>
<StageSelectCard
title={t('round_robin_label') + ' + ' + t('swiss_label')}
descriptions={[t('round_robin_label') + ': ' + t('round_robin_description'), t('single_elimination_label') + ': ' + t('single_elimination_description')]}
images={["/icons/group-stage-item.svg", "/icons/swiss-stage-item.svg"]}
onClick={() => {
}}
/>
</Grid.Col>
</Grid></>
);
}

View File

@@ -1,4 +1,4 @@
import { Group, Stack } from '@mantine/core';
import {Container, Group, Stack, Text, Title} from '@mantine/core';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import React from 'react';
@@ -20,6 +20,8 @@ import {
getTournamentById,
} from '../../../../services/adapter';
import TournamentLayout from '../../_tournament_layout';
import classes from "../../../../components/no_content/empty_table_info.module.css";
import {HiMiniWrenchScrewdriver} from "react-icons/hi2";
export default function StagesPage() {
const { t } = useTranslation();
@@ -47,7 +49,6 @@ export default function StagesPage() {
} else if (stages.length < 1) {
content = (
<Stack align="center">
<NoContent title={t('no_matches_title')} description={t('no_matches_description')} />
<CreateStageButtonLarge
tournament={tournamentDataFull}
swrStagesResponse={swrStagesResponse}