diff --git a/package.json b/package.json
index 206ab80..004e239 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"bits-ui": "^2.8.6",
"clsx": "^2.1.1",
"drizzle-kit": "^0.30.2",
+ "formsnap": "^2.0.1",
"mode-watcher": "^1.1.0",
"oxlint": "^1.5.0",
"prettier": "^3.4.2",
@@ -38,6 +39,7 @@
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"svelte-sonner": "^1.0.5",
+ "sveltekit-superforms": "^2.26.1",
"tailwind-merge": "^3.3.1",
"tailwind-variants": "^1.0.0",
"tailwindcss": "^4.0.0",
diff --git a/src/app.d.ts b/src/app.d.ts
index b4153f3..651c570 100644
--- a/src/app.d.ts
+++ b/src/app.d.ts
@@ -30,3 +30,11 @@ export interface NavItem {
isActive?: boolean;
requireAdmin?: boolean;
}
+
+export enum SchedulingMode {
+ single = 'signle',
+ double = 'double',
+ swiss = 'swiss',
+ round_robin = 'round_robin',
+ double_round_robin = 'double_round_robin'
+}
diff --git a/src/lib/components/app-layout.svelte b/src/lib/components/app-layout.svelte
index 6bfecb7..acacb84 100644
--- a/src/lib/components/app-layout.svelte
+++ b/src/lib/components/app-layout.svelte
@@ -9,7 +9,7 @@
import { cn } from '$lib/utils';
import { getContext } from 'svelte';
import Nav from '$lib/components/nav.svelte';
- import type { User } from '@/server/db/schema/users';
+ import type { User } from '$lib/server/db/schema/users';
let {
breadcrumbs,
diff --git a/src/lib/components/nav.svelte b/src/lib/components/nav.svelte
index 08d034c..359dd7f 100644
--- a/src/lib/components/nav.svelte
+++ b/src/lib/components/nav.svelte
@@ -4,8 +4,8 @@
import { Button } from '$lib/components/ui/button';
import type { NavItem } from '../../app';
import { Home, Trophy, Calendar, UserCircle, Settings } from 'lucide-svelte';
- import type { User } from '@/server/db/schema/users';
- import { type Role } from '@/server/db/schema/roles';
+ import type { User } from '$lib/server/db/schema/users';
+ import { type Role } from '$lib/server/db/schema/roles';
import { page } from '$app/state';
let { className }: { className?: string } = $props();
diff --git a/src/lib/components/rounds/create-round.svelte b/src/lib/components/rounds/create-round.svelte
new file mode 100644
index 0000000..2e9b5f9
--- /dev/null
+++ b/src/lib/components/rounds/create-round.svelte
@@ -0,0 +1,41 @@
+
+
+
diff --git a/src/lib/components/rounds/create-schema.ts b/src/lib/components/rounds/create-schema.ts
new file mode 100644
index 0000000..89b1b97
--- /dev/null
+++ b/src/lib/components/rounds/create-schema.ts
@@ -0,0 +1,7 @@
+import z from 'zod';
+
+export const formSchema = z.object({
+ scheduling_mode: z.nativeEnum(SchedulingMode)
+});
+
+export type FormSchema = typeof formSchema;
diff --git a/src/lib/components/rounds/rounds.svelte b/src/lib/components/rounds/rounds.svelte
new file mode 100644
index 0000000..d7eb96d
--- /dev/null
+++ b/src/lib/components/rounds/rounds.svelte
@@ -0,0 +1,10 @@
+
+
+{JSON.stringify(rounds)}
+
+
+
diff --git a/src/lib/components/ui/form/form-button.svelte b/src/lib/components/ui/form/form-button.svelte
new file mode 100644
index 0000000..cc0c590
--- /dev/null
+++ b/src/lib/components/ui/form/form-button.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/form/form-description.svelte b/src/lib/components/ui/form/form-description.svelte
new file mode 100644
index 0000000..a5f42be
--- /dev/null
+++ b/src/lib/components/ui/form/form-description.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/form/form-element-field.svelte b/src/lib/components/ui/form/form-element-field.svelte
new file mode 100644
index 0000000..c3ba111
--- /dev/null
+++ b/src/lib/components/ui/form/form-element-field.svelte
@@ -0,0 +1,24 @@
+
+
+
+ {#snippet children({ constraints, errors, tainted, value })}
+
+ {@render childrenProp?.({ constraints, errors, tainted, value: value as T[U] })}
+
+ {/snippet}
+
diff --git a/src/lib/components/ui/form/form-field-errors.svelte b/src/lib/components/ui/form/form-field-errors.svelte
new file mode 100644
index 0000000..b4c6fba
--- /dev/null
+++ b/src/lib/components/ui/form/form-field-errors.svelte
@@ -0,0 +1,30 @@
+
+
+
+ {#snippet children({ errors, errorProps })}
+ {#if childrenProp}
+ {@render childrenProp({ errors, errorProps })}
+ {:else}
+ {#each errors as error (error)}
+ {error}
+ {/each}
+ {/if}
+ {/snippet}
+
diff --git a/src/lib/components/ui/form/form-field.svelte b/src/lib/components/ui/form/form-field.svelte
new file mode 100644
index 0000000..7481fda
--- /dev/null
+++ b/src/lib/components/ui/form/form-field.svelte
@@ -0,0 +1,29 @@
+
+
+
+ {#snippet children({ constraints, errors, tainted, value })}
+
+ {@render childrenProp?.({ constraints, errors, tainted, value: value as T[U] })}
+
+ {/snippet}
+
diff --git a/src/lib/components/ui/form/form-fieldset.svelte b/src/lib/components/ui/form/form-fieldset.svelte
new file mode 100644
index 0000000..2c85857
--- /dev/null
+++ b/src/lib/components/ui/form/form-fieldset.svelte
@@ -0,0 +1,15 @@
+
+
+
diff --git a/src/lib/components/ui/form/form-label.svelte b/src/lib/components/ui/form/form-label.svelte
new file mode 100644
index 0000000..8749360
--- /dev/null
+++ b/src/lib/components/ui/form/form-label.svelte
@@ -0,0 +1,24 @@
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
diff --git a/src/lib/components/ui/form/form-legend.svelte b/src/lib/components/ui/form/form-legend.svelte
new file mode 100644
index 0000000..9d52f6a
--- /dev/null
+++ b/src/lib/components/ui/form/form-legend.svelte
@@ -0,0 +1,16 @@
+
+
+
diff --git a/src/lib/components/ui/form/index.ts b/src/lib/components/ui/form/index.ts
new file mode 100644
index 0000000..0713927
--- /dev/null
+++ b/src/lib/components/ui/form/index.ts
@@ -0,0 +1,33 @@
+import * as FormPrimitive from "formsnap";
+import Description from "./form-description.svelte";
+import Label from "./form-label.svelte";
+import FieldErrors from "./form-field-errors.svelte";
+import Field from "./form-field.svelte";
+import Fieldset from "./form-fieldset.svelte";
+import Legend from "./form-legend.svelte";
+import ElementField from "./form-element-field.svelte";
+import Button from "./form-button.svelte";
+
+const Control = FormPrimitive.Control;
+
+export {
+ Field,
+ Control,
+ Label,
+ Button,
+ FieldErrors,
+ Description,
+ Fieldset,
+ Legend,
+ ElementField,
+ //
+ Field as FormField,
+ Control as FormControl,
+ Description as FormDescription,
+ Label as FormLabel,
+ FieldErrors as FormFieldErrors,
+ Fieldset as FormFieldset,
+ Legend as FormLegend,
+ ElementField as FormElementField,
+ Button as FormButton,
+};
diff --git a/src/lib/components/ui/radio-group/index.ts b/src/lib/components/ui/radio-group/index.ts
new file mode 100644
index 0000000..90b33fe
--- /dev/null
+++ b/src/lib/components/ui/radio-group/index.ts
@@ -0,0 +1,10 @@
+import Root from "./radio-group.svelte";
+import Item from "./radio-group-item.svelte";
+
+export {
+ Root,
+ Item,
+ //
+ Root as RadioGroup,
+ Item as RadioGroupItem,
+};
diff --git a/src/lib/components/ui/radio-group/radio-group-item.svelte b/src/lib/components/ui/radio-group/radio-group-item.svelte
new file mode 100644
index 0000000..2cb0710
--- /dev/null
+++ b/src/lib/components/ui/radio-group/radio-group-item.svelte
@@ -0,0 +1,31 @@
+
+
+
+ {#snippet children({ checked })}
+
+ {#if checked}
+
+ {/if}
+
+ {/snippet}
+
diff --git a/src/lib/components/ui/radio-group/radio-group.svelte b/src/lib/components/ui/radio-group/radio-group.svelte
new file mode 100644
index 0000000..da2912b
--- /dev/null
+++ b/src/lib/components/ui/radio-group/radio-group.svelte
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 7521dc2..7a39ed9 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -3,7 +3,7 @@
import '../app.css';
import { setContext } from 'svelte';
import type { PageProps } from './$types';
- import { Toaster } from '@/components/ui/sonner';
+ import { Toaster } from '$lib/components/ui/sonner';
let {
children,
diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts
index 13de5ea..a148c75 100644
--- a/src/routes/+page.server.ts
+++ b/src/routes/+page.server.ts
@@ -1,4 +1,4 @@
-import { getCompetitionsWithAll } from '@/server/db/schema/competitions';
+import { getCompetitionsWithAll } from '$lib/server/db/schema/competitions';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals }) => {
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 39fb630..896d7ad 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -16,7 +16,7 @@
import { Skeleton } from '$lib/components/ui/skeleton';
import type { PageProps } from './$types.js';
import { toast } from 'svelte-sonner';
- import { formatDate } from '@/utils';
+ import { formatDate } from '$lib/utils';
const breadcrumbs: BreadcrumbItem[] = [
{
diff --git a/src/routes/competitions/[id]/+page.server.ts b/src/routes/competitions/[id]/+page.server.ts
index d69b36b..937ae67 100644
--- a/src/routes/competitions/[id]/+page.server.ts
+++ b/src/routes/competitions/[id]/+page.server.ts
@@ -1,10 +1,13 @@
-import { db } from '@/server/db';
+import { db } from '$lib/server/db';
import type { Actions, PageServerLoad } from './$types';
-import { competitions, getCompetitionWithAll } from '@/server/db/schema/competitions';
+import { competitions, getCompetitionWithAll } from '$lib/server/db/schema/competitions';
import { error, redirect } from '@sveltejs/kit';
import { eq } from 'drizzle-orm';
import { and } from 'drizzle-orm';
-import { teams } from '@/server/db/schema/teams';
+import { teams } from '$lib/server/db/schema/teams';
+import { superValidate } from 'sveltekit-superforms';
+import { zod } from 'sveltekit-superforms/adapters';
+import { formSchema } from '$lib/components/rounds/create-schema';
export const load: PageServerLoad = async ({ params, locals }) => {
try {
@@ -21,7 +24,8 @@ export const load: PageServerLoad = async ({ params, locals }) => {
}
return {
- competition: competition
+ competition: competition,
+ createForm: await superValidate(zod(formSchema))
};
} catch (e) {
return redirect(302, '/');
diff --git a/src/routes/competitions/[id]/+page.svelte b/src/routes/competitions/[id]/+page.svelte
index 9838361..e68dfcb 100644
--- a/src/routes/competitions/[id]/+page.svelte
+++ b/src/routes/competitions/[id]/+page.svelte
@@ -1,21 +1,22 @@