diff --git a/messages/de.json b/messages/de.json index f95878e3d..8d059356a 100644 --- a/messages/de.json +++ b/messages/de.json @@ -1996,6 +1996,9 @@ "webPushGlobal": "Browser-Push-Benachrichtigungen erlauben.", "integrationWebPush": "Web Push", "integrationBugReport": "Bug-Reports", + "offlineGeoLabel": "Geodaten", + "offlineGeoEnabled": "Offline (GeoLite2)", + "offlineGeoFallback": "Fallback (ipwho.is) — MAXMIND_LICENSE_KEY in CI setzen", "apiGlobal": "API-Endpunkte und API-Tokens erlauben.", "umamiTitle": "Umami", "umamiDescription": "Web-Analyse mit Umami", @@ -2176,6 +2179,9 @@ "snapshotStarted": "Gestartet", "snapshotBuildSha": "Build-SHA", "snapshotBuiltAt": "Gebaut am", + "snapshotOfflineGeo": "Geodaten", + "snapshotOfflineGeoOn": "Offline (GeoLite2)", + "snapshotOfflineGeoOff": "Fallback (ipwho.is)", "snapshotLoadError": "System-Snapshot konnte nicht geladen werden.", "snapshotLoading": "Snapshot wird geladen...", "auditTitle": "Letzte Aktivitäten", diff --git a/messages/en.json b/messages/en.json index 389a70156..71589ba8c 100644 --- a/messages/en.json +++ b/messages/en.json @@ -1996,6 +1996,9 @@ "webPushGlobal": "Allow browser push notifications.", "integrationWebPush": "Web Push", "integrationBugReport": "Bug Report", + "offlineGeoLabel": "Geo data", + "offlineGeoEnabled": "Offline (GeoLite2)", + "offlineGeoFallback": "Fallback (ipwho.is) — set MAXMIND_LICENSE_KEY in CI", "apiGlobal": "Allow API endpoints and API tokens.", "umamiTitle": "Umami", "umamiDescription": "Web analytics with Umami", @@ -2176,6 +2179,9 @@ "snapshotStarted": "Started", "snapshotBuildSha": "Build SHA", "snapshotBuiltAt": "Built at", + "snapshotOfflineGeo": "Geo data", + "snapshotOfflineGeoOn": "Offline (GeoLite2)", + "snapshotOfflineGeoOff": "Fallback (ipwho.is)", "snapshotLoadError": "Failed to load system snapshot.", "snapshotLoading": "Loading snapshot...", "auditTitle": "Recent activity", diff --git a/messages/es.json b/messages/es.json index 76e836274..f2c3d9c56 100644 --- a/messages/es.json +++ b/messages/es.json @@ -1996,6 +1996,9 @@ "webPushGlobal": "Allow browser push notifications.", "integrationWebPush": "Web Push", "integrationBugReport": "Bug Report", + "offlineGeoLabel": "Datos geográficos", + "offlineGeoEnabled": "Sin conexión (GeoLite2)", + "offlineGeoFallback": "Respaldo (ipwho.is) — configura MAXMIND_LICENSE_KEY en CI", "apiGlobal": "Allow API endpoints and API tokens.", "umamiTitle": "Umami", "umamiDescription": "Web analytics with Umami", @@ -2176,6 +2179,9 @@ "snapshotStarted": "Started", "snapshotBuildSha": "Build SHA", "snapshotBuiltAt": "Built at", + "snapshotOfflineGeo": "Datos geográficos", + "snapshotOfflineGeoOn": "Sin conexión (GeoLite2)", + "snapshotOfflineGeoOff": "Respaldo (ipwho.is)", "snapshotLoadError": "Failed to load system snapshot.", "snapshotLoading": "Loading snapshot...", "auditTitle": "Recent activity", diff --git a/messages/fr.json b/messages/fr.json index 65c94975d..6935e8e9d 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -1996,6 +1996,9 @@ "webPushGlobal": "Allow browser push notifications.", "integrationWebPush": "Web Push", "integrationBugReport": "Bug Report", + "offlineGeoLabel": "Données géographiques", + "offlineGeoEnabled": "Hors ligne (GeoLite2)", + "offlineGeoFallback": "Fallback (ipwho.is) — définissez MAXMIND_LICENSE_KEY dans la CI", "apiGlobal": "Allow API endpoints and API tokens.", "umamiTitle": "Umami", "umamiDescription": "Web analytics with Umami", @@ -2176,6 +2179,9 @@ "snapshotStarted": "Started", "snapshotBuildSha": "Build SHA", "snapshotBuiltAt": "Built at", + "snapshotOfflineGeo": "Données géographiques", + "snapshotOfflineGeoOn": "Hors ligne (GeoLite2)", + "snapshotOfflineGeoOff": "Fallback (ipwho.is)", "snapshotLoadError": "Failed to load system snapshot.", "snapshotLoading": "Loading snapshot...", "auditTitle": "Recent activity", diff --git a/messages/it.json b/messages/it.json index 21534cb01..18e171790 100644 --- a/messages/it.json +++ b/messages/it.json @@ -1996,6 +1996,9 @@ "webPushGlobal": "Allow browser push notifications.", "integrationWebPush": "Web Push", "integrationBugReport": "Bug Report", + "offlineGeoLabel": "Dati geografici", + "offlineGeoEnabled": "Offline (GeoLite2)", + "offlineGeoFallback": "Fallback (ipwho.is) — imposta MAXMIND_LICENSE_KEY in CI", "apiGlobal": "Allow API endpoints and API tokens.", "umamiTitle": "Umami", "umamiDescription": "Web analytics with Umami", @@ -2176,6 +2179,9 @@ "snapshotStarted": "Started", "snapshotBuildSha": "Build SHA", "snapshotBuiltAt": "Built at", + "snapshotOfflineGeo": "Dati geografici", + "snapshotOfflineGeoOn": "Offline (GeoLite2)", + "snapshotOfflineGeoOff": "Fallback (ipwho.is)", "snapshotLoadError": "Failed to load system snapshot.", "snapshotLoading": "Loading snapshot...", "auditTitle": "Recent activity", diff --git a/messages/pl.json b/messages/pl.json index ed0bfc772..29cc73add 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -1996,6 +1996,9 @@ "webPushGlobal": "Allow browser push notifications.", "integrationWebPush": "Web Push", "integrationBugReport": "Bug Report", + "offlineGeoLabel": "Dane geograficzne", + "offlineGeoEnabled": "Offline (GeoLite2)", + "offlineGeoFallback": "Awaryjne (ipwho.is) — ustaw MAXMIND_LICENSE_KEY w CI", "apiGlobal": "Allow API endpoints and API tokens.", "umamiTitle": "Umami", "umamiDescription": "Web analytics with Umami", @@ -2176,6 +2179,9 @@ "snapshotStarted": "Started", "snapshotBuildSha": "Build SHA", "snapshotBuiltAt": "Built at", + "snapshotOfflineGeo": "Dane geograficzne", + "snapshotOfflineGeoOn": "Offline (GeoLite2)", + "snapshotOfflineGeoOff": "Awaryjne (ipwho.is)", "snapshotLoadError": "Failed to load system snapshot.", "snapshotLoading": "Loading snapshot...", "auditTitle": "Recent activity", diff --git a/src/components/admin/system-status-section.tsx b/src/components/admin/system-status-section.tsx index 54a01e49e..221287c11 100644 --- a/src/components/admin/system-status-section.tsx +++ b/src/components/admin/system-status-section.tsx @@ -13,15 +13,36 @@ import { Globe, Key, Loader2, + Map, RotateCw, Server, Users, } from "lucide-react"; +import { useQuery } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { formatDateTime } from "@/lib/format"; import { useFormatters, useTranslations } from "@/lib/i18n/context"; import { StatusItem, useSystemStatus } from "./_shared"; +interface VersionResponse { + version: string; + buildSha: string | null; + builtAt: string | null; + offlineGeoEnabled?: boolean; +} + +function useOfflineGeoState() { + return useQuery({ + queryKey: ["public", "version"], + queryFn: async () => { + const res = await fetch("/api/version"); + if (!res.ok) throw new Error("Failed to load version"); + return (await res.json()).data as VersionResponse; + }, + staleTime: 5 * 60_000, + }); +} + // v1.4.16 phase B3: Recharts is ~108 KiB Brotli — defer-load the host // metrics chart so the system-status page only ships it when an admin // actually opens this view. Splitting at the wrapper boundary (instead @@ -44,6 +65,7 @@ export function SystemStatusSection() { const { t } = useTranslations(); const fmt = useFormatters(); const { data: status, isError, refetch, isFetching } = useSystemStatus(); + const { data: version } = useOfflineGeoState(); return (