import React, { useMemo } from 'react'; import { useUrlState } from '../hooks/useUrlState'; import PageHeader from '../components/ui/PageHeader'; import DataTable, { type Column } from '../components/ui/DataTable'; import SearchableSelect from '../components/ui/SearchableSelect'; import { Link } from 'react-router-dom'; import { usePlanAccuracy } from '../hooks/useReports'; import type { AccuracyRow } from '../types'; const RANGES = [ { value: '30', label: 'ماه گذشته' }, { value: '90', label: 'سه ماه گذشته' }, ]; const SEVERITY: Record = { none: { label: 'دقیق', className: 'badge green' }, low: { label: 'کم', className: 'badge' }, medium: { label: 'متوسط', className: 'badge amber' }, high: { label: 'زیاد', className: 'badge red' }, }; /** * مدت پیش‌بینی‌شده در برابر مدت واقعی. * * سرویسی که یک ساعت پیش‌بینی شده ولی یک‌ساعت‌ونیم طول می‌کشد، هر روز نیم ساعت از ظرفیت * کلینیک را بی‌صدا می‌خورد — این صفحه تنها جایی است که آن را نشان می‌دهد. */ export default function PlanAccuracyPage() { // بازه در URL: لینکِ گزارش باید همان بازه‌ای را باز کند که فرستنده دیده بود. const [urlState, setUrlState] = useUrlState({ days: '30' }); const days = urlState.days; const setDays = (v: string) => setUrlState({ days: v }); const range = useMemo(() => { const to = Math.floor(Date.now() / 1000); return { from: to - Number(days) * 86400, to }; }, [days]); const { rows, loading } = usePlanAccuracy(range.from, range.to); const columns: Column[] = [ { key: 'service_name', header: 'خدمت', render: (r) => (
{r.service_name} {r.sample_size} نوبت
), }, { key: 'planned_minutes', header: 'پیش‌بینی', render: (r) => {r.planned_minutes} دقیقه, }, { key: 'actual_minutes', header: 'واقعی', render: (r) => {r.actual_minutes} دقیقه, }, { key: 'deviation_percent', header: 'انحراف', render: (r) => ( {r.deviation_percent > 0 ? `+${r.deviation_percent}` : r.deviation_percent}٪ ), }, { key: 'fix', header: '', // گزارشی که راه اصلاح ندهد خوانده نمی‌شود. render: (r) => ( ویرایش بخش‌های این خدمت ), }, { key: 'severity', header: 'شدت', render: (r) => ( {SEVERITY[r.severity].label} ), }, ]; return (
setDays(String(v ?? '30'))} options={RANGES} />
خدماتی با کمتر از سه نوبت انجام‌شده در گزارش نمی‌آیند.
); }