From f2428d7fde31399c296f04984b472a86a77f1fc1 Mon Sep 17 00:00:00 2001 From: smanylov Date: Thu, 19 Mar 2026 12:49:46 +0700 Subject: [PATCH] update general statistic and analytic --- src/app/[locale]/pages/reports/page.tsx | 4 +- src/app/[locale]/pages/violations/page.tsx | 13 ++-- src/app/actions/violationActions.ts | 50 +++++++++++-- .../components/tanstak-table/TanstakTable.tsx | 3 - .../useViolationAnalyticStatistic.ts | 22 ++++++ .../react-query/useViolationGeography.ts | 24 ------ .../react-query/useViolationStatistic.ts | 25 +++++++ .../reports/analytics-card-distribution.tsx | 52 +++++++++++++ .../ui/reports/analytics-card-geography.tsx | 74 +++++++++---------- src/app/ui/reports/final-summary.tsx | 10 ++- src/app/ui/reports/reports-info.tsx | 6 +- .../ui/violations/violations-statistic.tsx | 15 ++-- src/i18n/messages/en.json | 3 +- src/i18n/messages/ru.json | 3 +- 14 files changed, 210 insertions(+), 94 deletions(-) create mode 100644 src/app/hooks/react-query/useViolationAnalyticStatistic.ts delete mode 100644 src/app/hooks/react-query/useViolationGeography.ts create mode 100644 src/app/hooks/react-query/useViolationStatistic.ts create mode 100644 src/app/ui/reports/analytics-card-distribution.tsx diff --git a/src/app/[locale]/pages/reports/page.tsx b/src/app/[locale]/pages/reports/page.tsx index f8708d1..4fe98d5 100644 --- a/src/app/[locale]/pages/reports/page.tsx +++ b/src/app/[locale]/pages/reports/page.tsx @@ -5,6 +5,7 @@ import AnalyticsCardGeography from '@/app/ui/reports/analytics-card-geography'; import ActivityByContentType from '@/app/ui/reports/activity-by-content-type'; import PageTitle from '@/app/ui/page-title'; import ReportsInfo from '@/app/ui/reports/reports-info'; +import AnalyticsCardDistribution from '@/app/ui/reports/analytics-card-distribution'; export default function Page() { return ( @@ -13,7 +14,8 @@ export default function Page() {
- + {/* */} +
diff --git a/src/app/[locale]/pages/violations/page.tsx b/src/app/[locale]/pages/violations/page.tsx index 43d58a8..99baf38 100644 --- a/src/app/[locale]/pages/violations/page.tsx +++ b/src/app/[locale]/pages/violations/page.tsx @@ -1,13 +1,12 @@ import PageTitleColorFrame from '@/app/ui/page-title-color-frame'; -import DahboardGeographySection from '@/app/ui/dashboard/new/dashboard-geography-section'; -import DashboardPlatformsList from '@/app/ui/dashboard/new/dashboard-platforms-list'; import ViolationsMyCases from '@/app/ui/violations/violations-my-cases'; import ViolationsCheckAllSection from '@/app/ui/violations/violations-check-all-section'; import ViolationsTable from '@/app/ui/violations/violations-table'; import ViolationsStatistic from '@/app/ui/violations/violations-statistic'; -export default function Page() { - const FILE_TYPE = "all"; +import AnalyticsCardGeography from '@/app/ui/reports/analytics-card-geography'; +import AnalyticsCardDistribution from '@/app/ui/reports/analytics-card-distribution'; +export default function Page() { return ( <> -
- - +
+ +
) diff --git a/src/app/actions/violationActions.ts b/src/app/actions/violationActions.ts index 5419470..f3265e6 100644 --- a/src/app/actions/violationActions.ts +++ b/src/app/actions/violationActions.ts @@ -186,11 +186,9 @@ export async function getFileViolations(fileId: string, page: number) { } } -export async function fetchViolationGeography() { +export async function fetchViolationAnalyticStatistic(group: 'domain' | 'tld') { const token = await getSessionData('token'); - /* "group_by": "tld" */ - try { const response = await fetch(`${API_BASE_URL}/api/v1/data`, { method: 'POST', @@ -198,8 +196,10 @@ export async function fetchViolationGeography() { version: 1, msg_id: 30009, message_body: { - group_by: "domain", - token: token + group_by: group, + action: "group", + token: token, + sort_direction: 'desc' } }), headers: { @@ -210,8 +210,44 @@ export async function fetchViolationGeography() { if (response.ok) { let parsed = await response.json(); - if (parsed) { - return parsed; + + if (parsed?.message_body) { + return parsed?.message_body; + } else { + throw null; + } + } else { + throw (`${response.status}`); + } + } catch (error) { + return null + } +} + +export async function fetchViolationStatistic() { + const token = await getSessionData('token'); + + try { + const response = await fetch(`${API_BASE_URL}/api/v1/data`, { + method: 'POST', + body: JSON.stringify({ + version: 1, + msg_id: 30010, + message_body: { + token: token, + } + }), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } + }); + + if (response.ok) { + let parsed = await response.json(); + + if (parsed?.message_body) { + return parsed?.message_body; } else { throw null; } diff --git a/src/app/components/tanstak-table/TanstakTable.tsx b/src/app/components/tanstak-table/TanstakTable.tsx index d71aeac..44d6e13 100644 --- a/src/app/components/tanstak-table/TanstakTable.tsx +++ b/src/app/components/tanstak-table/TanstakTable.tsx @@ -488,9 +488,6 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) { ); const handleView = async (file: FileItem) => { - console.log(`Просмотр файла: ${file.fileName}`); - console.log(file); - const fileInfo = await viewFileInfo(file.id); setOpenWindowChildren(() => { diff --git a/src/app/hooks/react-query/useViolationAnalyticStatistic.ts b/src/app/hooks/react-query/useViolationAnalyticStatistic.ts new file mode 100644 index 0000000..4980a74 --- /dev/null +++ b/src/app/hooks/react-query/useViolationAnalyticStatistic.ts @@ -0,0 +1,22 @@ +import { useQuery } from '@tanstack/react-query'; +import { fetchViolationAnalyticStatistic } from '@/app/actions/violationActions'; + +export interface UseViolationStatistic { + [key: string]: number +} + +export const useViolationAnalyticStatistic = (group: 'domain' | 'tld') => { + return useQuery({ + queryKey: ['violationAnalyticStatistic', group], + queryFn: () => { + return fetchViolationAnalyticStatistic(group) + }, + select: (data: UseViolationStatistic | null) => { + if (!data) { + return null + } + return data; + }, + retry: false + }); +}; \ No newline at end of file diff --git a/src/app/hooks/react-query/useViolationGeography.ts b/src/app/hooks/react-query/useViolationGeography.ts deleted file mode 100644 index 9d758b2..0000000 --- a/src/app/hooks/react-query/useViolationGeography.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; -import { fetchViolationGeography } from '@/app/actions/violationActions'; - -export interface UseViolationGeography { - ru: number; - usa: number; - uk: number; - ge: number; -} - -export const useViolationGeography = () => { - return useQuery({ - queryKey: ['violationGeography'], - queryFn: fetchViolationGeography, - select: (data): any | null => { - if (!data) { - return [] - } - - return data; - }, - retry: false - }); -}; \ No newline at end of file diff --git a/src/app/hooks/react-query/useViolationStatistic.ts b/src/app/hooks/react-query/useViolationStatistic.ts new file mode 100644 index 0000000..2f9d66f --- /dev/null +++ b/src/app/hooks/react-query/useViolationStatistic.ts @@ -0,0 +1,25 @@ +import { useQuery } from '@tanstack/react-query'; +import { fetchViolationStatistic } from '@/app/actions/violationActions'; + +export interface UseViolationStatistic { + total_violations: 2565, + new_violations: 2565, + in_progress_violations: 0, + resolved_violations: 0 +} + +export const useViolationStatistic = () => { + return useQuery({ + queryKey: ['violationStatistic'], + queryFn: () => { + return fetchViolationStatistic() + }, + select: (data: UseViolationStatistic | null) => { + if (!data) { + return null + } + return data; + }, + retry: false + }); +}; \ No newline at end of file diff --git a/src/app/ui/reports/analytics-card-distribution.tsx b/src/app/ui/reports/analytics-card-distribution.tsx new file mode 100644 index 0000000..c742245 --- /dev/null +++ b/src/app/ui/reports/analytics-card-distribution.tsx @@ -0,0 +1,52 @@ +'use client' + +import { useTranslations } from 'next-intl' +import { useViolationAnalyticStatistic, UseViolationStatistic } from '@/app/hooks/react-query/useViolationAnalyticStatistic'; + +interface DomainListProps { + data: UseViolationStatistic; +} + +export default function AnalyticsCardDistribution() { + const t = useTranslations('Global'); + const { data: violationGeography, isLoading, isError, error } = useViolationAnalyticStatistic('domain'); + + const DomainList = ({ data }: DomainListProps) => { + const topDomains = Object.entries(data) + .map(([domain, count]) => ({ domain, count })) + .sort((a, b) => b.count - a.count) + .slice(0, 6); + + return ( +
+ {topDomains.map((item, index) => ( +
+ + {item.domain} + + + {item.count} + +
+ ))} +
+ ); + }; + + return ( +
+
+
+

+ {t('distribution-analytics')} +

+
+ {violationGeography && ( + + )} +
+ ) +} \ No newline at end of file diff --git a/src/app/ui/reports/analytics-card-geography.tsx b/src/app/ui/reports/analytics-card-geography.tsx index 32fbb0a..28f9f7a 100644 --- a/src/app/ui/reports/analytics-card-geography.tsx +++ b/src/app/ui/reports/analytics-card-geography.tsx @@ -1,11 +1,40 @@ 'use client' import { useTranslations } from 'next-intl' -import {useViolationGeography} from '@/app/hooks/react-query/useViolationGeography'; +import {useViolationAnalyticStatistic, UseViolationStatistic} from '@/app/hooks/react-query/useViolationAnalyticStatistic'; + +interface DomainListProps { + data: UseViolationStatistic; +} export default function AnalyticsCardGeography() { const t = useTranslations('Global'); - const { data: violationGeography, isLoading, isError, error } = useViolationGeography(); + const { data: violationGeography, isLoading, isError, error } = useViolationAnalyticStatistic('tld'); + + const DomainList = ({ data }: DomainListProps) => { + const topDomains = Object.entries(data) + .map(([domain, count]) => ({ domain, count })) + .sort((a, b) => b.count - a.count) + .slice(0, 6); + + return ( +
+ {topDomains.map((item, index) => ( +
+ + {item.domain} + + + {item.count} + +
+ ))} +
+ ); + }; return (
@@ -15,44 +44,9 @@ export default function AnalyticsCardGeography() { {t('geography-of-violations')}
-
-
- - {t('russia')} - - 0 -
-
- - {t('usa')} - - 0 -
-
- - {t('germany')} - - 0 -
-
- - {t('france')} - - 0 -
-
- - {t('uk')} - - 0 -
-
- - {t('china')} - - 0 -
-
+ {violationGeography && ( + + )}
) } \ No newline at end of file diff --git a/src/app/ui/reports/final-summary.tsx b/src/app/ui/reports/final-summary.tsx index 740d8e0..d75bce5 100644 --- a/src/app/ui/reports/final-summary.tsx +++ b/src/app/ui/reports/final-summary.tsx @@ -3,10 +3,12 @@ import { useUserFilesInfo } from '@/app/hooks/react-query/useUserFilesInfo'; import { useTranslations } from 'next-intl'; import { useEffect } from 'react'; +import { useViolationStatistic } from '@/app/hooks/react-query/useViolationStatistic'; export default function FinalSummary() { const t = useTranslations('Global'); const { data: filesInfo, isLoading, isError, error } = useUserFilesInfo(); + const { data: violationStatistic } = useViolationStatistic(); return (
@@ -30,13 +32,17 @@ export default function FinalSummary() {
{/*
🚨
*/}
-
{filesInfo?.total.violation ? filesInfo?.total.violation : 0}
+
+ {violationStatistic?.new_violations ?? 0} +
{t('violations-found')}
-
0
+
+ {violationStatistic?.in_progress_violations ?? 0} +
{t('violations-registered')}
diff --git a/src/app/ui/reports/reports-info.tsx b/src/app/ui/reports/reports-info.tsx index e628159..f88f584 100644 --- a/src/app/ui/reports/reports-info.tsx +++ b/src/app/ui/reports/reports-info.tsx @@ -2,11 +2,13 @@ import { useTranslations } from 'next-intl'; import { useUserFilesInfo } from '@/app/hooks/react-query/useUserFilesInfo'; -import {IconDocument, IconSearch, IconWarning, IconGraph} from '@/app/ui/icons/icons'; +import { IconDocument, IconSearch, IconWarning, IconGraph } from '@/app/ui/icons/icons'; +import { useViolationStatistic } from '@/app/hooks/react-query/useViolationStatistic'; export default function ReportsInfo() { const t = useTranslations("Global"); const { data: filesInfo, isLoading, isError, error } = useUserFilesInfo(); + const { data: violationStatistic } = useViolationStatistic(); return ( <> @@ -27,7 +29,7 @@ export default function ReportsInfo() {
-
{filesInfo?.total.violation ? filesInfo?.total.violation : 0}
+
{violationStatistic?.total_violations ?? 0}
{t('violations-few')}
diff --git a/src/app/ui/violations/violations-statistic.tsx b/src/app/ui/violations/violations-statistic.tsx index e37dc79..38acd25 100644 --- a/src/app/ui/violations/violations-statistic.tsx +++ b/src/app/ui/violations/violations-statistic.tsx @@ -1,35 +1,38 @@ 'use client' import { useTranslations } from 'next-intl'; -import { useUserFilesInfo } from '@/app/hooks/react-query/useUserFilesInfo'; + +import { useViolationStatistic } from '@/app/hooks/react-query/useViolationStatistic'; export default function ViolationsStatistic() { const t = useTranslations('Global'); - const { data: filesInfo, isLoading, isError, error } = useUserFilesInfo(); + const { data: violationStatistic } = useViolationStatistic(); return (
- {filesInfo?.total.violation} + {violationStatistic?.total_violations ?? 0}
{t(`total-violations`)}
- {filesInfo?.total.violation} + {violationStatistic?.new_violations ?? 0}
{t(`new`)}
- 0 + {violationStatistic?.in_progress_violations ?? 0}
{t(`in-progress`)}
-
0
+
+ {violationStatistic?.resolved_violations ?? 0} +
{t('it-decided')}
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index c8b98e7..4775920 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -341,7 +341,8 @@ "germany": "Germany", "france": "France", "uk": "United Kingdom", - "china": "China" + "china": "China", + "distribution-analytics": "Distribution analytics" }, "Login-register-form": { "and": "and", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index aa7555e..0fdf93d 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -341,7 +341,8 @@ "germany": "Германия", "france": "Франция", "uk": "Великобритания", - "china": "Китай" + "china": "Китай", + "distribution-analytics": "Аналитика распространения" }, "Login-register-form": { "and": "и",