"use client"; import React, { useMemo } from "react"; import { useQuery } from "@tanstack/react-query"; import moment from "moment"; import { Activity, CalendarDays, ClipboardList, Hospital, Stethoscope, Users, } from "lucide-react"; import { QUERY_KEY } from "@/constant/config/enum"; import { httpRequest } from "@/services"; import consultationServices, { ConsultationItem, ConsultationResponse, ReportResponse, } from "@/services/consultationServices"; import specialtyServices, { SpecialtyItem } from "@/services/specialtyServices"; import DataWrapper from "@/components/customs/DataWrapper"; const MainPageHome = () => { const today = moment().format("YYYY-MM-DD"); const consultationQuery = useQuery({ queryKey: [QUERY_KEY.table_list_consultation, "dashboard"], queryFn: async () => { const res = await httpRequest({ showMessageFailed: true, http: consultationServices.getConsultations({ Page: 1, PageSize: 100, SortBy: "visitDate", Desc: true, }), }); return ( res || { items: [], page: 1, pageSize: 100, total: 0, totalPages: 0, } ); }, }); const reportQuery = useQuery({ queryKey: [QUERY_KEY.table_list_report, today], queryFn: async () => { const res = await httpRequest({ showMessageFailed: true, http: consultationServices.getConsultationsReport({ FromDate: today, ToDate: today, }), }); return res as ReportResponse; }, }); const specialtyQuery = useQuery({ queryKey: [QUERY_KEY.list_specialty_lookup], queryFn: async () => { const res = await httpRequest({ showMessageFailed: true, http: specialtyServices.getSpecialty(), }); return res || []; }, }); const consultationItems = consultationQuery.data?.items || []; const consultationReport = reportQuery.data; const specialtyItems = specialtyQuery.data || []; const todayConsultations = useMemo(() => { return consultationItems.filter((item) => { if (!item.visitDate) return false; return moment(item.visitDate).format("YYYY-MM-DD") === today; }); }, [consultationItems, today]); const statusCounts = useMemo(() => { return { total: todayConsultations.length, waiting: todayConsultations.filter((item) => item.status === 1).length, inProgress: todayConsultations.filter((item) => item.status === 2).length, completed: todayConsultations.filter((item) => item.status === 5).length, cancelled: todayConsultations.filter((item) => item.status === 6).length, }; }, [todayConsultations]); const specialtyActiveCounts = useMemo(() => { const map = new Map(); todayConsultations.forEach((item) => { item.specialtyClinics?.forEach((specialty) => { const count = map.get(specialty.specialtyId) || 0; map.set(specialty.specialtyId, count + 1); }); }); return specialtyItems.map((specialty) => ({ ...specialty, active: map.get(specialty.id) || 0, })); }, [todayConsultations, specialtyItems]); const summaryCards = useMemo( () => [ { title: "Tất cả đợt khám", value: statusCounts.total.toString(), subtitle: "Số đợt khám trong ngày", icon: CalendarDays, color: "bg-blue-50 text-blue-600", }, { title: "Đang khám", value: statusCounts.inProgress.toString(), subtitle: "Đang khám tổng quát", icon: Stethoscope, color: "bg-emerald-50 text-emerald-600", }, { title: "Hoàn tất", value: statusCounts.completed.toString(), subtitle: "Đã hoàn thành", icon: ClipboardList, color: "bg-sky-50 text-sky-600", }, { title: "Chờ khám", value: statusCounts.waiting.toString(), subtitle: "Đang chờ bác sĩ", icon: Activity, color: "bg-orange-50 text-orange-600", }, ], [statusCounts], ); const generalInfo = useMemo( () => [ { label: "Tổng đợt khám", value: statusCounts.total.toString(), icon: Users, color: "bg-violet-50 text-violet-600", }, { label: "Đợt khám chuyên khoa", value: specialtyActiveCounts .reduce((sum, item) => sum + item.active, 0) .toString(), icon: Hospital, color: "bg-cyan-50 text-cyan-600", }, { label: "Đơn thuốc", value: consultationReport?.totalPrescriptionsIssued?.toString() || "0", icon: ClipboardList, color: "bg-amber-50 text-amber-600", }, { label: "Chuyên khoa", value: specialtyItems.length.toString(), icon: Activity, color: "bg-teal-50 text-teal-600", }, ], [ consultationReport, statusCounts.total, specialtyActiveCounts, specialtyItems.length, ], ); return (

Dashboard khám bệnh

Theo dõi nhanh các đợt khám, chuyên khoa và thông tin tổng quát trong ngày.

Cập nhật: {moment().format("DD/MM/YYYY")}
{summaryCards.map((item) => { const Icon = item.icon; return (
{item.title}

{item.value}

{item.subtitle}

); })}

Chuyên khoa hiện có

Danh sách chuyên khoa.

{specialtyItems.length} chuyên khoa
{specialtyActiveCounts.map((specialty, idx) => (

{specialty.name}

Số chuyên khoa: {specialty.active} ca khám hôm nay

{specialty.active}
))}

Thông tin khám tổng quát

Tổng số đợt khám, ca khám chuyên khoa và đơn thuốc trong ngày.

{generalInfo.map((item) => { const Icon = item.icon; return (

{item.label}

{item.value}

); })}
); }; export default MainPageHome;