diff --git a/package.json b/package.json index df9fb9a..1b4b1f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { - "name": "peer-at-code-sveltekit", + "name": "peer-at-code", "version": "0.0.1", + "type": "module", "private": true, "scripts": { "dev": "vite dev", @@ -14,6 +15,14 @@ "test:integration": "playwright test", "test:unit": "vitest" }, + "dependencies": { + "class-variance-authority": "^0.7.0", + "clsx": "^2.0.0", + "marked": "^7.0.1", + "svelte-boring-avatars": "^1.2.4", + "tailwind-merge": "^1.14.0", + "zod": "^3.21.4" + }, "devDependencies": { "@playwright/test": "^1.28.1", "@sveltejs/adapter-auto": "^2.0.0", @@ -37,14 +46,5 @@ "typescript": "^5.0.0", "vite": "^4.4.2", "vitest": "^0.32.2" - }, - "type": "module", - "dependencies": { - "class-variance-authority": "^0.7.0", - "clsx": "^2.0.0", - "marked": "^7.0.1", - "svelte-boring-avatars": "^1.2.4", - "tailwind-merge": "^1.14.0", - "zod": "^3.21.4" } } diff --git a/src/lib/components/ui/Input.svelte b/src/lib/components/ui/Input.svelte index e9132e0..01fa24c 100644 --- a/src/lib/components/ui/Input.svelte +++ b/src/lib/components/ui/Input.svelte @@ -3,9 +3,30 @@ import { cn } from '$lib'; - let className: string | undefined | null = undefined; + type FormInputEvent = T & { + currentTarget: EventTarget & HTMLInputElement; + }; - export let value: HTMLInputAttributes['value'] = undefined; + type InputEvents = { + blur: FormInputEvent; + change: FormInputEvent; + click: FormInputEvent; + focus: FormInputEvent; + keydown: FormInputEvent; + keypress: FormInputEvent; + keyup: FormInputEvent; + mouseover: FormInputEvent; + mouseenter: FormInputEvent; + mouseleave: FormInputEvent; + paste: FormInputEvent; + input: FormInputEvent; + }; + + type $$Props = HTMLInputAttributes; + type $$Events = InputEvents; + + let className: $$Props['class'] = undefined; + export let value: $$Props['value'] = undefined; export { className as class }; diff --git a/src/lib/stores/Register.ts b/src/lib/stores/Register.ts new file mode 100644 index 0000000..763ee86 --- /dev/null +++ b/src/lib/stores/Register.ts @@ -0,0 +1,19 @@ +import { browser } from '$app/environment'; +import { writable } from 'svelte/store'; + +const defaultValue = false; +const initialValue = browser ? window.localStorage.getItem('register') === 'true' : defaultValue; + +const register = writable(initialValue); + +register.subscribe((value) => { + if (browser) { + window.localStorage.setItem('register', value ? 'true' : 'false'); + } +}); + +export function resetRegister() { + register.set(defaultValue); +} + +export default register; diff --git a/src/routes/sign-in/+page.svelte b/src/routes/sign-in/+page.svelte index 54fe625..7735925 100644 --- a/src/routes/sign-in/+page.svelte +++ b/src/routes/sign-in/+page.svelte @@ -34,17 +34,18 @@ Se connecter + + - diff --git a/src/routes/sign-up/+page.server.ts b/src/routes/sign-up/+page.server.ts index df5acd9..64aefbc 100644 --- a/src/routes/sign-up/+page.server.ts +++ b/src/routes/sign-up/+page.server.ts @@ -1,14 +1,28 @@ -import { redirect, type Actions, fail } from '@sveltejs/kit'; -import type { PageServerLoad } from './$types'; import { API_URL } from '$env/static/private'; +import { fail, redirect, type Actions } from '@sveltejs/kit'; + +import type { PageServerLoad } from './$types'; + import { z } from 'zod'; export const load = (async ({ locals: { user } }) => { if (user) throw redirect(303, '/dashboard'); }) satisfies PageServerLoad; -const schema = z.object({ +const registerSchema = z.object({ + email: z + .string() + .email({ + message: 'Email invalide' + }) + .trim(), + firstname: z.string().trim(), + lastname: z.string().trim(), + pseudo: z.string().trim() +}); + +const confirmationSchema = z.object({ email: z .string() .email({ @@ -18,17 +32,15 @@ const schema = z.object({ firstname: z.string().trim(), lastname: z.string().trim(), pseudo: z.string().trim(), - passwd: z.string(), - description: z.string().nullable(), - sgroup: z.string().nullable(), - avatar: z.string().nullable() + code: z.string(), + passwd: z.string() }); export const actions = { - default: async (event) => { + register: async (event) => { const data = await event.request.formData(); - const parse = schema.safeParse(Object.fromEntries(data.entries())); + const parse = registerSchema.safeParse(Object.fromEntries(data.entries())); if (!parse.success) { const errors = parse.error.errors.map((error) => { @@ -41,44 +53,74 @@ export const actions = { const res = await fetch(`${API_URL}/register`, { method: 'POST', body: JSON.stringify({ - ...parse.data + pseudo: parse.data.pseudo, + firstname: parse.data.firstname, + lastname: parse.data.lastname, + email: parse.data.email }) }); if (res.ok) { - const token = res.headers.get('Authorization')?.split(' ')[1]; - - if (!token) throw new Error('No token found'); - - event.cookies.set('session', token, { - path: '/' - }); - - throw redirect(303, '/dashboard'); + return { + success: true + }; } if (res.status === 400) { - const { username_valid, email_valid } = await res.json(); + const { email_valid } = await res.json(); const errors = []; - if (!username_valid) { - errors.push({ - field: 'pseudo', - message: 'Ce pseudo est déjà utilisé' - }); - } - - if (!email_valid) { + if (!email_valid) errors.push({ field: 'email', message: 'Cet email est déjà utilisé' }); - } return fail(400, { errors }); } + return fail(400, { + errors: [{ field: 'passwd', message: "Une erreur s'est produite" }] + }); + }, + confirmation: async (event) => { + const data = await event.request.formData(); + + const parse = confirmationSchema.safeParse(Object.fromEntries(data.entries())); + + if (!parse.success) { + const errors = parse.error.errors.map((error) => { + const { path, message } = error; + return { field: path[0], message }; + }); + return fail(400, { errors }); + } + + const res = await fetch(`${API_URL}/confirmation`, { + method: 'POST', + body: JSON.stringify({ + firstname: parse.data.firstname, + lastname: parse.data.lastname, + pseudo: parse.data.pseudo, + email: parse.data.email, + code: parseInt(parse.data.code), + passwd: parse.data.passwd + }) + }); + + if (res.ok) { + const token = res.headers.get('Authorization')?.split('Bearer ')[1]; + + if (!token) throw new Error('No token'); + + event.cookies.set('token', token, { + path: '/' + }); + + throw redirect(303, '/dashboard'); + } + return fail(400, { errors: [{ field: 'passwd', message: "Une erreur s'est produite" }] }); diff --git a/src/routes/sign-up/+page.svelte b/src/routes/sign-up/+page.svelte index 2dee1d5..253be5e 100644 --- a/src/routes/sign-up/+page.svelte +++ b/src/routes/sign-up/+page.svelte @@ -1,73 +1,152 @@
-

Inscription

-
+

{confirmation ? 'Confirmation' : 'Inscription'}

+ { + return async ({ result }) => { + switch (result.type) { + case 'success': + register.set(true); + break; + } + }; + }} + action={confirmation ? '/sign-up?/confirmation' : '/sign-up?/register'} + > - - {#if form?.errors.find((error) => error.field === 'email')} + + {#if form?.errors?.find((error) => error.field === 'email')}

{form?.errors.find((error) => error.field === 'email')?.message}

{/if} - - {#if form?.errors.find((error) => error.field === 'firstname')} + + {#if form?.errors?.find((error) => error.field === 'firstname')}

- {form?.errors.find((error) => error.field === 'firstname')?.message} + {form?.errors?.find((error) => error.field === 'firstname')?.message}

{/if} - - {#if form?.errors.find((error) => error.field === 'lastname')} + + {#if form?.errors?.find((error) => error.field === 'lastname')}

- {form?.errors.find((error) => error.field === 'lastname')?.message} + {form?.errors?.find((error) => error.field === 'lastname')?.message}

{/if} - - {#if form?.errors.find((error) => error.field === 'pseudo')} + + {#if form?.errors?.find((error) => error.field === 'pseudo')}

- {form?.errors.find((error) => error.field === 'pseudo')?.message} + {form?.errors?.find((error) => error.field === 'pseudo')?.message}

{/if} - - - {#if form?.errors.find((error) => error.field === 'passwd')} -

- {form?.errors.find((error) => error.field === 'passwd')?.message} -

+ {#if confirmation} +
+ + + {#if form?.errors?.find((error) => error.field === 'passwd')} +

+ {form?.errors?.find((error) => error.field === 'passwd')?.message} +

+ {/if} + + + {#if form?.errors?.find((error) => error.field === 'code')} +

+ {form?.errors?.find((error) => error.field === 'code')?.message} +

+ {/if} +
{/if} - - - - + +
    +
  • + Se connecter +
  • + {#if confirmation} +
  • + +
  • + {/if} +
-