From 86d80d2c041b19022ccc0657383a46b0dbdd52d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?=
Date: Wed, 1 Jul 2026 23:44:55 +0200
Subject: [PATCH] refactor(admin): migrate section cards onto the shared card
primitives
The admin tree hand-rolled its card surfaces and stepped padding at sm:
instead of md:, so it read denser than every other route on a tablet.
Move the sections onto SettingsCard/SettingsCardHeader and the mini-rows
onto ListRow; no behaviour, data, or copy changes.
---
.../api-token-overview-responsive.test.tsx | 9 +-
.../user-management-responsive.test.tsx | 4 +-
src/components/admin/ai-quality-section.tsx | 5 +-
.../admin/ai-server-key-section.tsx | 8 +-
.../admin/api-token-overview-section.tsx | 85 ++++++++++--------
.../admin/app-log-preview-section.tsx | 5 +-
src/components/admin/assistant-section.tsx | 5 +-
src/components/admin/backups-section.tsx | 89 ++++++++++---------
.../admin/coach-feedback-section.tsx | 5 +-
.../admin/general-settings-section.tsx | 5 +-
src/components/admin/glitchtip-section.tsx | 5 +-
src/components/admin/host-metrics-chart.tsx | 29 ++----
.../admin/login-overview-section.tsx | 5 +-
.../admin/module-availability-section.tsx | 5 +-
src/components/admin/recent-audit-preview.tsx | 8 +-
src/components/admin/reminders-section.tsx | 9 +-
src/components/admin/services-section.tsx | 5 +-
.../admin/system-status-section.tsx | 9 +-
.../admin/system-status-summary.tsx | 7 +-
src/components/admin/umami-section.tsx | 5 +-
.../admin/user-management-section.tsx | 63 +++++++------
src/components/admin/version-tile-section.tsx | 8 +-
.../admin/web-push-vapid-section.tsx | 5 +-
23 files changed, 200 insertions(+), 183 deletions(-)
diff --git a/src/components/admin/__tests__/api-token-overview-responsive.test.tsx b/src/components/admin/__tests__/api-token-overview-responsive.test.tsx
index 4ab40afa5..16a1eeff5 100644
--- a/src/components/admin/__tests__/api-token-overview-responsive.test.tsx
+++ b/src/components/admin/__tests__/api-token-overview-responsive.test.tsx
@@ -115,11 +115,12 @@ describe("ApiTokenOverviewSection — responsive", () => {
expect(html).toContain("All");
});
- it("uses a smaller card padding on mobile (p-4 sm:p-6)", () => {
+ it("uses a smaller card padding on mobile (p-4 md:p-6)", () => {
const html = render();
- // The card root carries the responsive padding to leave more room
- // for content within a 393 CSS-px viewport.
- expect(html).toMatch(/class="[^"]*\bp-4\b[^"]*sm:p-6/);
+ // The card root carries the shared SettingsCard padding contract
+ // (`p-4 md:p-6`) to leave more room for content within a 393 CSS-px
+ // viewport while stepping up only from `md`, not `sm`.
+ expect(html).toMatch(/class="[^"]*\bp-4\b[^"]*md:p-6/);
});
it("desktop date cells drop whitespace-nowrap (v1.4.22 C2 5th-attempt fix)", () => {
diff --git a/src/components/admin/__tests__/user-management-responsive.test.tsx b/src/components/admin/__tests__/user-management-responsive.test.tsx
index 3dc75b13d..60c5dedb9 100644
--- a/src/components/admin/__tests__/user-management-responsive.test.tsx
+++ b/src/components/admin/__tests__/user-management-responsive.test.tsx
@@ -115,9 +115,9 @@ describe("UserManagementSection — mobile responsive", () => {
expect(mobileSlice).toContain("Force logout");
});
- it("uses smaller card padding on mobile (p-4 sm:p-6)", () => {
+ it("uses smaller card padding on mobile (p-4 md:p-6)", () => {
const html = render();
- expect(html).toMatch(/class="[^"]*\bp-4\b[^"]*sm:p-6/);
+ expect(html).toMatch(/class="[^"]*\bp-4\b[^"]*md:p-6/);
});
it("wraps the filter pills below the title on narrow viewports", () => {
diff --git a/src/components/admin/ai-quality-section.tsx b/src/components/admin/ai-quality-section.tsx
index c43f24e3f..3b0e75ab0 100644
--- a/src/components/admin/ai-quality-section.tsx
+++ b/src/components/admin/ai-quality-section.tsx
@@ -21,6 +21,7 @@
import { useQuery } from "@tanstack/react-query";
import { Sparkles, Loader2 } from "lucide-react";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations, useFormatters } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -75,7 +76,7 @@ export function AiQualitySection() {
// resolves. Mirrors (header outside the
// fetch-state branch).
return (
-
+
)}
-
+
);
}
diff --git a/src/components/admin/ai-server-key-section.tsx b/src/components/admin/ai-server-key-section.tsx
index 5057b824d..16767c2a3 100644
--- a/src/components/admin/ai-server-key-section.tsx
+++ b/src/components/admin/ai-server-key-section.tsx
@@ -9,6 +9,7 @@ import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -92,10 +93,7 @@ export function AiServerKeySection() {
}
return (
-
+
-
+
);
}
diff --git a/src/components/admin/api-token-overview-section.tsx b/src/components/admin/api-token-overview-section.tsx
index 114c2917f..aa3af44c2 100644
--- a/src/components/admin/api-token-overview-section.tsx
+++ b/src/components/admin/api-token-overview-section.tsx
@@ -11,7 +11,9 @@ import {
TooltipTrigger,
} from "@/components/ui/tooltip";
import { formatDate, formatDateTime } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
+import { ListRow } from "@/components/ui/list-row";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
import { type ApiTokenInfo } from "./_shared";
@@ -157,7 +159,7 @@ export function ApiTokenOverviewSection() {
});
return (
-
+
{tokens.map((token) => {
return (
-
-
-
-
-
- {token.permissions.map((p) => (
-
- {p === "*" ? t("admin.tokenPermissionAll") : p}
-
- ))}
-
-
- {t("admin.tokenLastUsed")}:{" "}
- {token.lastUsedAt
- ? formatDateTime(token.lastUsedAt)
- : t("admin.tokenNeverUsed")}
-
-
- {t("admin.tokenCreated")}: {formatDate(token.createdAt)}
-
-
+
+ {token.permissions.map((p) => (
+
+ {p === "*" ? t("admin.tokenPermissionAll") : p}
+
+ ))}
+
+
+ {t("admin.tokenLastUsed")}:{" "}
+ {token.lastUsedAt
+ ? formatDateTime(token.lastUsedAt)
+ : t("admin.tokenNeverUsed")}
+
+
+ {t("admin.tokenCreated")}: {formatDate(token.createdAt)}
+
+
+
);
})}
>
)}
-
+
);
}
diff --git a/src/components/admin/app-log-preview-section.tsx b/src/components/admin/app-log-preview-section.tsx
index 61a46d8a0..995619b62 100644
--- a/src/components/admin/app-log-preview-section.tsx
+++ b/src/components/admin/app-log-preview-section.tsx
@@ -46,6 +46,7 @@ import {
DialogTitle,
} from "@/components/ui/dialog";
import { formatDateTime } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -115,7 +116,7 @@ export function AppLogPreviewSection() {
const events = data?.events ?? [];
return (
-
+
-
+
);
}
diff --git a/src/components/admin/assistant-section.tsx b/src/components/admin/assistant-section.tsx
index 8b49aaee4..a54adbe21 100644
--- a/src/components/admin/assistant-section.tsx
+++ b/src/components/admin/assistant-section.tsx
@@ -4,6 +4,7 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Sparkles } from "lucide-react";
import { toast } from "sonner";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -99,7 +100,7 @@ export function AssistantSection() {
const disabledSubs = !masterOn || mutation.isPending;
return (
-
+
-
+
);
}
diff --git a/src/components/admin/backups-section.tsx b/src/components/admin/backups-section.tsx
index f63244557..bc01e77e5 100644
--- a/src/components/admin/backups-section.tsx
+++ b/src/components/admin/backups-section.tsx
@@ -39,7 +39,9 @@ import { Button } from "@/components/ui/button";
import { EmptyState } from "@/components/ui/empty-state";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
+import { ListRow } from "@/components/ui/list-row";
import { useFormatters, useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
import type { BackupRow, BackupsList } from "@/types/backups";
@@ -332,7 +334,7 @@ export function BackupsSection() {
}
return (
-
+
{/* v1.18.1 E3 — the snapshot count leads (numbers first), the
"Run now" button follows, and the explainer + docs link move
into the header's description slot. Previously the description
@@ -550,48 +552,51 @@ export function BackupsSection() {
data-testid="admin-backups-mobile-list"
>
{rows.map((row) => (
-
-
- {row.username}
-
- {formatBackupType(row.type, t)}
-
-
-
- {t("admin.section.backups.colSize")}:{" "}
- {formatBytes(row.sizeBytes, fmt)} ·{" "}
- {fmt.dateTime(row.createdAt)}
-
-
- handleDownload(row)}
- aria-label={t("admin.section.backups.downloadAria", {
- username: row.username,
- })}
- className="min-h-11"
- >
- {downloadingId === row.id ? (
-
- ) : (
-
- )}
- {t("admin.section.backups.download")}
-
- restore.mutate(row)}
- />
-
-
+
+
+ {row.username}
+
+ {formatBackupType(row.type, t)}
+
+
+
+ {t("admin.section.backups.colSize")}:{" "}
+ {formatBytes(row.sizeBytes, fmt)} ·{" "}
+ {fmt.dateTime(row.createdAt)}
+
+
+ handleDownload(row)}
+ aria-label={t("admin.section.backups.downloadAria", {
+ username: row.username,
+ })}
+ className="min-h-11"
+ >
+ {downloadingId === row.id ? (
+
+ ) : (
+
+ )}
+ {t("admin.section.backups.download")}
+
+ restore.mutate(row)}
+ />
+
+
+
))}
@@ -602,6 +607,6 @@ export function BackupsSection() {
)}
-
+
);
}
diff --git a/src/components/admin/coach-feedback-section.tsx b/src/components/admin/coach-feedback-section.tsx
index c78619301..0308625c4 100644
--- a/src/components/admin/coach-feedback-section.tsx
+++ b/src/components/admin/coach-feedback-section.tsx
@@ -21,6 +21,7 @@
import { useQuery } from "@tanstack/react-query";
import { Loader2, Sparkles } from "lucide-react";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations, useFormatters } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -70,7 +71,7 @@ export function CoachFeedbackSection() {
// /admin/coach-feedback. Mirrors the canonical structure used by
// (header outside the fetch-state branch).
return (
-
+
)}
-
+
);
}
diff --git a/src/components/admin/general-settings-section.tsx b/src/components/admin/general-settings-section.tsx
index 62cb0d438..008edf4fb 100644
--- a/src/components/admin/general-settings-section.tsx
+++ b/src/components/admin/general-settings-section.tsx
@@ -2,6 +2,7 @@
import { useMemo } from "react";
import { Settings } from "lucide-react";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { NativeSelect } from "@/components/ui/native-select";
@@ -26,7 +27,7 @@ export function GeneralSettingsSection() {
const currentDefaultTz = settings?.defaultUserTimezone ?? "";
return (
-
+
-
+
);
}
diff --git a/src/components/admin/glitchtip-section.tsx b/src/components/admin/glitchtip-section.tsx
index c14a18cc8..a608f876c 100644
--- a/src/components/admin/glitchtip-section.tsx
+++ b/src/components/admin/glitchtip-section.tsx
@@ -4,6 +4,7 @@ import { useState } from "react";
import { useMutation } from "@tanstack/react-query";
import { AlertTriangle, Loader2 } from "lucide-react";
import { toast } from "sonner";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -69,7 +70,7 @@ export function GlitchtipSection() {
}
return (
-
+
-
+
);
}
diff --git a/src/components/admin/host-metrics-chart.tsx b/src/components/admin/host-metrics-chart.tsx
index 7188f90f3..0ef11da16 100644
--- a/src/components/admin/host-metrics-chart.tsx
+++ b/src/components/admin/host-metrics-chart.tsx
@@ -39,6 +39,7 @@ import { useMemo } from "react";
import { useFormatters, useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
import { Skeleton } from "@/components/ui/skeleton";
+import { SettingsCard } from "@/components/settings/settings-card";
import { apiGet } from "@/lib/api/api-fetch";
interface HostMetricsApiSample {
@@ -156,10 +157,7 @@ export function HostMetricsChart() {
// jump when data lands. Animated only when motion isn't reduced.
if (isLoading) {
return (
-
+
{t("admin.hostMetrics.title")}
@@ -169,16 +167,13 @@ export function HostMetricsChart() {
-
+
);
}
if (isError) {
return (
-
+
{t("admin.hostMetrics.title")}
@@ -188,7 +183,7 @@ export function HostMetricsChart() {
>
{t("admin.hostMetrics.loadError")}
-
+
);
}
@@ -197,10 +192,7 @@ export function HostMetricsChart() {
// instead of an empty plot.
if (rows.length === 0) {
return (
-
+
{t("admin.hostMetrics.title")}
@@ -212,15 +204,12 @@ export function HostMetricsChart() {
{t("admin.hostMetrics.empty")}
-
+
);
}
return (
-
+
{t("admin.hostMetrics.title")}
@@ -354,6 +343,6 @@ export function HostMetricsChart() {
-
+
);
}
diff --git a/src/components/admin/login-overview-section.tsx b/src/components/admin/login-overview-section.tsx
index 54a6059fc..601a67d80 100644
--- a/src/components/admin/login-overview-section.tsx
+++ b/src/components/admin/login-overview-section.tsx
@@ -25,6 +25,7 @@ import {
SelectValue,
} from "@/components/ui/select";
import { formatDateTime } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -219,7 +220,7 @@ export function LoginOverviewSection() {
}
return (
-
+
)}
-
+
);
}
diff --git a/src/components/admin/module-availability-section.tsx b/src/components/admin/module-availability-section.tsx
index c552c0245..e578d451f 100644
--- a/src/components/admin/module-availability-section.tsx
+++ b/src/components/admin/module-availability-section.tsx
@@ -4,6 +4,7 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { ToggleLeft } from "lucide-react";
import { toast } from "sonner";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -87,7 +88,7 @@ export function ModuleAvailabilitySection() {
const availability = data?.availability;
return (
-
+
-
+
);
}
diff --git a/src/components/admin/recent-audit-preview.tsx b/src/components/admin/recent-audit-preview.tsx
index 486afb127..6f112b24c 100644
--- a/src/components/admin/recent-audit-preview.tsx
+++ b/src/components/admin/recent-audit-preview.tsx
@@ -20,6 +20,7 @@ import {
} from "lucide-react";
import { EmptyState } from "@/components/ui/empty-state";
import { formatDateTime } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -53,10 +54,7 @@ export function RecentAuditPreview() {
const entries = data?.entries ?? [];
return (
-
+
);
}
diff --git a/src/components/admin/reminders-section.tsx b/src/components/admin/reminders-section.tsx
index 18dae6626..3c8b39f0b 100644
--- a/src/components/admin/reminders-section.tsx
+++ b/src/components/admin/reminders-section.tsx
@@ -15,6 +15,7 @@ import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -53,7 +54,7 @@ function NotificationHealthPanel() {
});
return (
-
+
)}
-
+
);
}
@@ -194,7 +195,7 @@ export function RemindersSection() {
return (
<>
-
+
{/* v1.4.22 D / F-58 — icon swap so the section header matches
the admin-shell nav tile (Bell). Clock now lives on the
timing chips inline instead of competing as the page icon. */}
@@ -404,7 +405,7 @@ export function RemindersSection() {
)}
-
+
>
);
diff --git a/src/components/admin/services-section.tsx b/src/components/admin/services-section.tsx
index 17a3bd784..27ff8e02b 100644
--- a/src/components/admin/services-section.tsx
+++ b/src/components/admin/services-section.tsx
@@ -1,6 +1,7 @@
"use client";
import { Bell, Globe, Key, MessageCircle, Smile } from "lucide-react";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { SettingsToggle, useAdminSettings, useUpdateSettings } from "./_shared";
@@ -11,7 +12,7 @@ export function ServicesSection() {
const updateSettings = useUpdateSettings();
return (
-
+
-
+
);
}
diff --git a/src/components/admin/system-status-section.tsx b/src/components/admin/system-status-section.tsx
index e14543a84..244087d7c 100644
--- a/src/components/admin/system-status-section.tsx
+++ b/src/components/admin/system-status-section.tsx
@@ -13,13 +13,14 @@ import {
Key,
Loader2,
Map,
- RotateCw,
+ RefreshCw,
Server,
Users,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { formatDateTime } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useFormatters, useTranslations } from "@/lib/i18n/context";
import { StatusItem, usePublicVersion, useSystemStatus } from "./_shared";
@@ -51,7 +52,7 @@ export function SystemStatusSection() {
return (
-
+
) : (
-
+
)}
{t("admin.systemStatusRetry")}
@@ -218,7 +219,7 @@ export function SystemStatusSection() {
)}
-
+
);
}
diff --git a/src/components/admin/system-status-summary.tsx b/src/components/admin/system-status-summary.tsx
index 72583f105..c21a0ed3e 100644
--- a/src/components/admin/system-status-summary.tsx
+++ b/src/components/admin/system-status-summary.tsx
@@ -23,6 +23,7 @@ import {
Tag,
} from "lucide-react";
import { formatDateTime } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { StatusItem, usePublicVersion, useSystemStatus } from "./_shared";
@@ -33,9 +34,9 @@ export function SystemStatusSummary() {
const { data: version } = usePublicVersion();
return (
-
+
);
}
diff --git a/src/components/admin/umami-section.tsx b/src/components/admin/umami-section.tsx
index 6a92dd0a8..b19d6327a 100644
--- a/src/components/admin/umami-section.tsx
+++ b/src/components/admin/umami-section.tsx
@@ -4,6 +4,7 @@ import { useState } from "react";
import { useMutation } from "@tanstack/react-query";
import { Activity, Loader2 } from "lucide-react";
import { toast } from "sonner";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -72,7 +73,7 @@ export function UmamiSection() {
}
return (
-
+
-
+
);
}
diff --git a/src/components/admin/user-management-section.tsx b/src/components/admin/user-management-section.tsx
index 320618621..f9412c43b 100644
--- a/src/components/admin/user-management-section.tsx
+++ b/src/components/admin/user-management-section.tsx
@@ -30,7 +30,9 @@ import {
} from "@/components/ui/alert-dialog";
import { useAuth } from "@/hooks/use-auth";
import { formatDate } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
+import { ListRow } from "@/components/ui/list-row";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
import { type AdminUser, PasswordInput } from "./_shared";
@@ -253,7 +255,7 @@ export function UserManagementSection() {
);
return (
-
+
{filteredUsers.map((u) => (
-
-
-
-
-
- {u.username}
-
-
- {u.role}
-
+
+
+
+
+
+ {u.username}
+
+
+ {u.role}
+
+
+
+ {u.email || "—"}
+
+
+ {t("admin.userPasskeys")}: {u.passkeyCount} ·{" "}
+ {formatDate(u.createdAt)}
+
-
- {u.email || "—"}
-
-
- {t("admin.userPasskeys")}: {u.passkeyCount} ·{" "}
- {formatDate(u.createdAt)}
-
-
-
- {renderUserActions(u)}
-
-
+
+ {renderUserActions(u)}
+
+
+
))}
>
@@ -594,6 +601,6 @@ export function UserManagementSection() {
-
+
);
}
diff --git a/src/components/admin/version-tile-section.tsx b/src/components/admin/version-tile-section.tsx
index fd7e0eda3..7389d6c0b 100644
--- a/src/components/admin/version-tile-section.tsx
+++ b/src/components/admin/version-tile-section.tsx
@@ -25,6 +25,7 @@ import {
} from "lucide-react";
import { useQuery } from "@tanstack/react-query";
import { formatDateTime } from "@/lib/format";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
@@ -82,10 +83,7 @@ export function VersionTileSection() {
const sha = shortSha(version?.buildSha ?? null);
return (
-
-
+
);
}
diff --git a/src/components/admin/web-push-vapid-section.tsx b/src/components/admin/web-push-vapid-section.tsx
index 16092aa65..c3acb4213 100644
--- a/src/components/admin/web-push-vapid-section.tsx
+++ b/src/components/admin/web-push-vapid-section.tsx
@@ -4,6 +4,7 @@ import { useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { BellRing, KeyRound, Loader2 } from "lucide-react";
+import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { Button } from "@/components/ui/button";
import {
@@ -119,7 +120,7 @@ export function WebPushVapidSection() {
}
return (
-
+
-
+
);
}