diff --git a/src/lib/api/api-client.js b/src/lib/api/api-client.js index 15d48e6..94e4798 100644 --- a/src/lib/api/api-client.js +++ b/src/lib/api/api-client.js @@ -95,7 +95,6 @@ export async function searchWithPath(endpoint, searchQuery) { } export async function create(endpoint, formData) { - console.log(cleanEmptyStrings(formData)); try { const res = await fetch(`${API.BASE_URL}${endpoint}`, { method: 'POST', @@ -115,19 +114,19 @@ export async function create(endpoint, formData) { export async function update(endpoint, formData) { console.log(cleanEmptyStrings(formData)); - try { - const res = await fetch(`${API.BASE_URL}${endpoint}`, { - method: 'PATCH', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(cleanEmptyStrings(formData)) - }); + // try { + // const res = await fetch(`${API.BASE_URL}${endpoint}`, { + // method: 'PATCH', + // headers: { + // 'Content-Type': 'application/json', + // }, + // body: JSON.stringify(cleanEmptyStrings(formData)) + // }); - const data = await res.json(); - return data; - } catch (err) { - console.error('Update Error:', err.message); - return { success: false, message: err.message || 'Network error' }; - } + // const data = await res.json(); + // return data; + // } catch (err) { + // console.error('Update Error:', err.message); + // return { success: false, message: err.message || 'Network error' }; + // } } \ No newline at end of file diff --git a/src/lib/components/app-sidebar.svelte b/src/lib/components/app-sidebar.svelte index fa7fbe1..2c34fd9 100644 --- a/src/lib/components/app-sidebar.svelte +++ b/src/lib/components/app-sidebar.svelte @@ -2,6 +2,10 @@ import ChartPieIcon from "@lucide/svelte/icons/chart-pie"; import FrameIcon from "@lucide/svelte/icons/frame"; import LifeBuoyIcon from "@lucide/svelte/icons/life-buoy"; + import ChartColumnIcon from "@lucide/svelte/icons/chart-column"; + import UserIcon from "@lucide/svelte/icons/user"; + import ReceiptTextIcon from "@lucide/svelte/icons/receipt-text"; + import BookOpenIcon from "@lucide/svelte/icons/book-open"; import MapIcon from "@lucide/svelte/icons/map"; import SendIcon from "@lucide/svelte/icons/send"; import Settings2Icon from "@lucide/svelte/icons/settings-2"; @@ -17,12 +21,12 @@ { title: "Dashboard", url: "/", - icon: LifeBuoyIcon, + icon: ChartColumnIcon, }, { title: "Patient", url: "/patient", - icon: LifeBuoyIcon, + icon: UserIcon, submenus: [ { title: "Patient List", @@ -37,7 +41,7 @@ { title: "Order", url: "/order", - icon: LifeBuoyIcon, + icon: ReceiptTextIcon, submenus: [ { title: "Test Order", @@ -50,7 +54,7 @@ { title: "Admission", url: "/admission", - icon: LifeBuoyIcon, + icon: BookOpenIcon, submenus: [ { title: "Contact", @@ -69,7 +73,7 @@ { title: "Value", url: "#", - icon: LifeBuoyIcon, + icon: BookOpenIcon, submenus: [ { title: "Value Set Def", @@ -84,7 +88,7 @@ { title: "Sample", url: "#", - icon: LifeBuoyIcon, + icon: BookOpenIcon, submenus: [ { title: "Container", @@ -95,7 +99,7 @@ { title: "Organization", url: "#", - icon: LifeBuoyIcon, + icon: BookOpenIcon, submenus: [ { title: "Account", @@ -122,7 +126,7 @@ { title: "Test", url: "#", - icon: LifeBuoyIcon, + icon: BookOpenIcon, submenus: [ { title: "Test Site", diff --git a/src/lib/components/composable/use-form.svelte.js b/src/lib/components/composable/use-form.svelte.js index 1e95610..e770d7b 100644 --- a/src/lib/components/composable/use-form.svelte.js +++ b/src/lib/components/composable/use-form.svelte.js @@ -7,12 +7,13 @@ export function useForm({schema, initialForm, defaultErrors, mode, modeOpt, save const val = useFormValidation(schema, state.form, defaultErrors, mode); const options = useFormOptions(modeOpt); - async function save() { + async function save(currentMode, customPayload = null) { state.isSaving.current = true try { - const payload = { ...state.form }; - const result = mode === 'edit' ? await editEndpoint(payload) : await saveEndpoint(payload) + // const payload = { ...state.form }; + const payload = customPayload || { ...state.form }; + const result = currentMode === 'edit' ? await editEndpoint(payload) : await saveEndpoint(payload); return result; } catch (error) { console.error('Save failed', error); diff --git a/src/lib/components/composable/use-master-detail.svelte.js b/src/lib/components/composable/use-master-detail.svelte.js index d5ba59b..7915834 100644 --- a/src/lib/components/composable/use-master-detail.svelte.js +++ b/src/lib/components/composable/use-master-detail.svelte.js @@ -42,21 +42,20 @@ export function useMasterDetail(options = {}) { } } -function enterCreate(initialData = null) { - mode = "create"; - selectedItem = null; + function enterCreate(initialData = null) { + mode = "create"; + selectedItem = null; - formState.reset(); + formState.reset(); - if (initialData) { - formState.setForm({ - ...formState.form, - ...initialData - }); + if (initialData) { + formState.setForm({ + ...formState.form, + ...initialData + }); + } } -} - function enterEdit(mapToForm = null) { if (!selectedItem) return; mode = "edit"; @@ -74,9 +73,6 @@ function enterCreate(initialData = null) { } function exitForm() { - // const confirmed = confirm('You have unsaved changes. Are you sure you want to exit?'); - // if (!confirmed) return; - mode = "view"; selectedItem = null; } @@ -87,12 +83,10 @@ function enterCreate(initialData = null) { } function saveForm() { - // Commit changes (mark as saved) formSnapshot = { ...form }; } return { - // State get selectedItem() { return selectedItem; }, @@ -127,7 +121,6 @@ function enterCreate(initialData = null) { return formState; }, - // Actions select, enterCreate, enterEdit, diff --git a/src/lib/components/patient/admission/config/admission-config.js b/src/lib/components/patient/admission/config/admission-config.js index e1941f4..4153e94 100644 --- a/src/lib/components/patient/admission/config/admission-config.js +++ b/src/lib/components/patient/admission/config/admission-config.js @@ -41,7 +41,7 @@ export const searchFields = [ export const detailSections = [ { - title: "", // No title for top row + title: "", class: "grid grid-cols-1 md:grid-cols-2 gap-4", groups: [ { @@ -84,10 +84,6 @@ export function admissionActions(masterDetail, selectedPatient) { { Icon: PlusIcon, label: 'Add Visit', - // onClick: masterDetail.enterCreate({ - // PatientID: selectedPatient?.PatientID, - // InternalPID: selectedPatient?.InternalPID - // }), onClick: () => masterDetail.enterCreate({ PatientID: selectedPatient?.PatientID, InternalPID: selectedPatient?.InternalPID @@ -108,7 +104,6 @@ export function viewActions(handlers){ Icon: PencilIcon, label: 'Edit Patient', onClick: handlers.editPatient, - }, ] } \ No newline at end of file diff --git a/src/lib/components/patient/admission/config/admission-form-config.js b/src/lib/components/patient/admission/config/admission-form-config.js index 3a1348e..09ee352 100644 --- a/src/lib/components/patient/admission/config/admission-form-config.js +++ b/src/lib/components/patient/admission/config/admission-form-config.js @@ -18,6 +18,7 @@ export const admissionInitialForm = { RefDoc: "", AdmDoc: "", CnsDoc: "", + isDischarge: false }; export const admissionDefaultErrors = {}; @@ -131,7 +132,7 @@ export const admissionFormFields = [ optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/service_classes`, }, { - key: "Discharge", + key: "isDischarge", label: "Discharge Status", required: false, type: "toggle", diff --git a/src/lib/components/patient/admission/config/admission-payload.js b/src/lib/components/patient/admission/config/admission-payload.js new file mode 100644 index 0000000..7bbfb0e --- /dev/null +++ b/src/lib/components/patient/admission/config/admission-payload.js @@ -0,0 +1,105 @@ +import { cleanEmptyStrings } from "$lib/utils/cleanEmptyStrings"; + +const ADT_CODE_MAP = { + LocationID: "A02", + AttDoc: "A54", + RefDoc: "A08", + AdmDoc: "A08", + CnsDoc: "A61", + isDischarge: "A03", +}; + +export function compareAdmissionData(oldData, newData) { + let diffs = []; + let current = { ...oldData }; + let sequence = 1; + + for (const key in ADT_CODE_MAP) { + // Skip if field tidak ada atau tidak berubah + if (!Object.hasOwn(oldData, key) || oldData[key] === newData[key]) { + continue; + } + + // Track discharge status + const originalisDischarge = !!oldData.isDischarge; + const newisDischarge = !!newData.isDischarge; + + // Update current state + current[key] = newData[key]; + + // Build diff entry + const filtered = Object.fromEntries( + Object.keys(ADT_CODE_MAP).map((k) => [k, current[k]]) + ); + + diffs.push({ + sequence: sequence++, + code: ADT_CODE_MAP[key], + originalisDischarge, + isDischarge: newisDischarge, + ...filtered, + }); + } + return diffs; +} + +export function buildEditAdmissionPayload(form, diffs = []) { + const base = { + InternalPVID: form.InternalPVID, + PVID: form.PVID, + EpisodeID: form.EpisodeID, + InternalPID: form.InternalPID, + PatDiag: { + DiagCode: form.DiagCode || null, + Diagnosis: form.Diagnosis || null, + }, + }; + + // No changes, return empty PatVisitADT + if (!diffs.length) { + return { + ...base, + PatVisitADT: [], + }; + } + + // Map diffs ke PatVisitADT entries + const PatVisitADT = diffs.map(diff => { + // Determine ADTCode based on discharge status + let ADTCode; + if (diff.isDischarge) { + ADTCode = "A03"; // Discharge + } else if (diff.originalisDischarge) { + ADTCode = "A13"; // Cancel discharge + } else { + ADTCode = diff.code; // Normal update + } + + return { + sequence: diff.sequence, + ADTCode, + LocationID: diff.LocationID || null, + AttDoc: diff.AttDoc || null, + RefDoc: diff.RefDoc || null, + AdmDoc: diff.AdmDoc || null, + CnsDoc: diff.CnsDoc || null, + }; + }); + + return { ...base, PatVisitADT }; +} + +export function buildEditPayloadWithDiff(originalData, formData) { + // Clean data + const cleanedForm = cleanEmptyStrings(formData); + const cleanedOriginal = cleanEmptyStrings(originalData); + + // Compare & get diffs + const diffs = compareAdmissionData(cleanedOriginal, cleanedForm); + console.log(formData); + + // Build payload + const payload = buildEditAdmissionPayload(cleanedForm, diffs); + + return cleanEmptyStrings(payload); +} \ No newline at end of file diff --git a/src/lib/components/patient/admission/page/create-page copy.svelte b/src/lib/components/patient/admission/page/create-page copy.svelte new file mode 100644 index 0000000..e2d3153 --- /dev/null +++ b/src/lib/components/patient/admission/page/create-page copy.svelte @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/src/lib/components/patient/admission/page/create-page.svelte b/src/lib/components/patient/admission/page/create-page.svelte index e2d3153..e92ac9e 100644 --- a/src/lib/components/patient/admission/page/create-page.svelte +++ b/src/lib/components/patient/admission/page/create-page.svelte @@ -1,24 +1,17 @@
@@ -22,11 +44,11 @@ {#if masterDetail.showDetail}
{#if masterDetail.mode === "view"} - + {:else if masterDetail.mode === "create"} - + {:else if masterDetail.mode === "edit"} - + {/if}
{/if} diff --git a/src/routes/patient/list/+page.svelte b/src/routes/patient/list/+page.svelte index ed75c7a..d3870d8 100644 --- a/src/routes/patient/list/+page.svelte +++ b/src/routes/patient/list/+page.svelte @@ -30,7 +30,7 @@ schema: patientSchema, initialForm: patientInitialForm, defaultErrors: { - create: patientDefaultErrors, + create: patientDefaultErrors, edit: {} } }