diff --git a/messages/en-US.json b/messages/en-US.json index 90097860..4ddb1f7d 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -442,6 +442,9 @@ "totalBlocked": "Requests Blocked By Pangolin", "totalRequests": "Total Requests", "requestsByCountry": "Requests By Country", + "requestsByDay": "Requests By Day", + "blocked": "Blocked", + "allowed": "Allowed", "topCountries": "Top Countries", "accessRoleSelect": "Select role", "inviteEmailSentDescription": "An email has been sent to the user with the access link below. They must access the link to accept the invitation.", diff --git a/src/components/LogAnalyticsData.tsx b/src/components/LogAnalyticsData.tsx index f6845742..9cc980b9 100644 --- a/src/components/LogAnalyticsData.tsx +++ b/src/components/LogAnalyticsData.tsx @@ -41,6 +41,15 @@ import { TooltipProvider, TooltipTrigger } from "./ui/tooltip"; +import { + ChartContainer, + ChartLegend, + ChartLegendContent, + ChartTooltip, + ChartTooltipContent, + type ChartConfig +} from "./ui/chart"; +import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"; export type AnalyticsContentProps = { orgId: string; @@ -271,14 +280,26 @@ export function LogAnalyticsData(props: AnalyticsContentProps) { + + +

{t("requestsByDay")}

+
+ + + +
+
- +

{t("requestsByCountry")}

- + - +

{t("topCountries")}

@@ -306,6 +327,179 @@ export function LogAnalyticsData(props: AnalyticsContentProps) { ); } +type RequestChartProps = { + data: { + day: string; + allowedCount: number; + blockedCount: number; + totalCount: number; + }[]; + isLoading: boolean; +}; + +function RequestChart(props: RequestChartProps) { + const t = useTranslations(); + + const numberFormatter = new Intl.NumberFormat(navigator.language, { + maximumFractionDigits: 1, + notation: "compact", + compactDisplay: "short" + }); + + const chartConfig = { + blockedCount: { + label: t("blocked"), + color: "var(--chart-5)" + }, + allowedCount: { + label: t("allowed"), + color: "var(--chart-2)" + } + } satisfies ChartConfig; + + return ( + + + } /> + { + const formattedDate = new Date( + item.payload.day + ).toLocaleDateString(navigator.language, { + dateStyle: "medium" + }); + + const value_str = numberFormatter.format( + value as number + ); + + const config = + chartConfig[ + name as keyof typeof chartConfig + ]; + + return ( +
+ {index === 0 && ( + {formattedDate} + )} + +
+
+
+ + {config.label} + +
+
+ {value_str} +
+
+
+ ); + }} + /> + } + /> + + + datum.totalCount)) + ]} + allowDataOverflow + type="number" + tickFormatter={(value) => { + return numberFormatter.format(value); + }} + /> + { + return new Date(value).toLocaleDateString( + navigator.language, + { + dateStyle: "medium" + } + ); + }} + /> + + + + + + + + + + + + + + + + + ); +} + type TopCountriesListProps = { countries: { code: string; @@ -322,7 +516,7 @@ function TopCountriesList(props: TopCountriesListProps) { fallback: "code" }); - const formatter = new Intl.NumberFormat(navigator.language, { + const numberFormatter = new Intl.NumberFormat(navigator.language, { maximumFractionDigits: 1, notation: "compact", compactDisplay: "short" @@ -381,7 +575,7 @@ function TopCountriesList(props: TopCountriesListProps) {