create rounds

This commit is contained in:
unurled 2025-07-07 19:22:26 +00:00
parent 4430dc0293
commit 592da87c26
No known key found for this signature in database
GPG key ID: 63B897371792D3D8
7 changed files with 73 additions and 39 deletions

View file

@ -1,41 +1,61 @@
<script lang="ts"> <script lang="ts">
import { superForm, type Infer, type SuperValidated } from 'sveltekit-superforms'; import { FormControl } from '$ui/form';
import { FormControl } from '../ui/form'; import FormDescription from '$ui/form/form-description.svelte';
import FormDescription from '../ui/form/form-description.svelte'; import FormFieldErrors from '$ui/form/form-field-errors.svelte';
import FormFieldErrors from '../ui/form/form-field-errors.svelte'; import FormField from '$ui/form/form-field.svelte';
import FormField from '../ui/form/form-field.svelte'; import FormLabel from '$ui/form/form-label.svelte';
import FormLabel from '../ui/form/form-label.svelte'; import RadioGroup from '$ui/radio-group/radio-group.svelte';
import { formSchema, type FormSchema } from './create-schema'; import RadioGroupItem from '$ui/radio-group/radio-group-item.svelte';
import { zodClient } from 'sveltekit-superforms/adapters';
import RadioGroup from '../ui/radio-group/radio-group.svelte';
import RadioGroupItem from '../ui/radio-group/radio-group-item.svelte';
import { SchedulingMode } from '@/types'; import { SchedulingMode } from '@/types';
import { cn } from '@/lib/utils';
import Label from '$ui/label/label.svelte';
import Card from '$ui/card/card.svelte';
import CardContent from '$ui/card/card-content.svelte';
import CardHeader from '$ui/card/card-header.svelte';
import { _ } from 'svelte-i18n';
import Button from '$ui/button/button.svelte';
import { ArrowRightIcon } from 'lucide-svelte';
let { data }: { data: { form: SuperValidated<Infer<FormSchema>> } } = $props(); let { competitionId }: { competitionId: number } = $props();
const form = superForm(data.form, { let schedulingMode: SchedulingMode = $state(SchedulingMode.single);
validators: zodClient(formSchema)
});
const { form: formData, enhance } = form; async function submit() {
const response = await fetch(`/api/competitions/${competitionId}`, {
method: 'POST',
credentials: 'include',
body: JSON.stringify({ scheduling_mode: schedulingMode })
});
}
</script> </script>
<form method="post" use:enhance> <div class="flex flex-col gap-4">
<FormField {form} name="scheduling_mode"> <RadioGroup
<RadioGroup required bind:value={$formData.scheduling_mode} name="scheduling_mode"> required
{#each Object.values(SchedulingMode) as mode} bind:value={() => schedulingMode, (t: SchedulingMode) => {}}
<div class="flex items-center gap-4"> name="scheduling_mode"
<FormControl> >
{#snippet children({ props })} {#each Object.values(SchedulingMode) as mode}
<RadioGroupItem value={mode} {...props} /> <button
<FormLabel>{mode}</FormLabel> class={cn(
{/snippet} 'flex h-full w-full items-center gap-4 rounded-xl border',
</FormControl> schedulingMode === mode && ' border-green-500'
</div> )}
{/each} onclick={() => (schedulingMode = mode)}
</RadioGroup> >
<Card class="w-full">
<FormDescription /> <CardHeader class="flex justify-between">
<FormFieldErrors /> <Label class="text-start">{$_(mode)}</Label>
</FormField> </CardHeader>
</form> <CardContent>
<RadioGroupItem hidden value={mode} />
<Label class="text-start">{$_(`${mode}.description`)}</Label>
</CardContent>
</Card>
</button>
{/each}
</RadioGroup>
<div class="flex w-full justify-end">
<Button onclick={submit}>Add Round<ArrowRightIcon /></Button>
</div>
</div>

View file

@ -4,7 +4,4 @@
let { rounds, createForm } = $props(); let { rounds, createForm } = $props();
</script> </script>
{JSON.stringify(rounds)}
<div></div>
<CreateRound data={{ form: createForm }} /> <CreateRound data={{ form: createForm }} />

View file

@ -0,0 +1,12 @@
{
"single": "Single",
"single.description": "In a single elimination format, a participant is eliminated after one loss. The last undefeated player is the winner.",
"double": "Double",
"double.description": "In a double elimination format, a participant must lose twice before being eliminated. It includes a winners bracket and a losers bracket.",
"swiss": "Swiss",
"swiss.description": "The Swiss system pairs players with similar win records over a fixed number of rounds. No one is eliminated, and standings are based on overall performance.",
"round_robin": "Round Robin",
"round_robin.description": "In a round robin format, each participant plays against every other participant once. Rankings are determined by total wins or points.",
"double_round_robin": "Double Round Robin",
"double_round_robin.description": "A double round robin has each participant play every other twice—once at 'home' and once 'away'. It provides a balanced and fair comparison across all competitors."
}

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1,3 @@
import type { RequestHandler } from '../../../competitions/[id]/$types';
export const POST: RequestHandler = () => {};

View file

@ -14,7 +14,7 @@ export interface NavItem {
} }
export enum SchedulingMode { export enum SchedulingMode {
single = 'signle', single = 'single',
double = 'double', double = 'double',
swiss = 'swiss', swiss = 'swiss',
round_robin = 'round_robin', round_robin = 'round_robin',

View file

@ -9,7 +9,8 @@ const config = {
kit: { kit: {
adapter: adapter(), adapter: adapter(),
alias: { alias: {
'@/*': './src/*' '@/*': './src/*',
'$ui/*': './src/lib/components/ui/*'
} }
} }
}; };