diff --git a/src/app/pharmacy/orders/page.tsx b/src/app/pharmacy/orders/page.tsx index 7dbdb95d..5e388f76 100644 --- a/src/app/pharmacy/orders/page.tsx +++ b/src/app/pharmacy/orders/page.tsx @@ -24,7 +24,7 @@ import { import toast from 'react-hot-toast'; import { fetchAllPatientMedicationOrders } from './api'; import { Switch } from '@/components/ui/switch'; -import Link from 'next/link'; +import { LoadingLink } from '@/components/LoadingLink'; type OrderRowData = { patient: { @@ -104,6 +104,38 @@ export default function OrdersPage() { return () => clearInterval(intervalId); }, [isAutoRefreshEnabled]); + const handleApproveOrRejectOrder = (orderId: number) => { + setOrderRowData(prev => + prev + .map(row => ({ + ...row, + data: row.data + .map(visit => ({ + ...visit, + orders: visit.orders.filter(order => order.order_id !== orderId), + })) + // Drop visits that no longer have any orders + .filter(visit => visit.orders.length > 0), + })) + // Drop patients that no longer have any visits + .filter(row => row.data.length > 0) + ); + + setFilteredOrderRowData(prev => + prev + .map(row => ({ + ...row, + data: row.data + .map(visit => ({ + ...visit, + orders: visit.orders.filter(order => order.order_id !== orderId), + })) + .filter(visit => visit.orders.length > 0), + })) + .filter(row => row.data.length > 0) + ); + }; + return (
@@ -180,7 +212,7 @@ export default function OrdersPage() { )) )} @@ -194,10 +226,10 @@ export default function OrdersPage() { function OrderRow({ orderRowData: { patient, data }, - removeNonPendingOrder, + onApproveOrRejectOrder, }: { orderRowData: OrderRowData; - removeNonPendingOrder: (id: number) => void; + onApproveOrRejectOrder: (id: number) => void; }) { const onPatchError = (err: Error, medicine_name: string) => { toast.error(() => ( @@ -220,9 +252,9 @@ function OrderRow({ {/* rowSpan is data.length + 1 because the current row has no data. */} {/* Hacky regex workaround cuz backend send patient_id with village prefix and padded zeroes*/} - @@ -240,7 +272,7 @@ function OrderRow({ height={80} width={80} /> - + {data.map(({ visit_id, visit_date, orders, diagnoses }) => ( @@ -296,7 +328,8 @@ function OrderRow({ onPatchError(new Error(r.error), o.medication_name); return; } - removeNonPendingOrder(o.order_id) + onApproveOrRejectOrder(o.order_id) + toast.success(`Order Approved`); }) }} handleCancelOrder={async () => { @@ -307,7 +340,8 @@ function OrderRow({ onPatchError(new Error(r.error), o.medication_name); return; } - removeNonPendingOrder(o.order_id) + onApproveOrRejectOrder(o.order_id) + toast.success(`Order Rejected`); }) }} /> diff --git a/src/app/records/patient-record/loading.tsx b/src/app/records/patient-record/loading.tsx new file mode 100644 index 00000000..8d70a230 --- /dev/null +++ b/src/app/records/patient-record/loading.tsx @@ -0,0 +1,7 @@ +export default function Loading() { + return ( +
+

Loading patient record...

+
+ ); +} diff --git a/src/components/LoadingLink.tsx b/src/components/LoadingLink.tsx new file mode 100644 index 00000000..ee65dbf8 --- /dev/null +++ b/src/components/LoadingLink.tsx @@ -0,0 +1,42 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { useTransition } from 'react'; + +export function LoadingLink({ + href, + children, + className, + ...props +}: { + href: string; + children: React.ReactNode; + className?: string; +}) { + const router = useRouter(); + const [isPending, startTransition] = useTransition(); + + return ( +
{ + e.preventDefault(); + startTransition(() => { + router.push(href); + }); + }} + className={`relative ${className}`} + > + {isPending && ( +
+
+

Loading...

+
+ )} + + {children} +
+ ); +} diff --git a/src/components/NavigationButtons.tsx b/src/components/NavigationButtons.tsx index 81fb9c22..e1eaff16 100644 --- a/src/components/NavigationButtons.tsx +++ b/src/components/NavigationButtons.tsx @@ -8,16 +8,17 @@ export function VitalsButton({ setIsHovered = () => {}, labelOverwrite, visitId, + className, }: { patient: Patient; setIsHovered?: Dispatch>; labelOverwrite?: string; visitId?: string; + className?: string; }) { - console.log(visitId) return ( e.stopPropagation()} onMouseEnter={e => { e.stopPropagation(); @@ -25,7 +26,11 @@ export function VitalsButton({ }} onMouseLeave={() => setIsHovered(true)} > -
); } diff --git a/src/components/records/document/ViewDocument.tsx b/src/components/records/document/ViewDocument.tsx index bc50ea71..c577c50c 100644 --- a/src/components/records/document/ViewDocument.tsx +++ b/src/components/records/document/ViewDocument.tsx @@ -109,12 +109,12 @@ export function ViewDocument({ }; return ( - <> +
); } diff --git a/src/components/records/patient/EditPatient.tsx b/src/components/records/patient/EditPatient.tsx index 0e018e3f..bc4b0d0a 100644 --- a/src/components/records/patient/EditPatient.tsx +++ b/src/components/records/patient/EditPatient.tsx @@ -23,13 +23,14 @@ export function EditPatient({ patient }: { patient: Patient }) { }, }); const router = useRouter(); + const [submitting, setSubmitting] = useState(false) return ( - <> +
); } diff --git a/src/components/records/patient/PatientForm.tsx b/src/components/records/patient/PatientForm.tsx index 4568b6c7..0bfeb143 100644 --- a/src/components/records/patient/PatientForm.tsx +++ b/src/components/records/patient/PatientForm.tsx @@ -154,6 +154,8 @@ export function PatientForm({ />
diff --git a/src/components/records/patient/PatientInfoHeaderSection.tsx b/src/components/records/patient/PatientInfoHeaderSection.tsx index c34984e2..5962192c 100644 --- a/src/components/records/patient/PatientInfoHeaderSection.tsx +++ b/src/components/records/patient/PatientInfoHeaderSection.tsx @@ -63,7 +63,7 @@ export function PatientInfoHeaderSection({ , {patient.name} -
+
{/*
*/} )} {showConsultationButton && ( @@ -85,6 +86,7 @@ export function PatientInfoHeaderSection({ patient={patient} labelOverwrite="Go to consultation" visitId={visitId} + className='w-44 sm:w-28' /> )}
diff --git a/src/components/records/vital/VitalsForm.tsx b/src/components/records/vital/VitalsForm.tsx index 4c00020c..ced2b4e7 100644 --- a/src/components/records/vital/VitalsForm.tsx +++ b/src/components/records/vital/VitalsForm.tsx @@ -11,7 +11,7 @@ import { NAOption } from '@/constants'; import { patchVital } from '@/data/vital/patchVital'; import { Patient } from '@/types/Patient'; import { displayBMI, validateVisualAcuity, Vital } from '@/types/Vital'; -import { FormEvent, useEffect } from 'react'; +import { useEffect } from 'react'; import { FieldValues, FormProvider, useForm } from 'react-hook-form'; import toast from 'react-hot-toast'; @@ -50,26 +50,9 @@ export function VitalsForm({ ? String(formWeight) : curVital.weight; - const submitVitalsFormHandler = (event: FormEvent) => { - event.preventDefault(); - - handleSubmit( - async (data: FieldValues) => { - data.visit_id = visitId; - patchVital(data as Vital).then(() => { - toast.success('Updated Vital'); - }); - }, - () => { - toast.error('Invalid/Missing Input'); - } - )(); - }; - return (

@@ -225,7 +208,27 @@ export function VitalsForm({ type="textarea" />
-