import {modals} from "@mantine/modals";
import React, {useMemo, useState, useEffect} from "react";
import {
ActionIcon,
Button, Checkbox,
type ComboboxItem, CopyButton,
Group,
NumberInput,
type OptionsFilter, Radio,
Select,
Stack,
Text,
TextInput, Tooltip,
Table,
MultiSelect,
Textarea
} from "@mantine/core";
import {
apiAdminRegister,
apiCreateWard,
apiDeleteWard,
apiEditDoctorInfo,
apiEditWard,
apiResetPasswordFromRoleID,
apiSetDoctorResigned,
apiDeleteTeam,
apiCreateTeam,
apiEditTeam,
apiPatientBooking,
apiEditPatientBooking,
apiDeletePatientBooking,
apiGetTeamList,
apiProcessAppointment,
apiPatientAdmission,
apiGetWardList,
apiEditPatientInfo,
apiPatientDischarge
} from "~/utils/hms_api.ts";
import {parseDmyToDate, showErrorMessage, showInfoMessage, timestampToDate} from "~/utils/utils.ts";
import {
type DoctorDataWithPermission,
type WardInfo,
WardTypes,
type DoctorTeamInfo,
type PatientBookingInfo,
type PatientDataWithWardAndAdmission, type PatientData, type DoctorData
} from "~/utils/models.ts";
import {useForm} from "@mantine/form";
import {iconMStyle} from "~/styles.ts";
import RenameIcon from "mdi-react/RenameIcon";
import HumanEditIcon from "mdi-react/HumanEditIcon";
import WardPatients from "~/components/subs/WardPatients.tsx";
import {DoctorGrade, Departments, BookingCategory} from "~/utils/hms_enums.ts";
import {DateInput, DateTimePicker} from "@mantine/dates";
import CalendarIcon from "mdi-react/CalendarIcon";
import PhoneIcon from "mdi-react/PhoneIcon";
import MailIcon from "mdi-react/MailIcon";
import GenderMaleFemaleIcon from "mdi-react/GenderMaleFemaleIcon";
import AlphaGIcon from "mdi-react/AlphaGIcon";
import HomeIcon from "mdi-react/HomeIcon";
import CheckIcon from "mdi-react/CheckIcon";
import ContentCopyIcon from "mdi-react/ContentCopyIcon";
export function confirmDeleteWard(wardId: number, wardName: String, onFinished: () => void = () => {}) {
const onClickConfirmDeleteWard = (wardId: number) => {
apiDeleteWard(wardId).then(res => {
if (res.success) {
showInfoMessage("", "Ward deleted successfully", 3000)
} else {
showErrorMessage(res.message, "Delete Ward Failed")
}
}).catch(err => {
showErrorMessage(err.toString(), "Delete Ward Failed")
}).finally(() => onFinished())
modals.closeAll()
}
modals.open({
title: "Delete Ward",
centered: true,
children: (
Are you sure you want to delete the ward: {wardName}?
)
})
}
export function confirmEditOrCreateWard(origWardInfo: WardInfo | null, onSucceed: () => void = () => {}) {
function ConfirmEditOrCreateWard({wardInfo}: {wardInfo: WardInfo | null}) {
const form = useForm({
initialValues: {
ward_id: wardInfo ? wardInfo.id : -1,
ward_name: wardInfo ? wardInfo.name : "",
total_capacity: wardInfo ? wardInfo.total_capacity : 0,
type: wardInfo ? wardInfo.type : "GENERAL"
},
validate: {
ward_name: (value) => (value.length == 0 ? "Input ward name." : null),
total_capacity: (value) => (value < 1 ? "Total capacity must be greater than 0." : null),
},
});
const optionsFilter: OptionsFilter = ({ options, search }) => {
const filtered = (options as ComboboxItem[]).filter((option) =>
option.label.toLowerCase().trim().includes(search.toLowerCase().trim())
);
filtered.sort((a, b) => a.label.localeCompare(b.label));
return filtered;
}
const wardTypesOptions = useMemo(() => {
return Object.entries(WardTypes).map(([key, value]) => ({ value: key, label: value }))
}, [WardTypes])
const onClickConfirmEditWard = (values: {ward_id: number, ward_name: string, total_capacity: number, type: string}) => {
if (origWardInfo) {
apiEditWard(values.ward_id, values.ward_name, values.total_capacity, values.type).then(res => {
if (res.success) {
modals.closeAll()
showInfoMessage("", "Ward edited successfully", 3000)
onSucceed()
} else {
showErrorMessage(res.message, "Edit Ward Failed")
}
}).catch(err => {
showErrorMessage(err.toString(), "Edit Ward Failed")
})
} else {
apiCreateWard(values.ward_name, values.total_capacity, values.type).then(res => {
if (res.success) {
modals.closeAll()
showInfoMessage("", "Ward created successfully", 3000)
onSucceed()
} else {
showErrorMessage(res.message, "Create Ward Failed")
}
}).catch(err => {
showErrorMessage(err.toString(), "Create Ward Failed")
})
}
}
return (
)
}
modals.open({
title: origWardInfo ? "Edit Ward" : "Create Ward",
centered: true,
children: (
)
})
}
export function confirmCheckWardPatients(origWardId: number, onChanged: () => void = () => {}) {
modals.open({
title: "Ward Patients",
centered: true,
size: "70%",
children: (
)
})
}
export function confirmEditDoctor(
origDoctorInfo: DoctorDataWithPermission,
onSucceed: () => void = () => {},
) {
function ConfirmEditOrCreateDoctor({
doctorInfo,
}: {
doctorInfo: DoctorDataWithPermission;
}) {
const form = useForm({
initialValues: {
id: doctorInfo ? doctorInfo.id : -1,
name: doctorInfo ? doctorInfo.name : '',
email: doctorInfo ? doctorInfo.email : '',
phone: doctorInfo ? doctorInfo.phone : '',
gender: doctorInfo ? doctorInfo.gender : 'M',
birth_date: doctorInfo ? parseDmyToDate(doctorInfo.birth_date) : new Date(2000, 1, 1),
title: doctorInfo ? doctorInfo.title : '',
grade: doctorInfo ? doctorInfo.grade.toString() : DoctorGrade.Unknown.toString(),
is_admin: doctorInfo ? doctorInfo.is_admin : false
},
validate: {
name: (v) => (v.length === 0 ? 'Input doctor name.' : null),
email: (v) =>
/^\S+@\S+\.\S+$/.test(v) ? null : 'Incorrect email address.',
phone: (v) =>
v.length === 0 || /^\+?\d{6,15}$/.test(v)
? null
: 'Invalid phone number.',
birth_date: (v) => (v > new Date() ? 'Date of birth cannot be in the future' : null),
gender: (v) => (v.length === 0 ? "Select a gender" : null)
},
});
const genderOptions = useMemo(
() => [
{ value: 'M', label: 'Male' },
{ value: 'F', label: 'Female' },
{ value: 'Intersex', label: 'Intersex' },
],
[],
);
const gradeOptions = useMemo(
() =>
Object.entries(DoctorGrade)
.filter(([k]) => isNaN(Number(k)))
.map(([k, v]) => ({
value: v.toString(),
label: k,
})),
[],
);
const optionsFilter: OptionsFilter = ({ options, search }) => {
const res = (options as ComboboxItem[]).filter((o) =>
o.label.toLowerCase().includes(search.toLowerCase().trim()),
);
res.sort((a, b) => a.label.localeCompare(b.label));
return res;
};
const onClickConfirmEditDoctor = (values: typeof form.values) => {
apiEditDoctorInfo(values).then((res) => {
if (res.success) {
modals.closeAll();
showInfoMessage('', 'Doctor edited successfully', 3000);
onSucceed();
} else showErrorMessage(res.message, 'Edit Doctor Failed');
}).catch((err) =>
showErrorMessage(err.toString(), 'Edit Doctor Failed'),
);
};
return (
);
}
modals.open({
title: origDoctorInfo ? 'Edit Doctor' : 'Create Doctor',
centered: true,
size: "xl",
children: ,
});
}
export function confirmSetResignedDoctor(doctor_id: number, doctor_name: string, is_resigned: boolean, onFinished: () => void = () => {}) {
const onClickConfirmSetResigned = (doctor: number, resigned: boolean) => {
apiSetDoctorResigned(doctor, resigned).then(res => {
if (res.success) {
showInfoMessage("", "The operation has been completed successfully.", 3000)
}
else {
showErrorMessage(res.message, "The doctor's resignation failed.")
}
}).catch(err => {
showErrorMessage(err.toString(), "The doctor's resignation failed.")
}).finally(() => onFinished())
modals.closeAll()
}
modals.open({
title: is_resigned ? "Termination" : "Reinstatement",
centered: true,
children: (
{ is_resigned ?
Are you certain you want to proceed with the termination of {doctor_name}?
:
Are you certain you want to proceed with the reinstatement of {doctor_name}?
}
)
})
}
export function confirmAdminAddUser(
initRegType: number = 1, // Patient: 0, Doctor: 1, Receptionist: 99
onSucceed: () => void = () => {},
) {
function ConfirmAddUser() {
const form = useForm({
initialValues: {
reg_type: initRegType.toString(),
username: '',
name: '',
email: '',
phone: '',
gender: '',
birth_date: new Date(2000, 1, 1),
title: '',
address: '',
postcode: '',
grade: DoctorGrade.Unknown.toString(),
is_admin: false
},
validate: {
name: (v) => (v.length === 0 ? 'Input name.' : null),
email: (v) =>
/^\S+@\S+\.\S+$/.test(v) ? null : 'Incorrect email address.',
phone: (v) =>
v.length === 0 || /^\+?\d{6,15}$/.test(v)
? null
: 'Invalid phone number.',
birth_date: (v) => (v > new Date() ? 'Date of birth cannot be in the future' : null),
gender: (v) => (v.length === 0 ? "Select a gender" : null)
},
});
const genderOptions = useMemo(
() => [
{ value: 'M', label: 'Male' },
{ value: 'F', label: 'Female' },
{ value: 'Intersex', label: 'Intersex' },
],
[],
);
const gradeOptions = useMemo(
() =>
Object.entries(DoctorGrade)
.filter(([k]) => isNaN(Number(k)))
.map(([k, v]) => ({
value: v.toString(),
label: k,
})),
[],
);
const optionsFilter: OptionsFilter = ({ options, search }) => {
const res = (options as ComboboxItem[]).filter((o) =>
o.label.toLowerCase().includes(search.toLowerCase().trim()),
);
res.sort((a, b) => a.label.localeCompare(b.label));
return res;
};
const onClickRegSubmit = (values: typeof form.values) => {
apiAdminRegister(values).then((res) => {
if (res.success) {
// modals.closeAll();
showRegAccountPassword("Added User Succeed", res.data?.username, res.data?.password)
onSucceed()
} else showErrorMessage(res.message, 'Add User Failed');
}).catch((err) =>
showErrorMessage(err.toString(), 'Add User Failed'),
);
};
return (
);
}
modals.open({
title: "Add User",
centered: true,
size: "70%",
children: ,
});
}
export function showRegAccountPassword(title: string, username?: string, password?: string) {
modals.open({
title: title,
centered: true,
closeOnEscape: false,
closeOnClickOutside: false,
withCloseButton: false,
children: (
Username: {username}
{ username &&
{({ copied, copy }) => (
{copied ? : }
)}
}
Password: {password}
{ password &&
{({ copied, copy }) => (
{copied ? : }
)}
}
{({ copied, copy }) => (
)}
),
});
}
export function confirmResetPassword(user_id: number, user_type: number) {
function ConfirmResetPWD() {
const [resetting, setResetting] = useState(false)
return(
Are you sure you want to reset the password?
)
}
modals.open({
title: "Reset Password",
centered: true,
children:
});
}
export function confirmDeleteTeam(teamId: number, department: String, onFinished: () => void = () => {}) {
const onClickConfirmDeleteTeam = (teamId: number) => {
apiDeleteTeam(teamId).then(res => {
if (res.success) {
showInfoMessage("", "Medical team deleted successfully", 3000)
} else {
showErrorMessage(res.message, "Failed to delete medical team")
}
}).catch(err => {
showErrorMessage(err.toString(), "Failed to delete medical team")
}).finally(() => onFinished())
modals.closeAll()
}
modals.open({
title: "Delete Medical Team",
centered: true,
children: (
Are you sure you want to delete this medical team: {department}?
)
})
}
export function confirmEditOrCreateTeam(
origTeamInfo: DoctorTeamInfo | null,
doctorsList: DoctorDataWithPermission[] = [],
onSucceed: () => void = () => {}
) {
function ConfirmEditOrCreateTeam({
teamInfo,
doctorsList
}: {
teamInfo: DoctorTeamInfo | null;
doctorsList: DoctorDataWithPermission[];
}) {
const [loading, setLoading] = useState(false);
const [availableDoctors, setAvailableDoctors] = useState([]);
useEffect(() => {
// Filter out resigned doctors
const activeDoctors = doctorsList.filter(d => !d.is_resigned);
setAvailableDoctors(activeDoctors);
}, [doctorsList]);
const form = useForm({
initialValues: {
team_id: teamInfo ? teamInfo.id : -1,
department: teamInfo ? teamInfo.department : '',
consultant_id: teamInfo ? teamInfo.consultant_id.toString() : '-1',
is_admin_team: teamInfo ? teamInfo.is_admin_team : false,
team_members: teamInfo
? teamInfo.members.map(member => member.id)
: []
},
validate: {
department: (value) => (!value ? 'Please select a department' : null),
consultant_id: (value) => (value === '-1' || !value ? 'Please select a consultant' : null),
},
});
const departmentOptions = useMemo(() => {
return Object.entries(Departments).map(([key, value]) => ({
value: value as string,
label: key.replace(/_/g, ' ')
}));
}, []);
const consultantOptions = useMemo(() => {
return availableDoctors
.map(d => ({
value: d.id.toString(),
label: `${d.title} ${d.name}`
}));
}, [availableDoctors]);
const teamMemberOptions = useMemo(() => {
return availableDoctors.map(d => ({
value: d.id.toString(),
label: `${d.title} ${d.name} (${DoctorGrade[d.grade]})`
}));
}, [availableDoctors]);
const handleFormSubmit = (values: typeof form.values) => {
setLoading(true);
const teamData = {
...values,
consultant_id: Number(values.consultant_id),
team_members: values.team_members.map(Number)
};
const apiCall = teamInfo
? apiEditTeam(teamData)
: apiCreateTeam(teamData);
apiCall.then(res => {
if (res.success) {
modals.closeAll();
showInfoMessage("", teamInfo ? "Medical team updated successfully" : "Medical team created successfully", 3000);
onSucceed();
} else {
showErrorMessage(res.message, teamInfo ? "Failed to update medical team" : "Failed to create medical team");
}
}).catch(err => {
showErrorMessage(err.toString(), teamInfo ? "Failed to update medical team" : "Failed to create medical team");
}).finally(() => {
setLoading(false);
});
};
return (
);
}
modals.open({
title: origTeamInfo ? "Edit Medical Team" : "Create Medical Team",
centered: true,
size: "lg",
children: (
)
});
}
export function confirmViewTeamMembers(teamInfo: DoctorTeamInfo) {
modals.open({
title: `Medical Team: ${teamInfo.department.replace(/_/g, ' ')}`,
centered: true,
size: "lg",
children: (
Team Information
Department: {teamInfo.department.replace(/_/g, ' ')}
Consultant: {
teamInfo.members.find(m => m.id === teamInfo.consultant_id)
? `${teamInfo.members.find(m => m.id === teamInfo.consultant_id)?.title || ''} ${teamInfo.members.find(m => m.id === teamInfo.consultant_id)?.name || ''}`
: `ID: ${teamInfo.consultant_id}`
}
Admin Team: {teamInfo.is_admin_team ? 'Yes' : 'No'}
Team Members ({teamInfo.members.length})
{teamInfo.members.length > 0 ? (
ID
Name
Grade
Gender
Contact
{teamInfo.members.map(member => (
{member.id}
{`${member.title} ${member.name}`}
{DoctorGrade[member.grade]}
{member.gender}
{member.email}
))}
) : (
No team members
)}
)
});
}
export function confirmDeleteBooking(appointmentId: number, category: string, onFinished: () => void = () => {}) {
const onClickConfirmDeleteBooking = (appointmentId: number) => {
apiDeletePatientBooking(appointmentId).then(res => {
if (res.success) {
showInfoMessage("", "Appointment deleted successfully", 3000)
} else {
showErrorMessage(res.message, "Failed to delete appointment")
}
}).catch(err => {
showErrorMessage(err.toString(), "Failed to delete appointment")
}).finally(() => onFinished())
modals.closeAll()
}
modals.open({
title: "Delete Appointment",
centered: true,
children: (
Are you sure you want to delete this appointment: {category}?
)
})
}
export function confirmEditOrCreateBooking(
origBookingInfo: PatientBookingInfo | null,
onSucceed: () => void = () => {}
) {
function ConfirmEditOrCreateBooking({
bookingInfo
}: {
bookingInfo: PatientBookingInfo | null;
}) {
const [loading, setLoading] = useState(false);
const form = useForm({
initialValues: {
appointment_id: bookingInfo ? bookingInfo.id : -1,
appointment_time: bookingInfo ? new Date(bookingInfo.appointment_time * 1000) : new Date(),
category: bookingInfo ? bookingInfo.category : BookingCategory.Consultation,
description: bookingInfo ? bookingInfo.description : '',
},
validate: {
appointment_time: (value) => (!value ? 'Please select appointment time' : null),
category: (value) => (!value ? 'Please select category' : null),
description: (value) => (!value || value.length < 5 ? 'Description must be at least 5 characters' : null),
},
});
const categoryOptions = useMemo(() => {
return Object.entries(BookingCategory).map(([key, value]) => ({
value: value,
label: key.replace(/_/g, ' ')
}));
}, []);
const handleFormSubmit = (values: typeof form.values) => {
setLoading(true);
const appointmentTime = Math.floor(values.appointment_time.getTime() / 1000);
const bookingData = {
...values,
appointment_time: appointmentTime,
};
const apiCall = bookingInfo
? apiEditPatientBooking(bookingData)
: apiPatientBooking(bookingData);
apiCall.then(res => {
if (res.success) {
modals.closeAll();
showInfoMessage("", bookingInfo ? "Appointment updated successfully" : "Appointment created successfully", 3000);
onSucceed();
} else {
showErrorMessage(res.message, bookingInfo ? "Failed to update appointment" : "Failed to create appointment");
}
}).catch(err => {
showErrorMessage(err.toString(), bookingInfo ? "Failed to update appointment" : "Failed to create appointment");
}).finally(() => {
setLoading(false);
});
};
return (
);
}
modals.open({
title: origBookingInfo ? "Edit Appointment" : "Create Appointment",
centered: true,
size: "lg",
children: (
)
});
}
export function confirmApproveAppointment(
appointmentId: number,
onSucceed: () => void = () => {}
) {
function ConfirmApproveAppointment() {
const [loading, setLoading] = useState(false);
const [teams, setTeams] = useState([]);
const [loadingTeams, setLoadingTeams] = useState(true);
const form = useForm({
initialValues: {
appointment_id: appointmentId,
approved: true,
feedback: '',
assigned_team: '',
},
validate: {
feedback: (value) => (!value ? 'Please provide feedback' : null),
assigned_team: (value) => (!value ? 'Please select a medical team' : null),
},
});
useEffect(() => {
// Load teams for selection
apiGetTeamList(1).then(res => {
if (res.success) {
setTeams(res.data.teams);
} else {
showErrorMessage(res.message, "Failed to load medical teams");
}
})
.catch(err => {
showErrorMessage("Failed to load medical teams", "Error");
})
.finally(() => {
setLoadingTeams(false);
});
}, []);
const teamOptions = useMemo(() => {
return teams.map(team => ({
value: team.id.toString(),
label: `${team.department.replace(/_/g, ' ')} (ID: ${team.id})`
}));
}, [teams]);
const handleFormSubmit = (values: typeof form.values) => {
setLoading(true);
apiProcessAppointment(
values.appointment_id,
values.approved,
values.feedback,
parseInt(values.assigned_team)
).then(res => {
if (res.success) {
modals.closeAll();
showInfoMessage("", "Appointment approved successfully", 3000);
onSucceed();
} else {
showErrorMessage(res.message, "Failed to approve appointment");
}
}).catch(err => {
showErrorMessage("Failed to approve appointment", "Error");
}).finally(() => {
setLoading(false);
});
};
return (
);
}
modals.open({
title: "Approve Appointment",
centered: true,
size: "md",
children:
});
}
export function confirmRejectAppointment(
appointmentId: number,
onSucceed: () => void = () => {}
) {
function ConfirmRejectAppointment() {
const [loading, setLoading] = useState(false);
const form = useForm({
initialValues: {
appointment_id: appointmentId,
approved: true,
feedback: '',
assigned_team: null,
},
validate: {
feedback: (value) => (!value ? 'Please provide rejection reason' : null),
},
});
const handleFormSubmit = (values: typeof form.values) => {
setLoading(true);
apiProcessAppointment(
values.appointment_id,
values.approved,
values.feedback,
values.assigned_team
).then(res => {
if (res.success) {
modals.closeAll();
showInfoMessage("", "Appointment rejected successfully", 3000);
onSucceed();
} else {
showErrorMessage(res.message, "Failed to reject appointment");
}
}).catch(err => {
showErrorMessage("Failed to reject appointment", "Error");
}).finally(() => {
setLoading(false);
});
};
return (
);
}
modals.open({
title: "Reject Appointment",
centered: true,
size: "md",
children:
});
}
export function confirmPatientAdmission(
appointmentId: number,
onSucceed: () => void = () => {}
) {
function ConfirmPatientAdmission() {
const [loading, setLoading] = useState(false);
const [wards, setWards] = useState([]);
const [loadingWards, setLoadingWards] = useState(true);
const form = useForm({
initialValues: {
appointment_id: appointmentId,
ward_id: '',
},
validate: {
ward_id: (value) => (!value ? 'Please select a ward' : null),
},
});
useEffect(() => {
// Load wards for selection
apiGetWardList(1, true).then(res => {
if (res.success) {
setWards(res.data.wards);
} else {
showErrorMessage(res.message, "Failed to load wards");
}
})
.catch(err => {
showErrorMessage("Failed to load wards", "Error");
})
.finally(() => {
setLoadingWards(false);
});
}, []);
const wardOptions = useMemo(() => {
return wards
.filter(ward => ward.current_occupancy < ward.total_capacity) // Only show wards with available capacity
.map(ward => ({
value: ward.id.toString(),
label: `${ward.name} (${ward.current_occupancy}/${ward.total_capacity}) - ${WardTypes[ward.type]}`
}));
}, [wards]);
const handleFormSubmit = (values: typeof form.values) => {
setLoading(true);
apiPatientAdmission(
values.appointment_id,
parseInt(values.ward_id)
).then(res => {
if (res.success) {
modals.closeAll();
showInfoMessage("", "Patient admitted successfully", 3000);
onSucceed();
} else {
showErrorMessage(res.message, "Failed to admit patient");
}
}).catch(err => {
showErrorMessage("Failed to admit patient", "Error");
}).finally(() => {
setLoading(false);
});
};
return (
);
}
modals.open({
title: "Patient Admission",
centered: true,
size: "md",
children:
});
}
export function confirmEditPatient(
origPatientInfo: PatientData,
onSucceed: () => void = () => {},
) {
function ConfirmEditPatient({
patientInfo,
}: {
patientInfo: PatientData;
}) {
const form = useForm({
initialValues: {
patient_id: patientInfo.id,
title: patientInfo.title,
name: patientInfo.name,
gender: patientInfo.gender,
birth_date: parseDmyToDate(patientInfo.birth_date),
email: patientInfo.email,
phone: patientInfo.phone,
address: patientInfo.address,
postcode: patientInfo.postcode,
},
validate: {
name: (value) => (!value || value.trim() === "" ? "Name cannot be empty" : null),
title: (value) => (!value || value.trim() === "" ? "Title cannot be empty" : null),
email: (value) => (!/^\S+@\S+$/.test(value) ? "Please enter a valid email" : null),
phone: (value) => (!value || value.length < 6 ? "Please enter a valid phone number" : null),
address: (value) => (!value || value.trim() === "" ? "Address cannot be empty" : null),
postcode: (value) => (!value || value.trim() === "" ? "Postcode cannot be empty" : null),
},
});
const onClickConfirmEditPatient = (values: typeof form.values) => {
apiEditPatientInfo(values).then(res => {
if (res.success) {
modals.closeAll()
showInfoMessage("", "Patient information updated successfully", 3000)
onSucceed()
} else {
showErrorMessage(res.message, "Failed to update patient information")
}
}).catch(err => {
showErrorMessage(err.toString(), "Failed to update patient information")
})
}
return (
);
}
modals.open({
title: "Edit Patient Information",
centered: true,
size: "xl",
children: ,
});
}
export function confirmPatientDischarge(admissionId: number, patientName: string, onFinished: () => void = () => {}) {
const onClickConfirmDischarge = (admissionId: number) => {
apiPatientDischarge(admissionId).then(res => {
if (res.success) {
modals.closeAll()
showInfoMessage("", "Patient discharged successfully", 3000)
onFinished()
} else {
showErrorMessage(res.message, "Failed to discharge patient")
}
}).catch(err => {
showErrorMessage(err.toString(), "Failed to discharge patient")
})
}
modals.open({
title: "Confirm Patient Discharge",
centered: true,
children: (
Are you sure you want to discharge {patientName}?
),
})
}