faiztyanirh 239147f7ec add feature and bug fix
patient list :
menambahkan client validation patientid boleh '.' dan '-'
fix isDeadLabel karena backend gamau ngeluarin valuenya

contact :
tambahkan guard pada handlesave
fix create contact gak nampilin detail di payload
fix edit contact updated ga nampil

occupation :
testing spinner untuk indikasi rowclick
testing close popover setelah save selesai
2026-04-13 18:06:07 +07:00

132 lines
5.3 KiB
Svelte

<script>
import { formatUTCDate } from "$lib/utils/formatUTCDate";
import { getUrl } from "$lib/utils/getUrl";
import { detailSections, viewActions } from "$lib/components/patient/list/config/patient-config";
import TopbarWrapper from "$lib/components/topbar/topbar-wrapper.svelte";
import ReusableEmpty from "$lib/components/reusable/reusable-empty.svelte";
let props = $props();
const { masterDetail, formFields, formActions, schema } = props.context;
let patient = $derived(masterDetail?.selectedItem?.patient);
const handlers = {
orderLab: () => console.log('order lab'),
medicalRecord: () => console.log('medical record'),
auditPatient: () => console.log('audit patient'),
editPatient: () => masterDetail.enterEdit("patient"),
};
const actions = viewActions(handlers);
let fullName = $derived.by(() => {
if (!patient) return "";
const first = patient.NameFirst || "";
const middle = patient.NameMiddle || "";
const last = patient.NameLast || "";
return `${first} ${middle} ${last}`.replace(/\s+/g, ' ').trim();
});
let prefix = $derived(
masterDetail?.selectedItem?.patient?.Prefix || null
);
function getFieldValue(field) {
if (!patient) return "-";
if (field.keys) {
return field.keys
.map(k => field.parentKey ? patient[field.parentKey]?.[k] : patient[k])
.filter(val => val && val.trim() !== "")
.join(" / ");
}
let value = field.parentKey ? patient[field.parentKey]?.[field.key] : patient[field.key];
if (field.valueMap && value != null) {
value = field.valueMap[value] ?? value;
}
// return field.parentKey ? patient[field.parentKey]?.[field.key] : patient[field.key];
return value;
}
</script>
{#snippet Fieldset({ value, label, className = '', isUTCDate = false, isFileList = false })}
<div class={`space-y-1.5 ${className}`}>
<dt class="text-xs font-medium text-muted-foreground uppercase tracking-wider">
{label}
</dt>
<dd class="text-sm font-medium">
{#if isFileList && Array.isArray(value)}
<div class="flex flex-col gap-1">
{#each value as item}
<div class="flex gap-2 items-center">
<a href={getUrl(item.Address)} target="_blank">
<div
class="w-10 h-10 object-cover border p-1 border-dashed border-2 border-primary rounded flex justify-center items-center"
>
{#if item.Address.endsWith(".jpg") || item.Address.endsWith(".png") || item.Address.endsWith(".PNG")}
<img
src={getUrl(item.Address)}
alt="preview"
class="max-w-full max-h-full object-cover"
/>
{:else}
<i class="fa-solid fa-file fa-xl"></i>
{/if}
</div>
</a>
<span class="text-xs break-all">{item.Address.split("/").pop()}</span>
</div>
{/each}
</div>
{:else if Array.isArray(value)}
{#each value as item, i}
<span>{item.PatientID || item.Identifier || JSON.stringify(item)}{i < value.length - 1 ? ', ' : ''}</span>
{/each}
{:else if isUTCDate}
{formatUTCDate(value)}
{:else}
{value ?? "-"}
{/if}
</dd>
</div>
{/snippet}
{#if masterDetail.selectedItem}
<div class="flex flex-col px-2 py-1 gap-2 h-full w-full">
<TopbarWrapper title={fullName} subtitle={prefix} {actions} />
<div class="flex-1 min-h-0 overflow-y-auto space-y-4">
{#each detailSections as section}
<div class="p-4">
<div class={section.class}>
{#each section.fields as field}
{#if field.isGroup}
<div class={field.class}>
{#each field.fields as subField}
{@render Fieldset({
label: subField.label,
value: getFieldValue(subField)
})}
{/each}
</div>
{:else}
{@render Fieldset({
label: field.label,
value: getFieldValue(field),
className: field.className,
isUTCDate: field.isUTCDate,
isFileList: field.isFileList
})}
{/if}
{/each}
</div>
</div>
{/each}
</div>
</div>
{:else}
<ReusableEmpty desc="Select a patient to see details"/>
{/if}