import type {Route} from "../../../.react-router/types/app/pages/dashboard/+types/MedicalTeamsManagement"; import {useEffect, useMemo, useState} from "react"; import {DashboardPageType} from "~/utils/hms_enums.ts"; import {useNavigate, useOutletContext} from "react-router"; import { type DoctorDataWithPermission, type DoctorTeamInfo, type OutletContextType, SORT_SYMBOLS } from "~/utils/models.ts"; import {Accordion, ActionIcon, Button, Card, Group, Pagination, Stack, Table, Text, Tooltip} from "@mantine/core"; import {apiGetDoctorsList, apiGetTeamList} 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 DeleteIcon from "mdi-react/DeleteIcon"; import {confirmDeleteTeam, confirmEditOrCreateTeam, confirmViewTeamMembers} from "~/components/subs/confirms.tsx"; import AddIcon from "mdi-react/AddIcon"; import EyeIcon from "mdi-react/EyeIcon"; import {MedicalTeamManageFilter} from "~/components/subs/MedicalTeamManageFilter.tsx"; import HistoryIcon from "mdi-react/HistoryIcon"; import FilterIcon from "mdi-react/FilterIcon"; import { ResponsiveTableContainer } from "~/components/subs/ResponsiveTableContainer"; export function meta({}: Route.MetaArgs) { return [ { title: "Medical Teams Management" }, { name: "description", content: "Medical Teams Management" }, ]; } export default function Component() { const navigate = useNavigate(); const [refreshingTeamList, setRefreshingTeamList] = useState(false); const [teamInfo, setTeamInfo] = useState<{teams: DoctorTeamInfo[], total_pages: number}>({teams: [], total_pages: 1}); const [doctorsList, setDoctorsList] = useState([]); const [loadingDoctors, setLoadingDoctors] = useState(false); const [sortKey, setSortKey] = useState(""); const [sortDesc, setSortDesc] = useState(true); const [currPage, setCurrPage] = useState(1); const [filterDepartments, setFilterDepartments] = useState([]); const [filterAdminTeam, setFilterAdminTeam] = useState(-1); const { changePage } = useOutletContext(); useEffect(() => { refreshTeamList(); loadDoctorsList(); }, []); useEffect(() => { refreshTeamList(); }, [currPage]); const updateFilter = (departments: string[], adminTeam: number) => { setFilterDepartments(departments); setFilterAdminTeam(adminTeam); }; const loadDoctorsList = () => { setLoadingDoctors(true); apiGetDoctorsList(1).then(res => { if (!res.success) { showErrorMessage(res.message, "Failed to get doctors list"); return; } setDoctorsList(res.data.doctors); }) .catch(err => {}) .finally(() => { setLoadingDoctors(false); }); }; const refreshTeamList = () => { setRefreshingTeamList(true); apiGetTeamList(currPage).then(res => { if (!res.success) { showErrorMessage(res.message, "Failed to get medical teams list"); return; } setTeamInfo(res.data); }) .catch(err => {}) .finally(() => { setRefreshingTeamList(false); }); }; const handleSort = (key: string) => { if (sortKey === key) { setSortDesc(!sortDesc); } else { setSortKey(key); setSortDesc(false); // Default ascending } }; const sortedTeams = useMemo(() => { let data = [...teamInfo.teams]; data = data.filter((team) => { const okDepartment = filterDepartments.length === 0 || filterDepartments.includes(team.department); const okAdmin = filterAdminTeam === -1 || (filterAdminTeam === 1 ? team.is_admin_team : !team.is_admin_team); return okDepartment && okAdmin; }); 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; }, [teamInfo.teams, sortKey, sortDesc, filterDepartments, filterAdminTeam]); const handleCreateTeam = () => { confirmEditOrCreateTeam(null, doctorsList, refreshTeamList); }; const handleEditTeam = (team: DoctorTeamInfo) => { confirmEditOrCreateTeam(team, doctorsList, refreshTeamList); }; const handleDeleteTeam = (teamId: number, department: string) => { confirmDeleteTeam(teamId, department, refreshTeamList); }; const handleViewTeamMembers = (team: DoctorTeamInfo) => { confirmViewTeamMembers(team); }; const rows = sortedTeams.map((team) => ( {team.id} {team.department.replace(/_/g, ' ')} {team.members.find(m => m.id === team.consultant_id) ? `${team.members.find(m => m.id === team.consultant_id)?.title || ''} ${team.members.find(m => m.id === team.consultant_id)?.name || ''}` : `ID: ${team.consultant_id}`} {team.members.length} {team.is_admin_team ? 'Yes' : 'No'} { changePage(DashboardPageType.TreatmentRecord, `/dashboard/treatment_record/t${team.id}`) }}> handleViewTeamMembers(team)}> handleEditTeam(team)}> handleDeleteTeam(team.id, team.department.replace(/_/g, ' '))}> )); return ( Medical Teams Management Filters handleSort("id")}> Team ID{" "} {sortKey === "id" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("department")}> Department{" "} {sortKey === "department" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} handleSort("consultant_id")}> Consultant{" "} {sortKey === "consultant_id" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} Members Count handleSort("is_admin_team")}> Admin Team{" "} {sortKey === "is_admin_team" && SORT_SYMBOLS[sortDesc ? "desc" : "asc"]} Operations {rows}
); }