From a1bd11afeec25685ba16fc16faec7a9a45def3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9=20=D0=A1=D0=B0?= =?UTF-8?q?=D0=B1=D0=B8=D0=BB=D0=B8=D0=BD?= Date: Mon, 13 Jul 2026 17:54:51 +0300 Subject: [PATCH] =?UTF-8?q?fix(dashboard):=20=D1=80=D0=BE=D0=BB=D0=B5?= =?UTF-8?q?=D0=B2=D1=8B=D0=B5=20=D0=B2=D0=B8=D0=B4=D1=8B=20=D0=B8=20=D1=81?= =?UTF-8?q?=D1=81=D1=8B=D0=BB=D0=BA=D0=B0=20=D0=BD=D0=B0=20=D0=B0=D1=83?= =?UTF-8?q?=D0=B4=D0=B8=D1=82=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20?= =?UTF-8?q?=D0=B4=D1=83=D0=B1=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moderator/support видят свою статистику; admin_activity заменён ссылкой на /audit. Co-authored-by: Cursor --- src/pages/dashboard/DashboardPage.tsx | 198 ++++++++++---------------- src/types/api.ts | 5 + 2 files changed, 83 insertions(+), 120 deletions(-) diff --git a/src/pages/dashboard/DashboardPage.tsx b/src/pages/dashboard/DashboardPage.tsx index 142f87d..8fb9319 100644 --- a/src/pages/dashboard/DashboardPage.tsx +++ b/src/pages/dashboard/DashboardPage.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Card, Col, Row, Statistic, Spin, Alert, Table, Tag } from 'antd'; +import { Card, Col, Row, Statistic, Spin, Alert, Button } from 'antd'; import { UserOutlined, CalendarOutlined, @@ -10,138 +10,99 @@ import { ClockCircleOutlined, DollarOutlined, } from '@ant-design/icons'; +import { Link, useNavigate } from 'react-router-dom'; import { useDashboardStats } from '../../hooks/useDashboard'; -import type { ColumnsType } from 'antd/es/table'; -import { AdminActivity } from '../../types/api'; -import { - AreaChart, - Area, - XAxis, - Tooltip, -} from 'recharts'; +import { useAuthStore } from '../../store/authStore'; import DailyLineChartCard from '../../components/DailyLineChartCard'; +import StatisticSparklineCard from '../../components/StatisticSparklineCard'; const DashboardPage: React.FC = () => { const { data, isLoading, error } = useDashboardStats(); + const role = useAuthStore((s) => s.user?.role); + const navigate = useNavigate(); if (isLoading) return ; if (error) return ; if (!data) return null; - const roleColors: Record = { - superadmin: 'red', - admin: 'blue', - moderator: 'purple', - support: 'cyan', - }; + if (role === 'moderator') { + return ( +
+

Модерация

+ + + } /> + + + + + + } /> + + + +
+ ); + } - const adminColumns: ColumnsType = [ - { title: 'Email', dataIndex: 'email', key: 'email' }, - { title: 'Ник', dataIndex: 'nickname', key: 'nickname' }, - { - title: 'Роль', - dataIndex: 'role', - key: 'role', - render: (role: string) => ( - {role} - ), - }, - { title: 'Действий', dataIndex: 'actions', key: 'actions' }, - { title: 'Последний вход', dataIndex: 'last_login', key: 'last_login' }, - ]; + if (role === 'support') { + return ( +
+

Поддержка

+ + + } /> + + + + + + } /> + + + +
+ ); + } - const eventsChartData = data.events_by_day?.map((item) => ({ + const registrationsSparkline = data.registrations_by_day?.map((item) => ({ date: item.date, - events: item.count, - })) || []; + value: item.count, + })) ?? []; - const registrationsChartData = data.registrations_by_day?.map((item) => ({ + const eventsSparkline = data.events_by_day?.map((item) => ({ date: item.date, - registrations: item.count, - })) || []; + value: item.count, + })) ?? []; return (

Общая статистика

- -
- } - style={{ flex: '0 0 auto', marginRight: 16 }} - /> - {registrationsChartData.length > 0 && ( - - - - - - - - - `Дата: ${label}`} /> - - - )} -
-
+ } + data={registrationsSparkline} + color="#52c41a" + gradientId="colorRegistrations" + /> - -
- } - style={{ flex: '0 0 auto', marginRight: 16 }} - /> - {eventsChartData.length > 0 && ( - - - - - - - - - `Дата: ${label}`} /> - - - )} -
-
+ } + data={eventsSparkline} + color="#1890ff" + gradientId="colorEvents" + /> @@ -240,17 +201,14 @@ const DashboardPage: React.FC = () => {
- {data.admin_activity && data.admin_activity.length > 0 && ( - <> -

Активность администраторов

- - + {role === 'superadmin' && ( + Подробный журнал действий — в разделе Аудит.} + /> )} ); diff --git a/src/types/api.ts b/src/types/api.ts index 0f3d819..39ad43e 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -350,6 +350,11 @@ export interface DashboardStats { tickets_by_day?: DayCount[]; subscriptions_by_day?: DayCount[]; pending_users_by_day?: DayCount[]; + avg_report_resolution_h?: number; + events_moderated?: number; + // support + tickets_assigned_open?: number; + tickets_assigned_total?: number; } export interface AdminActivity {