diff --git a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts index 01f2b6b83c..c02fa8d610 100644 --- a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts +++ b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts @@ -89,16 +89,16 @@ export const fetchLatestBusinessReport = async ({ export const fetchBusinessReports = async (params: { reportType?: MerchantReportType; - riskLevels: TRiskLevel[]; - statuses: TReportStatusValue[]; - findings: string[]; + riskLevels?: TRiskLevel[]; + statuses?: TReportStatusValue[]; + findings?: string[]; from?: string; to?: string; - page: { + page?: { number: number; size: number; }; - orderBy: string; + orderBy?: string; }) => { const queryParams = qs.stringify(params, { encode: false }); diff --git a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx index d82c352987..eb2d6d8f96 100644 --- a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx +++ b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx @@ -20,14 +20,14 @@ export const useBusinessReportsQuery = ({ isAlert, }: { reportType?: MerchantReportType; - search: string; - page: number; - pageSize: number; - sortBy: string; - sortDir: string; - riskLevels: TRiskLevel[]; - statuses: TReportStatusValue[]; - findings: string[]; + search?: string; + page?: number; + pageSize?: number; + sortBy?: string; + sortDir?: string; + riskLevels?: TRiskLevel[]; + statuses?: TReportStatusValue[]; + findings?: string[]; from?: string; to?: string; isAlert?: boolean; diff --git a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts index b58ce7a74e..7a0f01454c 100644 --- a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts +++ b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts @@ -17,14 +17,14 @@ export const businessReportsQueryKey = createQueryKeys('business-reports', { ...params }: { reportType?: MerchantReportType; - search: string; - page: number; - pageSize: number; - sortBy: string; - sortDir: string; - riskLevels: TRiskLevel[]; - statuses: TReportStatusValue[]; - findings: string[]; + search?: string; + page?: number; + pageSize?: number; + sortBy?: string; + sortDir?: string; + riskLevels?: TRiskLevel[]; + statuses?: TReportStatusValue[]; + findings?: string[]; from?: string; to?: string; isAlert?: boolean; diff --git a/apps/backoffice-v2/src/pages/Root/Root.page.tsx b/apps/backoffice-v2/src/pages/Root/Root.page.tsx index f2fa055f7d..59319d16f1 100644 --- a/apps/backoffice-v2/src/pages/Root/Root.page.tsx +++ b/apps/backoffice-v2/src/pages/Root/Root.page.tsx @@ -5,7 +5,6 @@ import { FullScreenLoader } from '@/common/components/molecules/FullScreenLoader import Chatbot from '@/domains/chat/chatbot-opengpt'; import { env } from '@/common/env/env'; import { Outlet } from 'react-router-dom'; -import { ServerDownLayout } from './ServerDown.layout'; const ReactQueryDevtools = lazy(() => process.env.NODE_ENV !== 'production' @@ -44,9 +43,7 @@ const ChatbotLayout: FunctionComponent = () => { export const Root: FunctionComponent = () => { return ( - - - + {/**/} {/* */} diff --git a/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/PortfolioRiskStatistics.tsx b/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/PortfolioRiskStatistics.tsx index 2e70239acb..e1a37d5e7c 100644 --- a/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/PortfolioRiskStatistics.tsx +++ b/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/PortfolioRiskStatistics.tsx @@ -16,8 +16,8 @@ import { titleCase } from 'string-ts'; import { usePortfolioRiskStatisticsLogic } from '@/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic'; import { z } from 'zod'; import { MetricsResponseSchema } from '@/domains/business-reports/hooks/queries/useBusinessReportMetricsQuery/useBusinessReportMetricsQuery'; -import { Link, useNavigate } from 'react-router-dom'; -import { useLocale } from '@/common/hooks/useLocale/useLocale'; +import { Link } from 'react-router-dom'; +import { buttonVariants, WarningFilledSvg } from '@ballerine/ui'; export const PortfolioRiskStatistics: FunctionComponent< Pick, 'riskLevelCounts' | 'violationCounts'> @@ -29,21 +29,23 @@ export const PortfolioRiskStatistics: FunctionComponent< riskLevelToBackgroundColor, totalRiskIndicators, filteredRiskIndicators, + locale, + navigate, + from, + to, + alertedReports, } = usePortfolioRiskStatisticsLogic({ riskLevelCounts, violationCounts, }); - const locale = useLocale(); - const navigate = useNavigate(); - return (

Portfolio Risk Statistics

- Merchant Monitoring Risk + Merchant Monitoring Risk

Risk levels of all merchant monitoring reports. @@ -119,7 +121,7 @@ export const PortfolioRiskStatistics: FunctionComponent<

- Top 10 Content Violations + Top 10 Content Violations @@ -152,6 +154,32 @@ export const PortfolioRiskStatistics: FunctionComponent< +
+ + Unresolved Monitoring Alerts + +
+
+ + + {Intl.NumberFormat().format(alertedReports)} + +
+ + View + +
+
+
+
); diff --git a/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic.tsx b/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic.tsx index 2393168308..82521cebfa 100644 --- a/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic.tsx +++ b/apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic.tsx @@ -7,6 +7,13 @@ import { } from '@/pages/Statistics/components/PortfolioRiskStatistics/constants'; import { z } from 'zod'; import { MetricsResponseSchema } from '@/domains/business-reports/hooks/queries/useBusinessReportMetricsQuery/useBusinessReportMetricsQuery'; +import { useLocale } from '@/common/hooks/useLocale/useLocale'; +import { useNavigate } from 'react-router-dom'; +import { useBusinessReportsQuery } from '@/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery'; +import dayjs from 'dayjs'; +import { useZodSearchParams } from '@/common/hooks/useZodSearchParams/useZodSearchParams'; +import { useAuthenticatedUserQuery } from '@/domains/auth/hooks/queries/useAuthenticatedUserQuery/useAuthenticatedUserQuery'; +import { getStatisticsSearchSchema } from '@/pages/Statistics/hooks/useStatisticsLogic'; export const usePortfolioRiskStatisticsLogic = ({ riskLevelCounts, @@ -40,6 +47,29 @@ export const usePortfolioRiskStatisticsLogic = ({ ), [filteredRiskIndicators], ); + const locale = useLocale(); + const navigate = useNavigate(); + const getLast30DaysDateRange = () => { + const today = dayjs(); + const thirtyDaysAgo = today.subtract(30, 'day'); + + return { + from: thirtyDaysAgo.format('YYYY-MM-DD'), + to: today.format('YYYY-MM-DD'), + }; + }; + + const last30DaysDateRange = getLast30DaysDateRange(); + const { data: userData } = useAuthenticatedUserQuery(); + const registrationDate = new Date(userData?.user?.registrationDate ?? '1970-01-01'); + const StatisticsSearchSchema = getStatisticsSearchSchema(registrationDate); + const [{ from }] = useZodSearchParams(StatisticsSearchSchema); + const { data: businessReports } = useBusinessReportsQuery({ + isAlert: true, + from, + to: dayjs(from).add(1, 'month').format('YYYY-MM-DD'), + }); + const alertedReports = businessReports?.data?.length ?? 0; return { riskLevelToFillColor, @@ -50,5 +80,10 @@ export const usePortfolioRiskStatisticsLogic = ({ onSortRiskIndicators, filteredRiskIndicators, totalRiskIndicators, + locale, + navigate, + from: last30DaysDateRange.from, + to: last30DaysDateRange.to, + alertedReports, }; }; diff --git a/apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx b/apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx index ffcaaf44ad..dca35fd8ed 100644 --- a/apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx +++ b/apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx @@ -5,11 +5,8 @@ import dayjs from 'dayjs'; import { useState } from 'react'; import { z } from 'zod'; -export const useStatisticsLogic = () => { - const { data: userData } = useAuthenticatedUserQuery(); - const registrationDate = new Date(userData?.user?.registrationDate ?? '1970-01-01'); - - const StatisticsSearchSchema = z.object({ +export const getStatisticsSearchSchema = (registrationDate: Date) => + z.object({ from: z .string() .optional() @@ -25,6 +22,10 @@ export const useStatisticsLogic = () => { }), }); +export const useStatisticsLogic = () => { + const { data: userData } = useAuthenticatedUserQuery(); + const registrationDate = new Date(userData?.user?.registrationDate ?? '1970-01-01'); + const StatisticsSearchSchema = getStatisticsSearchSchema(registrationDate); const [{ from }, setSearchParams] = useZodSearchParams(StatisticsSearchSchema); const [date, setDate] = useState(from ?? undefined); const { data, isLoading, error } = useBusinessReportMetricsQuery({