refactor: move request statistics into modal

This commit is contained in:
lizerk 2026-08-26 12:32:50 +03:00
parent 207022fd55
commit 6276c35659

View File

@ -22,6 +22,7 @@ import {
type LucideIcon,
} from "lucide-react";
import { Modal } from "@/components/ui/Modal";
import { ProjectSelectMenu } from "@/components/ui/ProjectSelectMenu";
import { apiClient } from "@/lib/api";
import { ApiError } from "@/lib/api/client";
@ -295,7 +296,7 @@ function StatisticsGrid({ statistics }: { statistics: RequestEmployeeStatistics
export default function EmployeeRequestsProfileSections({ employeeId }: { employeeId: number }) {
const [requestsOpen, setRequestsOpen] = useState(false);
const [statisticsOpen, setStatisticsOpen] = useState(false);
const [statisticsModalOpen, setStatisticsModalOpen] = useState(false);
const [data, setData] = useState<EmployeeRequestProfileSummary | null>(null);
const [loading, setLoading] = useState(true);
const [requestsLoading, setRequestsLoading] = useState(false);
@ -358,30 +359,47 @@ export default function EmployeeRequestsProfileSections({ employeeId }: { employ
<CollapsibleProfileSection
title="Заявления"
icon={<ClipboardList size={18} />}
action={badge}
action={
<div className="flex shrink-0 items-center gap-2">
{badge}
<button
type="button"
onClick={() => setStatisticsModalOpen(true)}
className="app-action-ghost app-text-muted flex h-8 w-8 items-center justify-center rounded-lg transition hover:text-[var(--foreground)]"
title="Статистика по заявлениям"
aria-label="Открыть статистику по заявлениям"
>
<BarChart3 size={16} />
</button>
</div>
}
open={requestsOpen}
onToggle={() => setRequestsOpen((value) => !value)}
>
{content || <RequestList
loading={requestsLoading}
requests={data?.results || []}
page={data?.page || requestPage}
totalPages={data?.total_pages || 1}
onPageChange={(nextPage) => {
setError(null);
setRequestsLoading(true);
setRequestPage(nextPage);
}}
/>}
{content || (
<RequestList
loading={requestsLoading}
requests={data?.results || []}
page={data?.page || requestPage}
totalPages={data?.total_pages || 1}
onPageChange={(nextPage) => {
setError(null);
setRequestsLoading(true);
setRequestPage(nextPage);
}}
/>
)}
</CollapsibleProfileSection>
<CollapsibleProfileSection
<Modal
isOpen={statisticsModalOpen}
onClose={() => setStatisticsModalOpen(false)}
title="Статистика по заявлениям"
icon={<BarChart3 size={18} />}
action={
loading ? (
<LoaderCircle size={16} className="app-text-muted shrink-0 animate-spin" />
) : data ? (
size="md"
closeOnClickOutside
>
<div className="mb-4 flex justify-end">
{data ? (
<ProjectSelectMenu
value={statisticsPeriod}
options={statisticsPeriodOptions}
@ -393,18 +411,24 @@ export default function EmployeeRequestsProfileSections({ employeeId }: { employ
ariaLabel="Период статистики по заявлениям"
variant="badge"
/>
) : null
}
open={statisticsOpen}
onToggle={() => setStatisticsOpen((value) => !value)}
>
{content || (statisticsLoading ? (
) : null}
</div>
{error ? (
<div className="app-feedback-danger rounded-xl px-3 py-2 text-sm">{error}</div>
) : loading || !data ? (
<div className="flex items-center justify-center gap-2 py-8">
<LoaderCircle size={18} className="app-text-muted animate-spin" />
<span className="app-text-muted text-sm">Загрузка статистики...</span>
</div>
) : statisticsLoading ? (
<div className="flex items-center justify-center gap-2 py-5">
<LoaderCircle size={18} className="app-text-muted animate-spin" />
<span className="app-text-muted text-sm">Обновляем статистику...</span>
</div>
) : data ? <StatisticsGrid statistics={data.statistics} /> : null)}
</CollapsibleProfileSection>
) : (
<StatisticsGrid statistics={data.statistics} />
)}
</Modal>
</>
);
}