Working Prototype for Create
This commit is contained in:
@@ -36,7 +36,8 @@
|
|||||||
"vite": "^6.0.0"
|
"vite": "^6.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inlang/paraglide-sveltekit": "^0.15.5"
|
"@inlang/paraglide-sveltekit": "^0.15.5",
|
||||||
|
"lodash": "^4.17.21"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
|
|||||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
|||||||
'@inlang/paraglide-sveltekit':
|
'@inlang/paraglide-sveltekit':
|
||||||
specifier: ^0.15.5
|
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)))
|
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:
|
devDependencies:
|
||||||
'@eslint/compat':
|
'@eslint/compat':
|
||||||
specifier: ^1.2.5
|
specifier: ^1.2.5
|
||||||
@@ -1561,6 +1564,9 @@ packages:
|
|||||||
lodash.once@4.1.1:
|
lodash.once@4.1.1:
|
||||||
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
|
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
|
||||||
|
|
||||||
|
lodash@4.17.21:
|
||||||
|
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||||
|
|
||||||
magic-string@0.30.17:
|
magic-string@0.30.17:
|
||||||
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
||||||
|
|
||||||
@@ -3582,6 +3588,8 @@ snapshots:
|
|||||||
|
|
||||||
lodash.once@4.1.1: {}
|
lodash.once@4.1.1: {}
|
||||||
|
|
||||||
|
lodash@4.17.21: {}
|
||||||
|
|
||||||
magic-string@0.30.17:
|
magic-string@0.30.17:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.0
|
'@jridgewell/sourcemap-codec': 1.5.0
|
||||||
|
|||||||
35
src/lib/FormInput.svelte
Normal file
35
src/lib/FormInput.svelte
Normal 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>
|
||||||
@@ -9,7 +9,7 @@ export const actions = {
|
|||||||
username: data.get('username'),
|
username: data.get('username'),
|
||||||
password: data.get('password')
|
password: data.get('password')
|
||||||
};
|
};
|
||||||
//"/api/public/1/auth/login/"
|
|
||||||
const response = await event.fetch("/api/public/1/auth/login/", {
|
const response = await event.fetch("/api/public/1/auth/login/", {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import type { Actions } from './$types';
|
||||||
import { superValidate } from 'sveltekit-superforms';
|
import { superValidate } from 'sveltekit-superforms';
|
||||||
import { arktype } from 'sveltekit-superforms/adapters';
|
import { arktype } from 'sveltekit-superforms/adapters';
|
||||||
import { message } from 'sveltekit-superforms';
|
import { message } from 'sveltekit-superforms';
|
||||||
import { fail } from '@sveltejs/kit';
|
|
||||||
import { schema, defaults } from './schema';
|
import { schema, defaults } from './schema';
|
||||||
|
|
||||||
export const load = async () => {
|
export const load = async () => {
|
||||||
@@ -13,21 +13,50 @@ export const load = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
default: async ({ request }) => {
|
default: async ({ request, fetch }) => {
|
||||||
const form = await superValidate(request, arktype(schema, { defaults }));
|
const form = await superValidate(request, arktype(schema, { defaults }));
|
||||||
console.log(form);
|
console.log(form);
|
||||||
|
|
||||||
if (!form.valid) {
|
if (!form.valid) {
|
||||||
// Return { form } and things will just work.
|
// 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 the form with a status message
|
||||||
return message(form, {
|
return message(form, {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
text: 'Form posted successfully!',
|
text: `Form posted successfully!\n${JSON.stringify(await response.json(), null, 2)}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
} satisfies Actions;
|
||||||
|
|||||||
@@ -1,107 +1,126 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { superForm } from 'sveltekit-superforms';
|
import { superForm } from 'sveltekit-superforms';
|
||||||
import { arktypeClient } from 'sveltekit-superforms/adapters';
|
import { arktypeClient } from 'sveltekit-superforms/adapters';
|
||||||
|
import { Field, Control, FieldErrors } from "formsnap";
|
||||||
import PwdFormInput from "$lib/PwdFormInput.svelte";
|
import PwdFormInput from "$lib/PwdFormInput.svelte";
|
||||||
import { schema } from './schema';
|
import { schema } from './schema';
|
||||||
|
import FormInput from "$lib/FormInput.svelte";
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
const { form, errors, constraints, message, enhance } = superForm(data.form, {
|
const form = superForm(data.form, {
|
||||||
validators: arktypeClient(schema),
|
validators: arktypeClient(schema),
|
||||||
resetForm: false,
|
resetForm: false,
|
||||||
});
|
});
|
||||||
|
const { form: formData, errors, constraints, message, enhance } = form;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mx-auto w-sm">
|
<div>
|
||||||
<!-- TODO: Do the new Form using https://www.formsnap.dev/docs/quick-start -->
|
<div class="mx-auto w-sm">
|
||||||
<form class="fieldset mt-4 bg-base-200 border border-base-300 p-4 rounded-box gap-4" method="POST" use:enhance>
|
<!-- TODO: Do the new Form using https://www.formsnap.dev/docs/quick-start -->
|
||||||
<h1 class="card-title">Create User</h1>
|
<form class="fieldset mt-4 bg-base-200 border border-base-300 p-4 rounded-box gap-4" method="POST" use:enhance>
|
||||||
<div>
|
<h1 class="card-title">Create User</h1>
|
||||||
<label class="label floating-label w-full">
|
<div>
|
||||||
<span>Username</span>
|
<Field {form} name="username">
|
||||||
<input type="text" class={["input w-full", $errors['username'] && 'input-error']}
|
<Control>
|
||||||
placeholder="Username" name="username"
|
{#snippet children({ props })}
|
||||||
aria-invalid={$errors['username'] ? 'true' : undefined}
|
<label class="label floating-label w-full">
|
||||||
bind:value={$form.username}
|
<span>Username</span>
|
||||||
{...$constraints.username}
|
<input type="text" class="input w-full aria-[invalid]:input-error" placeholder="Username"
|
||||||
/>
|
bind:value={$formData.username} {...props}
|
||||||
</label>
|
/>
|
||||||
<p class="text-error">{$errors['username'] ?? ''}</p>
|
</label>
|
||||||
</div>
|
{/snippet}
|
||||||
<div>
|
</Control>
|
||||||
<label class="label floating-label w-full">
|
<FieldErrors>
|
||||||
<span>Email</span>
|
{#snippet children({ errors, errorProps })}
|
||||||
<input type="email" class={["input w-full", $errors['email'] && 'input-error']} placeholder="Email"
|
{#each errors as err, idx (idx)}
|
||||||
name="email"
|
<p class="text-error" {...errorProps}>{err}</p>
|
||||||
aria-invalid={$errors['email'] ? 'true' : undefined}
|
{/each}
|
||||||
bind:value={$form.email}
|
{/snippet}
|
||||||
{...$constraints.email}
|
</FieldErrors>
|
||||||
/>
|
</Field>
|
||||||
</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>
|
||||||
{/if}
|
<div>
|
||||||
<!-- <fieldset class="fieldset w-sm bg-base-200 border border-base-300 p-4 rounded-box gap-4">-->
|
<FormInput {form} type="email" label="Email" name="email"/>
|
||||||
<!-- <legend class="fieldset-legend">Park Admin Feature</legend>-->
|
<!-- <label class="label floating-label w-full">-->
|
||||||
<!-- <label class="label">-->
|
<!-- <span>Email</span>-->
|
||||||
<!-- <span>Enable</span>-->
|
<!-- <input type="email" class={["input w-full", $errors['email'] && 'input-error']} placeholder="Email"-->
|
||||||
<!-- <input type="checkbox" class="checkbox"/>-->
|
<!-- name="email"-->
|
||||||
<!-- </label>-->
|
<!-- aria-invalid={$errors['email'] ? 'true' : undefined}-->
|
||||||
<!-- <div class="fieldset gap-4">-->
|
<!-- bind:value={$formData.email}-->
|
||||||
<!-- <label class="label floating-label">-->
|
<!-- {...$constraints.email}-->
|
||||||
<!-- <span>Username</span>-->
|
<!-- />-->
|
||||||
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
|
<!-- </label>-->
|
||||||
<!-- </label>-->
|
<!-- <p class="text-error">{$errors['email'] ?? ''}</p>-->
|
||||||
<!-- <label class="label floating-label">-->
|
</div>
|
||||||
<!-- <span>Username</span>-->
|
<div>
|
||||||
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
|
<PwdFormInput label="Password" autocomplete="new-password" name="password"
|
||||||
<!-- </label>-->
|
class={$errors['password'] && 'input-error'}
|
||||||
<!-- <label class="label floating-label">-->
|
aria-invalid={$errors['password'] ? 'true' : undefined}
|
||||||
<!-- <span>Username</span>-->
|
bind:value={$formData.password}
|
||||||
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
|
{...$constraints.password}
|
||||||
<!-- </label>-->
|
/>
|
||||||
<!-- <label class="label floating-label">-->
|
<p class="text-error">{$errors['password'] ?? ''}</p>
|
||||||
<!-- <span>Username</span>-->
|
</div>
|
||||||
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
|
<div>
|
||||||
<!-- </label>-->
|
<PwdFormInput label="Re-insert password" autocomplete="new-password" name="confirmPassword"
|
||||||
<!-- <label class="label floating-label">-->
|
class={$errors['confirmPassword'] && 'input-error'}
|
||||||
<!-- <span>Username</span>-->
|
aria-invalid={$errors['confirmPassword'] ? 'true' : undefined}
|
||||||
<!-- <input type="text" class="input w-full" placeholder="Username"/>-->
|
bind:value={$formData.confirmPassword}
|
||||||
<!-- </label>-->
|
{...$constraints.confirmPassword}
|
||||||
<!-- <label class="label">-->
|
/>
|
||||||
<!-- <span>Username</span>-->
|
<p class="text-error">{$errors['confirmPassword'] ?? ''}</p>
|
||||||
<!-- <input type="checkbox" class="checkbox" placeholder="Username"/>-->
|
</div>
|
||||||
<!-- </label>-->
|
<label class="label">
|
||||||
<!-- </div>-->
|
<span>RossiniEnergy Staff</span>
|
||||||
<!-- </fieldset>-->
|
<input type="checkbox" class="checkbox"/>
|
||||||
</form>
|
</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>
|
</div>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { type } from "arktype";
|
import { type } from "arktype";
|
||||||
|
|
||||||
export const schema = type({
|
export const schema = type({
|
||||||
username: 'string',
|
username: 'string > 3',
|
||||||
email: 'string.email',
|
email: 'string.email',
|
||||||
password: 'string > 6',
|
password: 'string > 6',
|
||||||
confirmPassword: 'string > 6'
|
confirmPassword: 'string > 6'
|
||||||
|
|||||||
Reference in New Issue
Block a user