fixed create form

This commit is contained in:
Shaheed Azaad
2025-07-14 00:53:24 +02:00
parent cde21e9286
commit e3c27b304f

View File

@@ -1,14 +1,15 @@
<script lang="ts"> <script lang="ts">
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card'; import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card';
import * as Form from '$lib/components/ui/form';
import { Input } from '$lib/components/ui/input'; import { Input } from '$lib/components/ui/input';
import { Checkbox } from '$lib/components/ui/checkbox'; import { Checkbox } from '$lib/components/ui/checkbox';
import * as Select from '$lib/components/ui/select/index.js'; import * as Select from '$lib/components/ui/select/index.js'; // the import should stay as index.js
import { superForm } from 'sveltekit-superforms'; import { superForm, type SuperValidated, type Infer } from 'sveltekit-superforms';
import { zod } from 'sveltekit-superforms/adapters'; import { zod } from 'sveltekit-superforms/adapters';
import { z } from 'zod'; import { z } from 'zod';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { Label } from '$lib/components/ui/label';
import { Button } from '$lib/components/ui/button';
const formSchema = z.object({ const formSchema = z.object({
name: z.string().min(1, 'Name is required'), name: z.string().min(1, 'Name is required'),
@@ -19,35 +20,36 @@
}) })
}); });
const form = superForm( const form = superForm({
{ name: '',
name: '', description: '',
description: '', multiplayer: false,
multiplayer: false, type: ''
type: 'jsPsych' }, {
}, validators: zod(formSchema),
{ SPA: true,
validators: zod(formSchema), onUpdate: async ({ form: f }) => {
SPA: true, if (f.valid) {
onUpdate: async ({ form: f }) => { const res = await fetch('/api/experiment', {
if (f.valid) { method: 'POST',
const res = await fetch('/api/experiment', { headers: { 'Content-Type': 'application/json' },
method: 'POST', body: JSON.stringify(f.data)
headers: { 'Content-Type': 'application/json' }, });
body: JSON.stringify(f.data) if (res.ok) {
}); await goto('/');
if (res.ok) { toast.success('Experiment created successfully');
await goto('/'); } else {
toast.success('Experiment created successfully'); const data = await res.json().catch(() => ({}));
} else { toast.error(data?.error || 'Failed to create experiment');
const data = await res.json().catch(() => ({}));
toast.error(data?.error || 'Failed to create experiment');
}
} }
} }
} }
});
const { form: formData, enhance, errors } = form;
const triggerContent = $derived(
$formData.type ? $formData.type : 'Select a type'
); );
const { form: formData, enhance } = form;
</script> </script>
<div class="flex justify-center items-center min-h-screen bg-background"> <div class="flex justify-center items-center min-h-screen bg-background">
@@ -57,45 +59,34 @@
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<form method="POST" use:enhance class="space-y-4"> <form method="POST" use:enhance class="space-y-4">
<Form.Field {form} name="name"> <div class="space-y-2">
<Form.Control let:attrs> <Label for="name">Name</Label>
<Form.Label>Name</Form.Label> <Input name="name" bind:value={$formData.name} />
<Input {...attrs} bind:value={$formData.name} /> {#if $errors.name}<span class="text-red-500 text-sm">{$errors.name[0]}</span>{/if}
</Form.Control> </div>
<Form.FieldErrors /> <div class="space-y-2">
</Form.Field> <Label for="description">Description</Label>
<Form.Field {form} name="description"> <Input name="description" bind:value={$formData.description} />
<Form.Control let:attrs> {#if $errors.description}<span class="text-red-500 text-sm">{$errors.description[0]}</span>{/if}
<Form.Label>Description</Form.Label> </div>
<Input {...attrs} bind:value={$formData.description} /> <div class="flex items-center space-x-2">
</Form.Control> <Checkbox name="multiplayer" bind:checked={$formData.multiplayer} />
<Form.FieldErrors /> <Label for="multiplayer">Multiplayer</Label>
</Form.Field> </div>
<Form.Field {form} name="multiplayer"> <div class="space-y-2">
<Form.Control let:attrs> <Label for="type">Type</Label>
<div class="flex items-center space-x-2"> <Select.Root type="single" bind:value={$formData.type} name="type">
<Checkbox {...attrs} bind:checked={$formData.multiplayer} /> <Select.Trigger class="w-full" name="type">
<Form.Label>Multiplayer</Form.Label> {triggerContent}
</div> </Select.Trigger>
</Form.Control> <Select.Content>
<Form.FieldErrors /> <Select.Item value="jsPsych">jsPsych</Select.Item>
</Form.Field> <Select.Item value="PsychoJS">PsychoJS</Select.Item>
<Form.Field {form} name="type"> </Select.Content>
<Form.Control let:attrs> </Select.Root>
<Form.Label>Type</Form.Label> {#if $errors.type}<span class="text-red-500 text-sm">{$errors.type[0]}</span>{/if}
<Select.Root {...attrs} bind:value={$formData.type} type="single"> </div>
<Select.Trigger> <Button type="submit" class="w-full">Create</Button>
{$formData.type || 'Select a type'}
</Select.Trigger>
<Select.Content>
<Select.Item value="jsPsych">jsPsych</Select.Item>
<Select.Item value="PsychoJS">PsychoJS</Select.Item>
</Select.Content>
</Select.Root>
</Form.Control>
<Form.FieldErrors />
</Form.Field>
<Form.Button class="w-full">Create</Form.Button>
</form> </form>
</CardContent> </CardContent>
</Card> </Card>