mirror of
https://github.com/danbulant/Portfolio
synced 2026-06-06 08:10:20 +00:00
feat: validate grades table in form
This commit is contained in:
parent
da3fe8c5ac
commit
16ef3569e6
2 changed files with 66 additions and 25 deletions
|
|
@ -7,9 +7,11 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
import GradesRow, { type Grade, type Semester } from './GradesRow.svelte';
|
import GradesRow, { type Grade, type Semester } from './GradesRow.svelte';
|
||||||
|
|
||||||
let gradesLocal: Array<Grade> = Array.from({ length: 8 }, () => {
|
let gradesLocal: Array<Grade> = Array.from({ length: 1 }, () => {
|
||||||
return {
|
return {
|
||||||
subject: '',
|
subject: '',
|
||||||
semesters: {
|
semesters: {
|
||||||
|
|
@ -21,27 +23,35 @@
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export let error: string = '';
|
||||||
|
|
||||||
export let grades: Array<GradeBackend>;
|
export let grades: Array<GradeBackend>;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
// Convert local Grade type to expanded GradesBackend type
|
// Convert local Grade type to expanded GradesBackend type
|
||||||
$: {
|
const convertGrades = () => {
|
||||||
const gradesTemp: Array<GradeBackend> = [];
|
// Delay to wait for select to be updated
|
||||||
for (let index = 0; index < gradesLocal.length; index++) {
|
setTimeout(() => {
|
||||||
const grade = gradesLocal[index];
|
const gradesTemp: Array<GradeBackend> = [];
|
||||||
for (const semester in grade.semesters) {
|
for (let index = 0; index < gradesLocal.length; index++) {
|
||||||
const semesterTyped = semester as Semester;
|
const grade = gradesLocal[index];
|
||||||
if (grade.semesters[semesterTyped] && grade.subject) {
|
for (const semester in grade.semesters) {
|
||||||
const gradeString = grade.semesters[semesterTyped]!;
|
const semesterTyped = semester as Semester;
|
||||||
gradesTemp.push({
|
if (grade.semesters[semesterTyped] && grade.subject) {
|
||||||
subject: grade.subject,
|
const gradeString = grade.semesters[semesterTyped]!;
|
||||||
grade: Number(gradeString),
|
gradesTemp.push({
|
||||||
semester: semesterTyped
|
subject: grade.subject,
|
||||||
});
|
grade: Number(gradeString),
|
||||||
|
semester: semesterTyped
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
grades = [...gradesTemp];
|
||||||
grades = gradesTemp;
|
dispatch('change', grades);
|
||||||
}
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mx-auto mt-8 flex max-h-[22rem] w-full flex-col overflow-scroll lg:w-4/5">
|
<div class="mx-auto mt-8 flex max-h-[22rem] w-full flex-col overflow-scroll lg:w-4/5">
|
||||||
|
|
@ -53,9 +63,10 @@
|
||||||
<span class="ml-0.5 w-1/6 text-center">2/9</span>
|
<span class="ml-0.5 w-1/6 text-center">2/9</span>
|
||||||
</div>
|
</div>
|
||||||
{#each gradesLocal as _, i}
|
{#each gradesLocal as _, i}
|
||||||
<GradesRow bind:grade={gradesLocal[i]} />
|
<GradesRow on:keyup={convertGrades} on:change={convertGrades} bind:grade={gradesLocal[i]} />
|
||||||
{/each}
|
{/each}
|
||||||
<button
|
<button
|
||||||
|
class:isError={error}
|
||||||
class="ml-auto w-24 rounded-full bg-gray-400 p-1 text-xl text-white transition-colors duration-300 hover:bg-gray-500"
|
class="ml-auto w-24 rounded-full bg-gray-400 p-1 text-xl text-white transition-colors duration-300 hover:bg-gray-500"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
gradesLocal = [
|
gradesLocal = [
|
||||||
|
|
@ -82,4 +93,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
.isError {
|
||||||
|
@apply bg-red-500;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,8 @@
|
||||||
citizenship: '',
|
citizenship: '',
|
||||||
personalIdNumber: '',
|
personalIdNumber: '',
|
||||||
schoolName: '',
|
schoolName: '',
|
||||||
healthInsurance: ''
|
healthInsurance: '',
|
||||||
|
grades: []
|
||||||
},
|
},
|
||||||
parents: [
|
parents: [
|
||||||
{
|
{
|
||||||
|
|
@ -106,7 +107,20 @@
|
||||||
citizenship: yup.string().required(),
|
citizenship: yup.string().required(),
|
||||||
personalIdNumber: yup.string().required(),
|
personalIdNumber: yup.string().required(),
|
||||||
schoolName: yup.string().required(),
|
schoolName: yup.string().required(),
|
||||||
healthInsurance: yup.number().required()
|
healthInsurance: yup.number().required(),
|
||||||
|
grades: yup
|
||||||
|
.array()
|
||||||
|
.min(1)
|
||||||
|
.of(
|
||||||
|
yup
|
||||||
|
.object()
|
||||||
|
.shape({
|
||||||
|
subject: yup.string().required(),
|
||||||
|
grade: yup.number().required(),
|
||||||
|
semester: yup.string().required()
|
||||||
|
})
|
||||||
|
.required()
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
parents: yup.array().of(
|
parents: yup.array().of(
|
||||||
yup.object().shape({
|
yup.object().shape({
|
||||||
|
|
@ -272,7 +286,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { form, errors, handleSubmit, handleChange } = createForm({
|
const { form, errors, handleSubmit, handleChange, updateValidateField } = createForm({
|
||||||
initialValues: formInitialValues,
|
initialValues: formInitialValues,
|
||||||
validationSchema: formValidationSchema,
|
validationSchema: formValidationSchema,
|
||||||
|
|
||||||
|
|
@ -371,7 +385,8 @@
|
||||||
street: details.candidate.address.split(',')[0].split(' ')[0],
|
street: details.candidate.address.split(',')[0].split(' ')[0],
|
||||||
houseNumber: details.candidate.address.split(',')[0].split(' ')[1],
|
houseNumber: details.candidate.address.split(',')[0].split(' ')[1],
|
||||||
city: details.candidate.address.split(',')[1],
|
city: details.candidate.address.split(',')[1],
|
||||||
zip: details.candidate.address.split(',')[2]
|
zip: details.candidate.address.split(',')[2],
|
||||||
|
grades: []
|
||||||
},
|
},
|
||||||
parents: [
|
parents: [
|
||||||
{
|
{
|
||||||
|
|
@ -390,8 +405,6 @@
|
||||||
pageIndex = 2; // skip gdpr page
|
pageIndex = 2; // skip gdpr page
|
||||||
pageTexts[2] = 'Úprava osobních údajů';
|
pageTexts[2] = 'Úprava osobních údajů';
|
||||||
}
|
}
|
||||||
|
|
||||||
let test = 8;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SplitLayout>
|
<SplitLayout>
|
||||||
|
|
@ -684,7 +697,21 @@
|
||||||
<p class="description mt-8 block text-center">
|
<p class="description mt-8 block text-center">
|
||||||
Přidejte prosím přepis Vaších známek z posledních dvou let studia
|
Přidejte prosím přepis Vaších známek z posledních dvou let studia
|
||||||
</p>
|
</p>
|
||||||
<GradesTable />
|
<GradesTable
|
||||||
|
error={$typedErrors['candidate']['grades']}
|
||||||
|
on:change={(event) => {
|
||||||
|
//@ts-ignore
|
||||||
|
const mockEvent = {
|
||||||
|
target: {
|
||||||
|
name: 'candidate.grades',
|
||||||
|
value: event.detail
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//@ts-ignore
|
||||||
|
handleChange(mockEvent);
|
||||||
|
}}
|
||||||
|
bind:grades={$form.candidate.grades}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="bottom-1/12 absolute w-full">
|
<div class="bottom-1/12 absolute w-full">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue