diff --git a/src/frontend/config/api.ts b/src/frontend/config/api.ts index f240f84..f56a9c8 100644 --- a/src/frontend/config/api.ts +++ b/src/frontend/config/api.ts @@ -33,6 +33,11 @@ export const API_URLS = { return `${DESA_PLUS_PROXY}/api/monitoring/log-all-villages?${params}` }, getStaleVillages: (days: 7 | 14 | 30 = 7) => `${DESA_PLUS_PROXY}/api/monitoring/stale-villages?days=${days}`, + getPeakHours: (idVillage?: string) => { + const params = new URLSearchParams() + if (idVillage) params.set('idVillage', idVillage) + return `${DESA_PLUS_PROXY}/api/monitoring/peak-hours?${params}` + }, getInactiveUsers: (days: 7 | 14 | 30 = 7, idVillage?: string, page = 1) => { const params = new URLSearchParams({ days: String(days), page: String(page) }) if (idVillage) params.set('idVillage', idVillage) diff --git a/src/frontend/routes/apps.$appId.villages.$villageId.tsx b/src/frontend/routes/apps.$appId.villages.$villageId.tsx index f50a798..970fc52 100644 --- a/src/frontend/routes/apps.$appId.villages.$villageId.tsx +++ b/src/frontend/routes/apps.$appId.villages.$villageId.tsx @@ -1,4 +1,4 @@ -import { AreaChart } from '@mantine/charts' +import { AreaChart, BarChart } from '@mantine/charts' import { Badge, Box, @@ -194,6 +194,73 @@ function ActivityChart({ villageId }: { villageId: string }) { ) } +// ── Peak Hours Chart ────────────────────────────────────────────────────────── + +function PeakHoursChart({ villageId }: { villageId: string }) { + const { data: response, isLoading } = useSWR(API_URLS.getPeakHours(villageId), fetcher) + const hours: { hour: number; label: string; count: number }[] = response?.data?.hours || [] + const peak: { label: string; count: number } | null = response?.data?.peak || null + + return ( + + + + + + + + Peak Activity Hours + + {peak && peak.count > 0 + ? `Busiest hour: ${peak.label} (${peak.count.toLocaleString()} activities)` + : 'No activity data'} + + + + + + {isLoading ? ( + + + + ) : ( + { + if (!active || !payload?.length) return null + return ( + + {label} + + Activities: {payload[0].value} + + + ) + }, + }} + /> + )} + + ) +} + // ── Recent Activity Logs ────────────────────────────────────────────────────── function RecentVillageLogs({ villageId }: { villageId: string }) { @@ -563,6 +630,9 @@ function VillageDetailPage() { {/* ── Activity Chart ── */} + {/* ── Peak Hours Chart ── */} + + {/* ── Recent Logs + System Info ── */}