clqms-fe1/src/routes/(app)/patients/OrderList.svelte

128 lines
3.9 KiB
Svelte

<script>
import { Plus, FileText, RefreshCw } from 'lucide-svelte';
import OrderCard from './OrderCard.svelte';
import { formatPatientName } from '$lib/utils/patients.js';
/**
* @typedef {Object} Patient
* @property {string} InternalPID
* @property {string} PatientID
* @property {string} [FullName]
* @property {string} [Prefix]
* @property {string} [NameFirst]
* @property {string} [NameMiddle]
* @property {string} [NameLast]
*/
/**
* @typedef {Object} Order
* @property {string} [OrderID]
* @property {string} [OrderNumber]
* @property {string} [Status]
* @property {string} [TestName]
*/
/** @type {{
* patient: Patient | null,
* orders: Order[],
* loading: boolean,
* onCreateOrder: () => void,
* onViewOrder: (order: Order) => void,
* onPrintBarcode: (order: Order) => void,
* onRefresh: () => void
* }} */
let {
patient = null,
orders = [],
loading = false,
onCreateOrder,
onViewOrder,
onPrintBarcode,
onRefresh
} = $props();
let patientName = $derived(formatPatientName(patient));
let hasOrders = $derived(orders.length > 0);
</script>
<div class="bg-base-100 rounded-lg shadow border border-base-200 flex flex-col h-full overflow-hidden">
{#if patient}
<!-- Patient Header -->
<div class="p-3 bg-base-200 border-b border-base-200">
<div class="flex items-center justify-between">
<div class="min-w-0 flex-1">
<h3 class="font-bold text-base truncate" title={patientName}>
{patientName}
</h3>
<p class="text-xs text-gray-600">ID: {patient.PatientID}</p>
</div>
<div class="flex gap-1 ml-2">
<button
class="btn btn-sm btn-ghost"
title="Refresh"
onclick={onRefresh}
disabled={loading}
>
<RefreshCw class="w-4 h-4" />
</button>
<button
class="btn btn-primary btn-sm"
onclick={onCreateOrder}
>
<Plus class="w-4 h-4 mr-1" />
New Order
</button>
</div>
</div>
</div>
<!-- Orders List -->
<div class="flex-1 overflow-auto p-3">
{#if loading}
<div class="flex items-center justify-center py-12">
<span class="loading loading-spinner loading-lg text-primary"></span>
</div>
{:else if !hasOrders}
<div class="text-center py-12 text-gray-500">
<FileText class="w-12 h-12 mx-auto mb-3 opacity-50" />
<p class="text-base">No orders found</p>
<p class="text-sm mt-1">This patient has no lab orders.</p>
<button
class="btn btn-primary btn-sm mt-4"
onclick={onCreateOrder}
>
<Plus class="w-4 h-4 mr-1" />
Create First Order
</button>
</div>
{:else}
<!-- Compact Orders Table Header -->
<div class="flex items-center py-1 px-2 text-xs font-medium text-gray-500 border-b border-base-300 bg-base-100">
<span class="w-24">Order #</span>
<span class="w-24">Date</span>
<span class="flex-1">Doctor</span>
<span class="w-8"></span>
</div>
<div class="divide-y divide-base-200">
{#each orders as order (order.OrderID || order.OrderNumber)}
<OrderCard
{order}
onView={() => onViewOrder(order)}
onPrintBarcode={() => onPrintBarcode(order)}
/>
{/each}
</div>
{/if}
</div>
{:else}
<!-- Empty State -->
<div class="flex-1 flex items-center justify-center text-gray-500 p-6">
<div class="text-center">
<FileText class="w-16 h-16 mx-auto mb-4 opacity-50" />
<p class="text-lg">Select a patient</p>
<p class="text-sm">Click a patient to view lab orders</p>
</div>
</div>
{/if}
</div>