feat: edit personal details

This commit is contained in:
Sebastian Pravda 2022-12-25 12:28:30 +01:00
parent a59b06d18c
commit 23c577fd52
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
4 changed files with 209 additions and 104 deletions

View file

@ -7,7 +7,8 @@
import StatusNotificationBig from './StatusNotificationBig.svelte'; import StatusNotificationBig from './StatusNotificationBig.svelte';
import InfoButton from './InfoButton.svelte'; import InfoButton from './InfoButton.svelte';
import { candidateData } from '$lib/stores/candidate'; import { candidateData } from '$lib/stores/candidate';
import tippy from 'tippy.js'; import tippy, {sticky} from 'tippy.js';
import { goto } from '$app/navigation';
export let title: string; export let title: string;
export let status: Status; export let status: Status;
@ -58,6 +59,10 @@
console.log(e); console.log(e);
} }
}; };
const editDetails = async () => {
goto('/register?edit=true')
}
</script> </script>
<div class="card flex flex-col"> <div class="card flex flex-col">
@ -86,7 +91,8 @@
</div> </div>
</div> </div>
{#if showDetails} {#if showDetails}
<div class="overflow-scroll"> <div class="overflow-scroll flex justify-between">
<div>
<div <div
use:tippy={{ use:tippy={{
content: '<span>Vámi vyplněné osobní údaje</span>', content: '<span>Vámi vyplněné osobní údaje</span>',
@ -133,6 +139,18 @@
{/each} {/each}
</div> </div>
</div> </div>
<span
use:tippy={{
content: 'Upravit osobní údaje',
placement: 'top',
showOnCreate: false,
sticky: true,
plugins: [sticky]
}}
on:click={(_) => editDetails()} on:keydown={(_) => editDetails()} class="mt-4 hover:cursor-pointer">
<svg class="w-10 h-10 stroke-sspsBlue" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path></svg>
</span>
</div>
{/if} {/if}
</div> </div>
</div> </div>

View file

@ -2,23 +2,23 @@ import { writable } from 'svelte/store';
export interface CandidateData { export interface CandidateData {
candidate: { candidate: {
name?: string; name: string;
surname?: string; surname: string;
birthplace?: string; birthplace: string;
birthdate?: string; birthdate: string;
address?: string; address: string;
telephone?: string; telephone: string;
citizenship?: string; citizenship: string;
email?: string; email: string;
sex?: string; sex: string;
study?: string; study: string;
personalIdNumber?: string; personalIdNumber: string;
}; };
parents: Array<{ parents: Array<{
name?: string; name: string;
surname?: string; surname: string;
telephone?: string; telephone: string;
email?: string; email: string;
}>; }>;
} }
@ -44,6 +44,18 @@ export interface CreateCandidateLogin extends CreateCandidate {
} }
export const candidateData = writable<CandidateData>({ export const candidateData = writable<CandidateData>({
candidate: {}, candidate: {
name: '',
surname: '',
birthplace: '',
birthdate: '',
address: '',
telephone: '',
citizenship: '',
email: '',
sex: '',
study: '',
personalIdNumber: ''
},
parents: [] parents: []
}); });

View file

@ -0,0 +1,14 @@
import { apiFetchDetails, apiFetchSubmissionProgress } from '$lib/@api/candidate';
import type { CandidateData } from '$lib/stores/candidate';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ fetch }) => {
const details: CandidateData | undefined = await apiFetchDetails(fetch).catch((e) => {
console.error(e);
return undefined;
});
return {
candidate: details,
};
};

View file

@ -13,16 +13,23 @@
import NameField from '$lib/components/textfield/NameField.svelte'; import NameField from '$lib/components/textfield/NameField.svelte';
import TelephoneField from '$lib/components/textfield/TelephoneField.svelte'; import TelephoneField from '$lib/components/textfield/TelephoneField.svelte';
import TextField from '$lib/components/textfield/TextField.svelte'; import TextField from '$lib/components/textfield/TextField.svelte';
import type { CandidateData } from '$lib/stores/candidate'; import type { PageData } from './$types';
import { createForm } from 'svelte-forms-lib'; import { createForm } from 'svelte-forms-lib';
import type { Writable } from 'svelte/store'; import type { Writable } from 'svelte/store';
import * as yup from 'yup'; import * as yup from 'yup';
import type { CandidateData } from '$lib/stores/candidate';
import { onMount } from 'svelte';
const pageCount = 5; const pageCount = 5;
let pageIndex = 0; let pageIndex = 0;
let pagesFilled = [false, false, false, false, false]; let pagesFilled = [false, false, false, false, false];
export let data: PageData;
let details = data.candidate;
let editMode = false;
const formInitialValues = { const formInitialValues = {
gdpr: false, gdpr: false,
candidate: { candidate: {
@ -108,11 +115,7 @@
) )
}); });
const { form, errors, handleSubmit, handleChange } = createForm({ const onSubmit = async (values: CandidateData) => {
initialValues: formInitialValues,
validationSchema: formValidationSchema,
onSubmit: async (values: CandidateData) => {
console.log('page count: ' + pageIndex); console.log('page count: ' + pageIndex);
console.log(values.candidate); console.log(values.candidate);
console.log(values.parents); console.log(values.parents);
@ -145,6 +148,12 @@
} }
} }
} }
const { form, errors, handleSubmit, handleChange } = createForm({
initialValues: formInitialValues,
validationSchema: formValidationSchema,
onSubmit: async (values: CandidateData) => onSubmit(values)
}); });
type FormErrorType = { type FormErrorType = {
@ -163,8 +172,8 @@
// TODO: https://github.com/tjinauyeung/svelte-forms-lib/issues/171!! (Zatím tenhle mega typ) // TODO: https://github.com/tjinauyeung/svelte-forms-lib/issues/171!! (Zatím tenhle mega typ)
$: typedErrors = errors as unknown as Writable<FormErrorType>; $: typedErrors = errors as unknown as Writable<FormErrorType>;
const isPageInvalid = (): boolean => { const isPageInvalid = (index: number): boolean => {
switch (pageIndex) { switch (index) {
case 0: case 0:
if ($typedErrors['gdpr']) { if ($typedErrors['gdpr']) {
return true; return true;
@ -224,6 +233,52 @@
} }
return false; return false;
}; };
const formatTelephone = (telephone: string) => {
return '+' + telephone
.match(/[0-9]{1,3}/g)!
.join(' ');
}
$: console.log($form.candidate.birthdate);
if (details !== undefined) {
details.candidate.birthdate = details.candidate.birthdate
.split('-')
.map((x) => x.startsWith('0') ? x.slice(1) : x)
.reverse()
.join('.');
details.candidate.telephone = formatTelephone(details.candidate.telephone);
details.parents.map((x) => x.telephone = x.telephone != '' ? formatTelephone(x.telephone) : '');
form.set({
gdpr: true,
candidate: {
...details.candidate
},
parents: [
{
...details.parents[0]
},
{
...details.parents[1] ?? {
name: '',
surname: '',
email: '',
telephone: ''
}
}
]
});
pageIndex = 1; // skip gdpr page
}
// onMount(() => {
// let evt: Event = document.createEvent('MouseEvent');
// handleSubmit(evt);
// });
</script> </script>
<SplitLayout> <SplitLayout>
@ -231,8 +286,9 @@
<div class="h-24 w-24 md:h-auto md:w-auto"> <div class="h-24 w-24 md:h-auto md:w-auto">
<SchoolBadge /> <SchoolBadge />
</div> </div>
<form on:submit={(e) => {handleSubmit(e); console.log("event" + e)}} id="triggerForm" class="invisible hidden"></form>
{#if pageIndex === 0} {#if pageIndex === 0}
<form on:submit={handleSubmit}> <form on:submit={(e) => {handleSubmit(e); console.log("event" + e)}}>
<h1 class="text-sspsBlue mt-8 text-4xl font-semibold">Váš souhlas</h1> <h1 class="text-sspsBlue mt-8 text-4xl font-semibold">Váš souhlas</h1>
<p class="text-sspsGray mt-8 block text-center font-light"> <p class="text-sspsGray mt-8 block text-center font-light">
V rámci portálu pro přijímací řízení zpracováváme mnoho osobních údajů. Proto je nutný Váš V rámci portálu pro přijímací řízení zpracováváme mnoho osobních údajů. Proto je nutný Váš
@ -247,7 +303,7 @@
</div> </div>
</form> </form>
{:else if pageIndex === 1} {:else if pageIndex === 1}
<form on:submit={handleSubmit}> <form on:submit={(e) => {handleSubmit(e); console.log("event" + e)}}>
<h1 class="text-sspsBlue mt-8 text-4xl font-semibold">Registrace</h1> <h1 class="text-sspsBlue mt-8 text-4xl font-semibold">Registrace</h1>
<p class="text-sspsGray mt-8 block text-center font-light"> <p class="text-sspsGray mt-8 block text-center font-light">
V rámci usnadnění přijímacího řízení jsme připravili online formulář, který vám pomůže s V rámci usnadnění přijímacího řízení jsme připravili online formulář, který vám pomůže s
@ -452,9 +508,9 @@
<div class="mt-8 w-full"> <div class="mt-8 w-full">
<Submit <Submit
on:click={async (e) => { on:click={async (e) => {
console.log('event: ' + e);
await handleSubmit(e); await handleSubmit(e);
console.log('clicked ' + isPageInvalid()); if (isPageInvalid(pageIndex)) return;
if (isPageInvalid()) return;
if (pageIndex === pageCount) { if (pageIndex === pageCount) {
} else { } else {
pagesFilled[pageIndex] = true; pagesFilled[pageIndex] = true;
@ -472,19 +528,24 @@
<button <button
class:dotActive={i === pageIndex} class:dotActive={i === pageIndex}
on:click={async (e) => { on:click={async (e) => {
pageIndex -= pageIndex === pageCount ? 1 : 0;
await handleSubmit(e);
pagesFilled = pagesFilled.map((_, i) => !isPageInvalid(i));
const progress = pagesFilled.slice(0, i).every((item) => item === true); const progress = pagesFilled.slice(0, i).every((item) => item === true);
if (progress) { if (progress) {
if (i > pageIndex) { if (i > pageIndex) {
// if next page is clicked, validate current page // if next page is clicked, validate current page
await handleSubmit(e); console.log($errors);
if (isPageInvalid()) return; if (isPageInvalid(pageIndex)) return;
pagesFilled[i] = true; // pagesFilled[i] = true;
pageIndex++; console.log(pagesFilled);
pageIndex = i;
} else { } else {
pageIndex = i; pageIndex = i;
} }
// @ts-ignore // @ts-ignore
errors.set(formInitialValues); // errors.set(formInitialValues);
} }
}} }}
class="dot" class="dot"