diff --git a/src/lib/components/composable/use-form-option.svelte.js b/src/lib/components/composable/use-form-option.svelte.js
index 67deb3c..603169e 100644
--- a/src/lib/components/composable/use-form-option.svelte.js
+++ b/src/lib/components/composable/use-form-option.svelte.js
@@ -8,8 +8,17 @@ const optionsMode = {
const res = await fetch(field.optionsEndpoint);
const json = await res.json();
- selectOptions[field.key] = json?.data ?? [];
+ // selectOptions[field.key] = json?.data ?? [];
+ const data = json?.data ?? [];
+ const valueKey = field.valueKey ?? 'value';
+ const labelKey = field.labelKey ?? 'label';
+
+ selectOptions[field.key] = data.map((item) => ({
+ value: item[valueKey],
+ label: typeof labelKey === 'function' ? labelKey(item) : item[labelKey],
+ }));
+console.log(selectOptions);
} catch (err) {
console.error("Failed to fetch options for", field.key, err);
selectOptions[field.key] = [];
@@ -52,8 +61,17 @@ const optionsMode = {
const res = await fetch(endpoint);
const json = await res.json();
- selectOptions[field.key] = json?.data ?? [];
+ // selectOptions[field.key] = json?.data ?? [];
+ const data = json?.data ?? [];
+ const valueKey = field.valueKey ?? 'value';
+ const labelKey = field.labelKey ?? 'label';
+
+ selectOptions[field.key] = data.map((item) => ({
+ value: item[valueKey],
+ label: typeof labelKey === 'function' ? labelKey(item) : item[labelKey],
+ }));
+console.log(selectOptions);
// Track last fetched parent value for dependent fields
if (field.dependsOn) {
lastFetched[field.key] = parentValue;
diff --git a/src/lib/components/patient/admission/api/patient-admission-api.js b/src/lib/components/patient/admission/api/patient-admission-api.js
index 8d612bf..8b2d0ed 100644
--- a/src/lib/components/patient/admission/api/patient-admission-api.js
+++ b/src/lib/components/patient/admission/api/patient-admission-api.js
@@ -13,17 +13,10 @@ export async function getVisit(searchQuery) {
return await getById(API.PATVISIT, searchQuery)
}
-export async function getPatient(searchQuery) {
- const { data: patient, error } = await getById(API.PATIENTS, searchQuery)
- return { patient };
+export async function createAdmission(newAdmissionForm) {
+ return await create(API.PATVISIT, newAdmissionForm)
}
-export async function createPatient(newContactForm) {
- // console.log(JSON.stringify(newContactForm));
- return await create(API.PATIENTS, newContactForm)
-}
-
-export async function editPatient(editContactForm) {
- // console.log(JSON.stringify(editContactForm));
- return await update(API.PATIENTS, editContactForm)
+export async function editAdmission(editAdmissionForm) {
+ return await update(API.PATVISIT, editAdmissionForm)
}
\ No newline at end of file
diff --git a/src/lib/components/patient/admission/config/admission-config.js b/src/lib/components/patient/admission/config/admission-config.js
index c4b8229..70275fd 100644
--- a/src/lib/components/patient/admission/config/admission-config.js
+++ b/src/lib/components/patient/admission/config/admission-config.js
@@ -1,5 +1,6 @@
import PlusIcon from "@lucide/svelte/icons/plus";
import Settings2Icon from "@lucide/svelte/icons/settings-2";
+import PencilIcon from "@lucide/svelte/icons/pencil";
export const searchFields = [
{
@@ -38,6 +39,66 @@ export const searchFields = [
},
];
+// export const detailSections = [
+// {
+// class: "grid grid-cols-1 sm:grid-cols-2 gap-3",
+// fields: [
+// { key: "PVID", label: "Visit ID" },
+// { key: "EpisodeID", label: "Episode ID" },
+// { key: "", label: "Visit Class" },
+// { key: "", label: "Service Class" },
+// { key: "LocationID", label: "Location" },
+// { key: "AttDoc", label: "Attending Doctor" },
+// { key: "RefDoc", label: "Reffering Doctor" },
+// { key: "AdmDoc", label: "Admitting Doctor" },
+// { key: "CnsDoc", label: "Consulting Doctor" },
+// { key: "", label: "Admission Date", isUTCDate: true },
+// { key: "", label: "Discharge Date", isUTCDate: true },
+// { key: "Diagnosis", label: "Clinical Diagnosis" },
+// ]
+// },
+// ]
+
+export const detailSections = [
+ {
+ title: "", // No title for top row
+ class: "grid grid-cols-1 md:grid-cols-2 gap-4",
+ groups: [
+ {
+ class: "space-y-3",
+ fields: [
+ { key: "PVID", label: "Visit ID" },
+ { key: "EpisodeID", label: "Episode ID" },
+ { key: "VisitClass", label: "Visit Class" },
+ { key: "ServiceClass", label: "Service Class" },
+ ]
+ },
+ {
+ class: "space-y-3",
+ fields: [
+ { key: "LocationID", label: "Location" },
+ { key: "AttDoc", label: "Attending Doctor" },
+ { key: "RefDoc", label: "Referring Doctor" },
+ { key: "AdmDoc", label: "Admitting Doctor" },
+ { key: "CnsDoc", label: "Consulting Doctor" },
+ ]
+ }
+ ]
+ },
+ {
+ class: "grid grid-cols-2 gap-4 items-center",
+ fields: [
+ { key: "AdmissionDate", label: "Admission Date", isUTCDate: true },
+ { key: "DischargeDate", label: "Discharge Date", isUTCDate: true },
+ ]
+ },
+ {
+ fields: [
+ { key: "Diagnosis", label: "Clinical Diagnosis" },
+ ]
+ }
+];
+
export function admissionActions(masterDetail) {
return [
{
@@ -51,4 +112,15 @@ export function admissionActions(masterDetail) {
popoverWidth: "w-256",
},
];
+}
+
+export function viewActions(handlers){
+ return [
+ {
+ 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 e69de29..0bfd68e 100644
--- a/src/lib/components/patient/admission/config/admission-form-config.js
+++ b/src/lib/components/patient/admission/config/admission-form-config.js
@@ -0,0 +1,209 @@
+import { API } from "$lib/config/api";
+import EraserIcon from "@lucide/svelte/icons/eraser";
+import { z } from "zod";
+
+export const admissionSchema = z.object({});
+
+export const admissionInitialForm = {
+ InternalPVID: "",
+ InternalPID: "",
+ PVID: "",
+ EpisodeID: "",
+ DiagCode: "",
+ Diagnosis: "",
+ ADTCode: "",
+ LocationID: "",
+ AttDoc: "",
+ RefDoc: "",
+ AdmDoc: "",
+ CnsDoc: "",
+};
+
+export const admissionDefaultErrors = {};
+
+export const admissionFormFields = [
+ {
+ title: "Visit Information",
+ rows: [
+ {
+ type: "row",
+ columns: [
+ {
+ key: "PVID",
+ label: "Visit ID",
+ required: false,
+ type: "text",
+ },
+ {
+ key: "EpisodeID",
+ label: "Episode ID",
+ required: false,
+ type: "text",
+ }
+ ]
+ }
+ ]
+ },
+ {
+ title: "Medical Team",
+ rows: [
+ {
+ type: "row",
+ columns: [
+ {
+ key: "AttDoc",
+ label: "Attended Doctor",
+ required: false,
+ type: "select",
+ optionsEndpoint: `${API.BASE_URL}${API.CONTACT}`,
+ valueKey: "ContactID",
+ labelKey: (item) => `${item.Initial} - ${item.NameFirst} ${item.NameLast}`,
+ },
+ {
+ key: "RefDoc",
+ label: "Reference Doctor",
+ required: false,
+ type: "select",
+ optionsEndpoint: `${API.BASE_URL}${API.CONTACT}`,
+ valueKey: "ContactID",
+ labelKey: (item) => `${item.Initial} - ${item.NameFirst} ${item.NameLast}`,
+ }
+ ]
+ },
+ {
+ type: "row",
+ columns: [
+ {
+ key: "AdmDoc",
+ label: "Admitted Doctor",
+ required: false,
+ type: "select",
+ optionsEndpoint: `${API.BASE_URL}${API.CONTACT}`,
+ valueKey: "ContactID",
+ labelKey: (item) => `${item.Initial} - ${item.NameFirst} ${item.NameLast}`,
+ },
+ {
+ key: "CnsDoc",
+ label: "Consulte Doctor",
+ required: false,
+ type: "select",
+ optionsEndpoint: `${API.BASE_URL}${API.CONTACT}`,
+ valueKey: "ContactID",
+ labelKey: (item) => `${item.Initial} - ${item.NameFirst} ${item.NameLast}`,
+ }
+ ]
+ }
+ ]
+ },
+ {
+ title: "Visit Classification",
+ rows: [
+ {
+ type: "row",
+ columns: [
+ {
+ key: "LocationID",
+ label: "Location",
+ required: false,
+ type: "select",
+ optionsEndpoint: `${API.BASE_URL}${API.LOCATION}`,
+ valueKey: "LocationID",
+ labelKey: (item) => `${item.LocCode} - ${item.LocFull}`,
+ },
+ {
+ key: "VisitClass",
+ label: "Visit Class",
+ required: false,
+ type: "select",
+ optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/visit_classes`,
+ }
+ ]
+ },
+ {
+ type: "row",
+ columns: [
+ {
+ key: "ServiceClass",
+ label: "Service Class",
+ required: false,
+ type: "select",
+ optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/service_classes`,
+ },
+ {
+ key: "Discharge",
+ label: "Discharge Status",
+ required: false,
+ type: "toggle",
+ defaultValue: false,
+ }
+ ]
+ }
+ ]
+ },
+ {
+ title: "Clinical Information",
+ rows: [
+ {
+ type: "row",
+ columns: [
+ {
+ key: "Diagnosis",
+ label: "Diagnosis",
+ required: false,
+ type: "textarea",
+ rows: 4,
+ maxLength: 1000,
+ }
+ ]
+ }
+ ]
+ }
+];
+
+export function getAdmissionFormActions(handlers) {
+ return [
+ {
+ Icon: EraserIcon,
+ label: 'Clear Form',
+ onClick: handlers.clearForm,
+ },
+ ];
+}
+
+const admissionTemplate = {
+ PVID: 'PVID',
+ InternalPID: 'InternalPID',
+ EpisodeID: 'EpisodeID',
+ PatDiag: {
+ DiagCode: 'DiagCode',
+ Diagnosis: 'Diagnosis',
+ },
+ PatVisitADT: {
+ ADTCode: () => 'A04',
+ LocationID: 'LocationID',
+ AttDoc: 'AttDoc',
+ RefDoc: 'RefDoc',
+ AdmDoc: 'AdmDoc',
+ CnsDoc: 'CnsDoc',
+ },
+};
+
+export function buildPayload(form, schema = admissionTemplate) {
+ const payload = {};
+
+ for (const [key, config] of Object.entries(schema)) {
+ if (typeof config === 'string') {
+ // Kirim nilai dari form, atau null jika tidak ada (agar key tetap ada)
+ payload[key] = form[config] ?? null;
+ }
+ else if (typeof config === 'function') {
+ payload[key] = config(form);
+ }
+ else if (typeof config === 'object' && config !== null) {
+ // Rekursif tanpa pengecekan panjang keys, agar objek nested selalu dibuat
+ payload[key] = buildPayload(form, config);
+ }
+ }
+
+ return payload;
+}
\ 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 4649907..a1d7b32 100644
--- a/src/lib/components/patient/admission/page/create-page.svelte
+++ b/src/lib/components/patient/admission/page/create-page.svelte
@@ -1 +1,60 @@
-cr
\ No newline at end of file
+
+
+