diff --git a/src/lib/components/composable/use-patient-form.svelte.js b/src/lib/components/composable/use-patient-form.svelte.js index a99391c..7640b34 100644 --- a/src/lib/components/composable/use-patient-form.svelte.js +++ b/src/lib/components/composable/use-patient-form.svelte.js @@ -28,7 +28,7 @@ export function usePatientForm(formState, patientSchema) { ), EmailAddress1: patientSchema.shape.EmailAddress1.refine( async (value) => { - if (!value) return false; + if (!value) return true; const res = await fetch(`${API.BASE_URL}${API.CHECK}?EmailAddress1=${value}`); const { status, data } = await res.json(); return status === "success" && data === false ? false : true; @@ -37,13 +37,22 @@ export function usePatientForm(formState, patientSchema) { ), EmailAddress2: patientSchema.shape.EmailAddress2.refine( async (value) => { - if (!value) return false; + if (!value) return true; const res = await fetch(`${API.BASE_URL}${API.CHECK}?EmailAddress1=${value}`); const { status, data } = await res.json(); return status === "success" && data === false ? false : true; }, { message: "Email address already used" } ), + Phone: patientSchema.shape.Phone.refine( + async (value) => { + if (!value) return true; + const res = await fetch(`${API.BASE_URL}${API.CHECK}?Phone=${value}`); + const { status, data } = await res.json(); + return status === "success" && data === false ? false : true; + }, + { message: "Phone number already used" } + ), }); const partial = asyncSchema.pick({ [field]: true }); diff --git a/src/lib/components/dictionary/contact/page/create-page.svelte b/src/lib/components/dictionary/contact/page/create-page.svelte index 3973d3b..3a63272 100644 --- a/src/lib/components/dictionary/contact/page/create-page.svelte +++ b/src/lib/components/dictionary/contact/page/create-page.svelte @@ -113,10 +113,10 @@ tempDetailContact, }); console.log(payload) - // const result = await formState.save(masterDetail.mode); + const result = await formState.save(masterDetail.mode); - // toast('Contact Created!'); - // masterDetail?.exitForm(true); + toast('Contact Created!'); + masterDetail?.exitForm(true); } const primaryAction = $derived({ diff --git a/src/lib/components/dictionary/location/config/location-form-config.js b/src/lib/components/dictionary/location/config/location-form-config.js index af9f8ed..11694b8 100644 --- a/src/lib/components/dictionary/location/config/location-form-config.js +++ b/src/lib/components/dictionary/location/config/location-form-config.js @@ -3,7 +3,7 @@ import EraserIcon from "@lucide/svelte/icons/eraser"; import { z } from "zod"; export const locationSchema = z.object({ - LocCode: z.string().min(1, "Required"), + LocCode: z.string().min(1, "Required").max(6, "Max 6 chars"), LocFull: z.string().min(1, "Required"), Email: z.string().trim().optional().refine((val) => !val || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),"Invalid email format"), Phone: z.string().max(14, "Max 14 chars").regex(/^$|^[0-9]+$/, "Can only contain numbers"), diff --git a/src/lib/components/dictionary/location/page/create-page.svelte b/src/lib/components/dictionary/location/page/create-page.svelte index 901d678..94ba3bd 100644 --- a/src/lib/components/dictionary/location/page/create-page.svelte +++ b/src/lib/components/dictionary/location/page/create-page.svelte @@ -26,8 +26,14 @@ async function handleSave() { const result = await formState.save(masterDetail.mode); - toast('Location Created!'); - masterDetail?.exitForm(true); + if (result.status === 'success') { + toast('Location Created!'); + masterDetail?.exitForm(true); + } else { + console.error('Failed to save location'); + const errorMessages = result.messages ? Object.values(result.messages).join('\n') : 'Failed to save location'; + toast.error(errorMessages) + } } const primaryAction = $derived({ diff --git a/src/lib/components/dictionary/testmap/page/create-page.svelte b/src/lib/components/dictionary/testmap/page/create-page.svelte index 20c01f7..f4825eb 100644 --- a/src/lib/components/dictionary/testmap/page/create-page.svelte +++ b/src/lib/components/dictionary/testmap/page/create-page.svelte @@ -63,7 +63,6 @@ } function handleInsertDetail() { - console.log('object'); const row = { id: ++idCounter, ...snapshotForm() diff --git a/src/lib/components/patient/list/config/patient-config.js b/src/lib/components/patient/list/config/patient-config.js index 2c911d2..550c3e8 100644 --- a/src/lib/components/patient/list/config/patient-config.js +++ b/src/lib/components/patient/list/config/patient-config.js @@ -79,7 +79,7 @@ export const detailSections = [ }, { key: "isDeadLabel", label: "Deceased" }, { key: "CreateDate", label: "Create Date", isUTCDate: true }, - { key: "DelDate", label: "Disabled Date" }, + { key: "DelDate", label: "Delete Date" }, { key: "TimeOfDeath", label: "Time of Death", isUTCDate: true }, ] }, diff --git a/src/lib/components/patient/list/config/patient-form-config.js b/src/lib/components/patient/list/config/patient-form-config.js index 59f9f51..6619474 100644 --- a/src/lib/components/patient/list/config/patient-form-config.js +++ b/src/lib/components/patient/list/config/patient-form-config.js @@ -12,12 +12,13 @@ export const patientSchema = z.object({ ), EmailAddress1: z.string().trim().optional().refine((val) => !val || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),"Invalid email format"), EmailAddress2: z.string().trim().optional().refine((val) => !val || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),"Invalid email format"), - Phone: z.string().max(14, "Max 14 chars").regex(/^$|^[0-9]+$/, "Can only contain numbers"), + Phone: z.string().max(14, "Max 14 chars").regex(/^$|^[0-9]+$/, "Can only contain numbers").optional(), MobilePhone: z.string().max(14, "Max 14 chars").regex(/^$|^[0-9]+$/, "Can only contain numbers"), TimeOfDeath: z.string().optional().refine( (date) => new Date(date) <= new Date(), "Cannot exceed today's date" ), + ZIP: z.string().max(7, "Max 7 chars").regex(/^$|^[0-9]+$/, "Can only contain numbers"), }); export const patientInitialForm = { @@ -55,7 +56,7 @@ export const patientInitialForm = { Phone: "", EmailAddress2: "", MobilePhone: "", - DeathIndicator: "", + isDead: "", TimeOfDeath: "", LinkTo: [], PatCom: "", @@ -73,6 +74,7 @@ export const patientDefaultErrors = { Phone: null, MobilePhone: null, TimeOfDeath: null, + ZIP: null, }; export const patientFormFields = [ @@ -236,7 +238,7 @@ export const patientFormFields = [ { type: "group", columns: [ - { key: "ZIP", label: "ZIP", required: false, type: "number" }, + { key: "ZIP", label: "ZIP", required: false, type: "text", validateOn: ["input"] }, { key: "Country", label: "Country", @@ -257,7 +259,7 @@ export const patientFormFields = [ type: "row", columns: [ { key: "EmailAddress1", label: "Email Address 1", required: false, type: "email", validateOn: ["input", "blur"] }, - { key: "Phone", label: "Phone", required: false, type: "text", validateOn: ["input"] }, + { key: "Phone", label: "Phone", required: false, type: "text", validateOn: ["input", "blur"] }, ] }, { @@ -273,13 +275,23 @@ export const patientFormFields = [ { type: "group", columns: [ + // { + // key: "isDead", + // label: "Deceased", + // required: false, + // type: "select", + // optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/death_indicator`, + // defaultValue: 'N' + // }, { key: "isDead", label: "Deceased", required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/death_indicator`, - defaultValue: 'N' + type: "toggle", + optionsToggle: [ + { value: 0, label: 'No' }, + { value: 1, label: 'Yes' } + ] }, { key: "TimeOfDeath", label: "Time of Death", required: false, type: "datetime", validateOn: ["input"] } ] diff --git a/src/lib/components/patient/list/page/create-page.svelte b/src/lib/components/patient/list/page/create-page.svelte index 62c869d..0cbd972 100644 --- a/src/lib/components/patient/list/page/create-page.svelte +++ b/src/lib/components/patient/list/page/create-page.svelte @@ -68,7 +68,7 @@ disabled: formState.isSaving.current } ]; - // $inspect(formState.selectOptions) + $inspect(formState.errors) diff --git a/src/lib/components/patient/reusable/patient-form-renderer.svelte b/src/lib/components/patient/reusable/patient-form-renderer.svelte index 46f90a8..1cb5250 100644 --- a/src/lib/components/patient/reusable/patient-form-renderer.svelte +++ b/src/lib/components/patient/reusable/patient-form-renderer.svelte @@ -68,17 +68,18 @@ } let isDeathDateDisabled = $derived( - formState.form.isDead !== 'Y' + formState.form.isDead !== 1 && formState.form.isDead !== "1" ); $effect(() => { if (isDeathDateDisabled && formState.form.TimeOfDeath) { formState.form.TimeOfDeath = ""; + formState.errors.TimeOfDeath = null; } }); -{#snippet Fieldset({ key, label, required, type, optionsEndpoint, options, validateOn, dependsOn, endpointParamKey, valueKey, labelKey })} +{#snippet Fieldset({ key, label, required, type, optionsEndpoint, options, optionsToggle, validateOn, dependsOn, endpointParamKey, valueKey, labelKey })}
@@ -283,22 +284,27 @@ {/if}
{:else if type === "toggle"} -
- - - {#if formState.form.isDischarge} - - {:else} - - {/if} - {formState.form.isDischarge ? "Discharged" : "Active"} - -
+ {@const toggleOff = optionsToggle?.[0] ?? { value: false, label: 'Off' }} + {@const toggleOn = optionsToggle?.[1] ?? { value: true, label: 'On' }} + {@const isOn = String(formState.form[key]) === String(toggleOn.value)} +
+ { + formState.form[key] = pressed ? toggleOn.value : toggleOff.value; + }} + > + {#if isOn} + + {:else} + + {/if} + {isOn ? toggleOn.label : toggleOff.label} + +
{:else}