[FE][Certs] Implement register presets
This commit is contained in:
parent
45e56b4b79
commit
85887f2460
@ -1,6 +1,6 @@
|
|||||||
CREATE TABLE course (
|
CREATE TABLE course (
|
||||||
course_id INTEGER PRIMARY KEY AUTO_INCREMENT,
|
course_id INTEGER PRIMARY KEY AUTO_INCREMENT,
|
||||||
course_name VARCHAR(50) NOT NULL,
|
course_name VARCHAR(75) NOT NULL,
|
||||||
course_display_name VARCHAR(100) NOT NULL,
|
course_display_name VARCHAR(100) NOT NULL,
|
||||||
course_days_amount INTEGER NOT NULL,
|
course_days_amount INTEGER NOT NULL,
|
||||||
course_has_custom_label BOOLEAN NOT NULL
|
course_has_custom_label BOOLEAN NOT NULL
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
CREATE TABLE person (
|
CREATE TABLE person (
|
||||||
person_id INTEGER PRIMARY KEY AUTO_INCREMENT,
|
person_id INTEGER PRIMARY KEY AUTO_INCREMENT,
|
||||||
person_dni VARCHAR(8) NOT NULL,
|
person_dni VARCHAR(20) NOT NULL,
|
||||||
person_names VARCHAR(100) NOT NULL,
|
person_names VARCHAR(100) NOT NULL,
|
||||||
person_paternal_surname VARCHAR(50) NOT NULL,
|
person_paternal_surname VARCHAR(50) NOT NULL,
|
||||||
person_maternal_surname VARCHAR(50) NOT NULL
|
person_maternal_surname VARCHAR(50) NOT NULL
|
||||||
|
@ -43,8 +43,6 @@ export function ManualRegistration(props: {personId: number | null, onAdd: (v: [
|
|||||||
setCount((x) => x + 1);
|
setCount((x) => x + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(`Person ID: ${props.personId}`);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<form onsubmit={register}>
|
<form onsubmit={register}>
|
||||||
|
@ -1,20 +1,107 @@
|
|||||||
|
import { Accessor, For, createSignal } from "solid-js";
|
||||||
import { Chip } from "../../components/Chip";
|
import { Chip } from "../../components/Chip";
|
||||||
|
import { getCourseMemo } from "../../utils/allCourses";
|
||||||
|
import { Course } from "../../types/Course";
|
||||||
|
|
||||||
export function RegisterPresets() {
|
type PresetName = "None" | "2 Matpel" | "3 Matpel" | "4 Escolta" | "MD, 2 Matpel" | "3 4x4" | "2 4x4";
|
||||||
|
|
||||||
|
function genPresets(): {[k: string]: Array<Accessor<Course | null>>} {
|
||||||
|
return {
|
||||||
|
"2 Matpel": [
|
||||||
|
getCourseMemo("Matpel 2"),
|
||||||
|
getCourseMemo("Matpel 1"),
|
||||||
|
],
|
||||||
|
"3 Matpel": [
|
||||||
|
getCourseMemo("Matpel 3"),
|
||||||
|
getCourseMemo("Matpel 2"),
|
||||||
|
getCourseMemo("Matpel 1"),
|
||||||
|
],
|
||||||
|
"4 Escolta": [
|
||||||
|
getCourseMemo("Sup. Escolta"),
|
||||||
|
getCourseMemo("Matpel 3"),
|
||||||
|
getCourseMemo("Matpel 2"),
|
||||||
|
getCourseMemo("Matpel 1"),
|
||||||
|
],
|
||||||
|
"MD, 2 Matpel": [
|
||||||
|
getCourseMemo("Matpel 2"),
|
||||||
|
getCourseMemo("Matpel 1"),
|
||||||
|
getCourseMemo("Manejo Defensivo"),
|
||||||
|
],
|
||||||
|
"3 4x4": [
|
||||||
|
getCourseMemo("4x4"),
|
||||||
|
getCourseMemo("Mecanica Basica"),
|
||||||
|
getCourseMemo("Manejo Defensivo"),
|
||||||
|
],
|
||||||
|
"2 4x4": [
|
||||||
|
getCourseMemo("4x4"),
|
||||||
|
getCourseMemo("Manejo Defensivo"),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RegisterPresets(props: {disableCreation: boolean, onAdd: (v: [number, string]) => void}) {
|
||||||
let datePicker: HTMLInputElement | undefined;
|
let datePicker: HTMLInputElement | undefined;
|
||||||
|
const [selectedPreset, setSelectedPreset] = createSignal<PresetName>("None");
|
||||||
|
const [error, setError] = createSignal("");
|
||||||
|
const presets = genPresets();
|
||||||
|
|
||||||
|
const add = () => {
|
||||||
|
if (datePicker === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const date = datePicker.value;
|
||||||
|
const preset = selectedPreset();
|
||||||
|
|
||||||
|
if (date === "") {
|
||||||
|
setError("Selecciona una fecha");
|
||||||
|
setTimeout(() => setError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (preset === "None") {
|
||||||
|
setError("Selecciona un preset");
|
||||||
|
setTimeout(() => setError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const presetIds = presets[preset];
|
||||||
|
const currentDate = new Date(date);
|
||||||
|
for (const courseMemo of presetIds) {
|
||||||
|
// Get course and course duration from the memo
|
||||||
|
const course = courseMemo();
|
||||||
|
if (course === null) {
|
||||||
|
setError(`Un curso no existe. Error fatal. (${preset})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const courseId = course.course_id;
|
||||||
|
const courseDuration = course.course_days_amount;
|
||||||
|
const dateYYYYMMDD = currentDate.toISOString().split("T")[0];
|
||||||
|
|
||||||
|
// Add
|
||||||
|
props.onAdd([courseId, dateYYYYMMDD]);
|
||||||
|
|
||||||
|
// Substract current date for the next course
|
||||||
|
currentDate.setDate(currentDate.getDate() - courseDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedPreset("None");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class="h-52">
|
<div class="h-52">
|
||||||
<p>Las fechas se colocan automáticamente según la duración del curso.</p>
|
<p>Las fechas se colocan automáticamente según la duración del curso y su jeraquía.</p>
|
||||||
<br />
|
<br />
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
<Chip text="2 Matpel" />
|
<For each={Object.keys(presets)}>
|
||||||
<Chip text="3 Matpel" />
|
{(key) => (
|
||||||
<Chip text="4 Escolta" />
|
<Chip
|
||||||
<Chip text="MD, 2 Matpel" />
|
selected={selectedPreset() === key}
|
||||||
<Chip text="3 4x4" />
|
select={() => setSelectedPreset(key as PresetName)}
|
||||||
<Chip text="2 4x4" />
|
text={key}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
@ -28,13 +115,22 @@ export function RegisterPresets() {
|
|||||||
<label for="create-date" class="absolute -top-2 left-2 text-xs bg-c-surface px-1">Fecha</label>
|
<label for="create-date" class="absolute -top-2 left-2 text-xs bg-c-surface px-1">Fecha</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<div>
|
||||||
class="bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer
|
<input
|
||||||
disabled:opacity-50 disabled:cursor-not-allowed"
|
class="bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer
|
||||||
type="submit"
|
disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
value="Agregar"
|
type="button"
|
||||||
// disabled={props.personId === null}
|
value="Agregar"
|
||||||
/>
|
onclick={add}
|
||||||
|
disabled={props.disableCreation}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<p
|
||||||
|
class="my-2 p-1 w-fit mx-4 text-c-error inline-block"
|
||||||
|
>
|
||||||
|
{error()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ export function RegisterPreview(props: {selections: Array<[number, string]>, per
|
|||||||
const result = await createRegisters(registers);
|
const result = await createRegisters(registers);
|
||||||
|
|
||||||
if (result === null) {
|
if (result === null) {
|
||||||
console.log("Success");
|
console.log("Create register: success");
|
||||||
} else {
|
} else {
|
||||||
console.log(`error. ${result}`);
|
console.log(`error. ${result}`);
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ export function RegisterPreview(props: {selections: Array<[number, string]>, per
|
|||||||
function Register(props: {courseId: number, date: string, onDelete: (v: number) => void}) {
|
function Register(props: {courseId: number, date: string, onDelete: (v: number) => void}) {
|
||||||
const courseName = () => {
|
const courseName = () => {
|
||||||
const courses = allCourses();
|
const courses = allCourses();
|
||||||
return courses.find((course) => course.course_id === props.courseId)?.course_name ?? "!";
|
return courses.find((course) => course.course_id === props.courseId)?.course_name ?? `Curso invalido! (${props.courseId})`;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -30,8 +30,9 @@ export function SearchableSelect(props: {
|
|||||||
});
|
});
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
// Makes reactivity happen
|
// Makes reactivity happen, don't remove
|
||||||
console.log(props.count);
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const _count = props.count;
|
||||||
|
|
||||||
setFilter("");
|
setFilter("");
|
||||||
setSelected(null);
|
setSelected(null);
|
||||||
|
@ -12,7 +12,7 @@ export function NewRegister(props: {
|
|||||||
personId: number | null,
|
personId: number | null,
|
||||||
onSuccess: () => void,
|
onSuccess: () => void,
|
||||||
}) {
|
}) {
|
||||||
const [active, setActive] = createSignal<TabType>("Manual");
|
const [active, setActive] = createSignal<TabType>("Presets");
|
||||||
const [selections, setSelections] = createSignal<Array<[number, string]>>([]);
|
const [selections, setSelections] = createSignal<Array<[number, string]>>([]);
|
||||||
|
|
||||||
const onRegister = () => {
|
const onRegister = () => {
|
||||||
@ -29,7 +29,10 @@ export function NewRegister(props: {
|
|||||||
|
|
||||||
<div class="bg-c-surface p-4 h-[22rem]">
|
<div class="bg-c-surface p-4 h-[22rem]">
|
||||||
<Show when={active() === "Presets"}>
|
<Show when={active() === "Presets"}>
|
||||||
<RegisterPresets />
|
<RegisterPresets
|
||||||
|
onAdd={(v) => setSelections((x) => [...x, v])}
|
||||||
|
disableCreation={props.personId === null}
|
||||||
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={active() === "Manual"}>
|
<Show when={active() === "Manual"}>
|
||||||
<ManualRegistration
|
<ManualRegistration
|
||||||
|
@ -12,7 +12,7 @@ export function Certs() {
|
|||||||
<div class="grid grid-cols-[16rem_25rem_1fr]">
|
<div class="grid grid-cols-[16rem_25rem_1fr]">
|
||||||
<Search setPerson={setPerson} />
|
<Search setPerson={setPerson} />
|
||||||
<NewRegister
|
<NewRegister
|
||||||
personId={person()?.person_id ?? -1}
|
personId={person()?.person_id ?? null}
|
||||||
onSuccess={() => setCount((x) => x + 1)}
|
onSuccess={() => setCount((x) => x + 1)}
|
||||||
/>
|
/>
|
||||||
<Registers person={person()} count={count()} />
|
<Registers person={person()} count={count()} />
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
export function Chip(props: {text: string}) {
|
export function Chip(props: {text: string, selected: boolean, select: () => void}) {
|
||||||
|
const selectedClasses = () => {
|
||||||
|
if (props.selected) {
|
||||||
|
return "bg-c-surface-variant text-c-on-surface-variant shadow";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="inline-block px-3 py-1 border border-c-outline rounded-md text-sm cursor-pointer
|
<div
|
||||||
hover:bg-c-surface-variant hover:text-c-on-surface-variant transition-colors"
|
class={`inline-block px-3 py-1 border border-c-outline rounded-md text-sm cursor-pointer
|
||||||
|
hover:bg-c-surface-variant hover:text-c-on-surface-variant transition-colors
|
||||||
|
select-none ${selectedClasses()}`}
|
||||||
|
onClick={props.select}
|
||||||
>
|
>
|
||||||
{props.text}
|
{props.text}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { createSignal } from "solid-js";
|
import { Accessor, createMemo, createSignal } from "solid-js";
|
||||||
import { Course } from "../types/Course";
|
import { Course } from "../types/Course";
|
||||||
|
|
||||||
type CourseMap = {[k: number]: Course};
|
type CourseMap = {[k: number]: Course};
|
||||||
@ -17,8 +17,17 @@ export const [courseMap, setCourseMap] = createSignal<CourseMap>({});
|
|||||||
for (const course of data) {
|
for (const course of data) {
|
||||||
map[course.course_id] = course;
|
map[course.course_id] = course;
|
||||||
}
|
}
|
||||||
console.log("course map", map);
|
|
||||||
setCourseMap(map);
|
setCourseMap(map);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
export function getCourseMemo(name: string): Accessor<Course | null> {
|
||||||
|
return createMemo(() => {
|
||||||
|
const course = allCourses().find((course) => course.course_name === name);
|
||||||
|
if (course) {
|
||||||
|
return course;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user