import type {Route} from "../../../.react-router/types/app/pages/dashboard/+types/StaffManagement"; import {useEffect, useMemo, useState} from "react"; import {DashboardPageType, DoctorGrade, UserType} from "~/utils/hms_enums.ts"; import {useNavigate, useOutletContext} from "react-router"; import { type DoctorDataWithPermission, type DoctorListInfo, type OutletContextType, SORT_SYMBOLS } from "~/utils/models.ts"; import {Accordion, ActionIcon, Button, Card, Group, Pagination, Stack, Table, Text, Tooltip} from "@mantine/core"; import {apiGetDoctorsList} from "~/utils/hms_api.ts"; import {showErrorMessage} from "~/utils/utils.ts"; import {iconMStyle, marginLeftRight, marginRightBottom, marginTopBottom} from "~/styles.ts"; import PencilIcon from "mdi-react/PencilIcon"; import { confirmAdminAddUser, confirmEditDoctor, confirmResetPassword, confirmSetResignedDoctor } from "~/components/subs/confirms.tsx"; import AddIcon from "mdi-react/AddIcon"; import LogoutIcon from "mdi-react/LogoutIcon"; import LoginIcon from "mdi-react/LoginIcon"; import LockResetIcon from "mdi-react/LockResetIcon"; import {StaffTableFilter} from "~/components/subs/StaffManageTableFilter.tsx"; import HistoryIcon from "mdi-react/HistoryIcon"; import FilterIcon from "mdi-react/FilterIcon"; import {ResponsiveTableContainer} from "~/components/subs/ResponsiveTableContainer.tsx"; export function meta({}: Route.MetaArgs) { return [ { title: "Medical Teams Management" }, { name: "description", content: "Medical Teams Management" }, ]; } export default function Component() { const navigate = useNavigate(); const [refreshingStaffList, setRefreshingStaffList] = useState(false) const [staffInfo, setStaffInfo] = useState({doctors: [], total_pages: 1}) const [sortKey, setSortKey] = useState("") const [sortDesc, setSortDesc] = useState(true) const [currPage, setCurrPage] = useState(1) const [filterGrades, setFilterGrades] = useState([]) const [filterGenders, setFilterGenders] = useState([]) const [filterIsAdmin, setFilterIsAdmin] = useState(-1) const [filterIsTerminated, setFilterIsTerminated] = useState(-1) const { changePage } = useOutletContext(); useEffect(() => { refreshStaffList() }, []); useEffect(() => { refreshStaffList() }, [currPage]); const updateFilter = (grades: string[], genders: string[], isAdmin: string, isTerminated: string) => { setFilterGrades(grades) setFilterGenders(genders) setFilterIsAdmin(Number(isAdmin)) setFilterIsTerminated(Number(isTerminated)) } const refreshStaffList = () => { setRefreshingStaffList(true) apiGetDoctorsList(currPage).then(res => { if (!res.success) { showErrorMessage(res.message, "Get Ward List Failed") return } setStaffInfo(res.data) }) .catch(err => {}) .finally(() => { setRefreshingStaffList(false) }) } const handleSort = (key: string) => { if (sortKey === key) { setSortDesc(!sortDesc) } else { setSortKey(key) setSortDesc(false) // 默认升序 } } const sortedDoctors = useMemo(() => { let data = [...staffInfo.doctors] data = data.filter((w) => { const okType = filterGrades.length === 0 || filterGrades.includes(w.grade.toString()) const okGender = filterGenders.length === 0 || filterGenders.includes(w.gender) const okAdmin = filterIsAdmin === -1 || (filterIsAdmin === 1 ? w.is_admin : !w.is_admin) const okTerminated = filterIsTerminated === -1 || (filterIsTerminated === 1 ? w.is_resigned : !w.is_resigned) return okType && okGender && okAdmin && okTerminated }) if (!sortKey) return data data.sort((a, b) => { const valA = a[sortKey] const valB = b[sortKey] if (typeof valA === 'string' && typeof valB === 'string') { const cmp = valA.localeCompare(valB) return sortDesc ? -cmp : cmp } if (typeof valA === 'number' && typeof valB === 'number') { return sortDesc ? valB - valA : valA - valB } if (typeof valA === 'boolean' && typeof valB === 'boolean') { return sortDesc ? (valB ? 1 : -1) : (valA ? 1 : -1) } return 0 }) return data }, [staffInfo.doctors, sortKey, sortDesc, filterGrades, filterGenders, filterIsAdmin, filterIsTerminated]) const rows = sortedDoctors.map((doctor) => ( {doctor.id} {`${doctor.title} ${doctor.name}`} {DoctorGrade[doctor.grade]} {doctor.gender} {doctor.birth_date} {doctor.email} {doctor.phone} {doctor.is_admin ? "Yes" : "No"} {doctor.is_resigned ? "Yes" : "No"} { changePage(DashboardPageType.TreatmentRecord, `/dashboard/treatment_record/d${doctor.id}`) }}> { confirmEditDoctor(doctor, refreshStaffList) }}> { confirmResetPassword(doctor.id, UserType.DOCTOR) }}> {doctor.is_resigned ? { confirmSetResignedDoctor(doctor.id, `${doctor.title} ${doctor.name}`, false, refreshStaffList) }}> : { confirmSetResignedDoctor(doctor.id, `${doctor.title} ${doctor.name}`, true, refreshStaffList) }}> } )) return ( Staff Management Filters handleSort("id")}> User ID{" "} {sortKey === "id" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("name")}> Name{" "} {sortKey === "name" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("grade")}> Grade{" "} {sortKey === "grade" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("gender")}> Gender{" "} {sortKey === "gender" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("birth_date")}> Birth Date{" "} {sortKey === "birth_date" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("email")}> Email{" "} {sortKey === "email" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("phone")}> Phone{" "} {sortKey === "phone" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("is_admin")}> Admin{" "} {sortKey === "is_admin" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("is_resigned")}> Terminated{" "} {sortKey === "is_resigned" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} Operations {rows}
); }