Working Prototype for Create

This commit is contained in:
2025-03-19 13:27:10 +01:00
parent 0b71434fc5
commit 8caa23d716
7 changed files with 194 additions and 102 deletions

View File

@@ -36,7 +36,8 @@
"vite": "^6.0.0"
},
"dependencies": {
"@inlang/paraglide-sveltekit": "^0.15.5"
"@inlang/paraglide-sveltekit": "^0.15.5",
"lodash": "^4.17.21"
},
"pnpm": {
"onlyBuiltDependencies": [

8
pnpm-lock.yaml generated
View File

@@ -11,6 +11,9 @@ importers:
'@inlang/paraglide-sveltekit':
specifier: ^0.15.5
version: 0.15.5(@sveltejs/kit@2.20.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.23.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.23.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)))
lodash:
specifier: ^4.17.21
version: 4.17.21
devDependencies:
'@eslint/compat':
specifier: ^1.2.5
@@ -1561,6 +1564,9 @@ packages:
lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
@@ -3582,6 +3588,8 @@ snapshots:
lodash.once@4.1.1: {}
lodash@4.17.21: {}
magic-string@0.30.17:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0

35
src/lib/FormInput.svelte Normal file
View File

@@ -0,0 +1,35 @@
<script lang="ts" generics="T extends Record<string, unknown>">
import { Field, Control, FieldErrors } from "formsnap";
import type { FormPath, SuperForm } from "sveltekit-superforms";
let { form, type, label, name }: {
form: SuperForm<T>,
type: string,
label: string,
name: FormPath<T>,
} = $props();
const formData = form.form;
</script>
<div>
<Field {form} {name}>
<Control>
{#snippet children({ props })}
<label class="label floating-label w-full">
<span>{label}</span>
<input {type} class="input w-full aria-[invalid]:input-error" placeholder={label}
bind:value={$formData[name]} {...props}
/>
</label>
{/snippet}
</Control>
<FieldErrors>
{#snippet children({ errors, errorProps })}
{#each errors as err, idx (idx)}
<p class="text-error" {...errorProps}>{err}</p>
{/each}
{/snippet}
</FieldErrors>
</Field>
</div>

View File

@@ -9,7 +9,7 @@ export const actions = {
username: data.get('username'),
password: data.get('password')
};
//"/api/public/1/auth/login/"
const response = await event.fetch("/api/public/1/auth/login/", {
method: 'POST',
body: JSON.stringify(payload),

View File

@@ -1,7 +1,7 @@
import type { Actions } from './$types';
import { superValidate } from 'sveltekit-superforms';
import { arktype } from 'sveltekit-superforms/adapters';
import { message } from 'sveltekit-superforms';
import { fail } from '@sveltejs/kit';
import { schema, defaults } from './schema';
export const load = async () => {
@@ -13,21 +13,50 @@ export const load = async () => {
};
export const actions = {
default: async ({ request }) => {
default: async ({ request, fetch }) => {
const form = await superValidate(request, arktype(schema, { defaults }));
console.log(form);
if (!form.valid) {
// Return { form } and things will just work.
return fail(400, { form });
// return fail(400, { form });
return message(form, {
status: 'error',
text: 'Invalid Form'
});
}
// TODO: Do something with the validated form.data
// Create User
const payload = {
username: form.data.username,
email: form.data.email,
password: form.data.password,
features: {},
};
const response = await fetch("/api/internal/current/users/", {
method: "POST",
body: JSON.stringify(payload),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
if (response.status >= 500) {
console.error(`INTERNAL SERVER ERROR ${response.status}:\n${await response.text()}`);
return message(form, {
status: 'error',
text: `Internal Server Error ${response.status}`
});
}
if (response.status !== 201) return message(form, {
status: 'error',
text: `HTTP Code ${response.status}:\n${JSON.stringify(await response.json(), null, 2)}`
}, { status: 400 });
// Return the form with a status message
return message(form, {
status: 'success',
text: 'Form posted successfully!',
text: `Form posted successfully!\n${JSON.stringify(await response.json(), null, 2)}`,
});
}
};
} satisfies Actions;

View File

@@ -1,107 +1,126 @@
<script lang="ts">
import { superForm } from 'sveltekit-superforms';
import { arktypeClient } from 'sveltekit-superforms/adapters';
import { Field, Control, FieldErrors } from "formsnap";
import PwdFormInput from "$lib/PwdFormInput.svelte";
import { schema } from './schema';
import FormInput from "$lib/FormInput.svelte";
let { data } = $props();
const { form, errors, constraints, message, enhance } = superForm(data.form, {
const form = superForm(data.form, {
validators: arktypeClient(schema),
resetForm: false,
});
const { form: formData, errors, constraints, message, enhance } = form;
</script>
<div class="mx-auto w-sm">
<!-- TODO: Do the new Form using https://www.formsnap.dev/docs/quick-start -->
<form class="fieldset mt-4 bg-base-200 border border-base-300 p-4 rounded-box gap-4" method="POST" use:enhance>
<h1 class="card-title">Create User</h1>
<div>
<label class="label floating-label w-full">
<span>Username</span>
<input type="text" class={["input w-full", $errors['username'] && 'input-error']}
placeholder="Username" name="username"
aria-invalid={$errors['username'] ? 'true' : undefined}
bind:value={$form.username}
{...$constraints.username}
/>
</label>
<p class="text-error">{$errors['username'] ?? ''}</p>
</div>
<div>
<label class="label floating-label w-full">
<span>Email</span>
<input type="email" class={["input w-full", $errors['email'] && 'input-error']} placeholder="Email"
name="email"
aria-invalid={$errors['email'] ? 'true' : undefined}
bind:value={$form.email}
{...$constraints.email}
/>
</label>
<p class="text-error">{$errors['email'] ?? ''}</p>
</div>
<div>
<PwdFormInput label="Password" autocomplete="new-password" name="password"
class={$errors['password'] && 'input-error'}
aria-invalid={$errors['password'] ? 'true' : undefined}
bind:value={$form.password}
{...$constraints.password}
/>
<p class="text-error">{$errors['password'] ?? ''}</p>
</div>
<div>
<PwdFormInput label="Re-insert password" autocomplete="new-password" name="confirmPassword"
class={$errors['confirmPassword'] && 'input-error'}
aria-invalid={$errors['confirmPassword'] ? 'true' : undefined}
bind:value={$form.confirmPassword}
{...$constraints.confirmPassword}
/>
<p class="text-error">{$errors['confirmPassword'] ?? ''}</p>
</div>
<label class="label">
<span>RossiniEnergy Staff</span>
<input type="checkbox" class="checkbox"/>
</label>
<button class="btn btn-primary">SUBMIT</button>
{#if $message}
<div
class:success={$message['status'] === 'success'}
class:error={$message['status'] === 'error'}
>
{$message['text']}
<div>
<div class="mx-auto w-sm">
<!-- TODO: Do the new Form using https://www.formsnap.dev/docs/quick-start -->
<form class="fieldset mt-4 bg-base-200 border border-base-300 p-4 rounded-box gap-4" method="POST" use:enhance>
<h1 class="card-title">Create User</h1>
<div>
<Field {form} name="username">
<Control>
{#snippet children({ props })}
<label class="label floating-label w-full">
<span>Username</span>
<input type="text" class="input w-full aria-[invalid]:input-error" placeholder="Username"
bind:value={$formData.username} {...props}
/>
</label>
{/snippet}
</Control>
<FieldErrors>
{#snippet children({ errors, errorProps })}
{#each errors as err, idx (idx)}
<p class="text-error" {...errorProps}>{err}</p>
{/each}
{/snippet}
</FieldErrors>
</Field>
</div>
{/if}
<!-- <fieldset class="fieldset w-sm bg-base-200 border border-base-300 p-4 rounded-box gap-4">-->
<!-- <legend class="fieldset-legend">Park Admin Feature</legend>-->
<!-- <label class="label">-->
<!-- <span>Enable</span>-->
<!-- <input type="checkbox" class="checkbox"/>-->
<!-- </label>-->
<!-- <div class="fieldset gap-4">-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label">-->
<!-- <span>Username</span>-->
<!-- <input type="checkbox" class="checkbox" placeholder="Username"/>-->
<!-- </label>-->
<!-- </div>-->
<!-- </fieldset>-->
</form>
<div>
<FormInput {form} type="email" label="Email" name="email"/>
<!-- <label class="label floating-label w-full">-->
<!-- <span>Email</span>-->
<!-- <input type="email" class={["input w-full", $errors['email'] && 'input-error']} placeholder="Email"-->
<!-- name="email"-->
<!-- aria-invalid={$errors['email'] ? 'true' : undefined}-->
<!-- bind:value={$formData.email}-->
<!-- {...$constraints.email}-->
<!-- />-->
<!-- </label>-->
<!-- <p class="text-error">{$errors['email'] ?? ''}</p>-->
</div>
<div>
<PwdFormInput label="Password" autocomplete="new-password" name="password"
class={$errors['password'] && 'input-error'}
aria-invalid={$errors['password'] ? 'true' : undefined}
bind:value={$formData.password}
{...$constraints.password}
/>
<p class="text-error">{$errors['password'] ?? ''}</p>
</div>
<div>
<PwdFormInput label="Re-insert password" autocomplete="new-password" name="confirmPassword"
class={$errors['confirmPassword'] && 'input-error'}
aria-invalid={$errors['confirmPassword'] ? 'true' : undefined}
bind:value={$formData.confirmPassword}
{...$constraints.confirmPassword}
/>
<p class="text-error">{$errors['confirmPassword'] ?? ''}</p>
</div>
<label class="label">
<span>RossiniEnergy Staff</span>
<input type="checkbox" class="checkbox"/>
</label>
<button class="btn btn-primary">SUBMIT</button>
<!-- <fieldset class="fieldset w-sm bg-base-200 border border-base-300 p-4 rounded-box gap-4">-->
<!-- <legend class="fieldset-legend">Park Admin Feature</legend>-->
<!-- <label class="label">-->
<!-- <span>Enable</span>-->
<!-- <input type="checkbox" class="checkbox"/>-->
<!-- </label>-->
<!-- <div class="fieldset gap-4">-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label floating-label">-->
<!-- <span>Username</span>-->
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
<!-- </label>-->
<!-- <label class="label">-->
<!-- <span>Username</span>-->
<!-- <input type="checkbox" class="checkbox" placeholder="Username"/>-->
<!-- </label>-->
<!-- </div>-->
<!-- </fieldset>-->
</form>
</div>
{#if $message}
<div class="card bg-base-200 mx-auto mt-4 w-fit card-border max-w-md">
<div class="card-body">
<h2 class="card-title" class:text-error={$message['status'] === 'error'}>
{$message['status'] === 'success' ? 'Success!' : 'Error'}
</h2>
<div>
{$message['text']}
</div>
</div>
</div>
{/if}
</div>

View File

@@ -1,7 +1,7 @@
import { type } from "arktype";
export const schema = type({
username: 'string',
username: 'string > 3',
email: 'string.email',
password: 'string > 6',
confirmPassword: 'string > 6'