diff --git a/src/app/p/[secret]/layout.tsx b/src/app/p/[secret]/layout.tsx
index 586009f..480e9fe 100644
--- a/src/app/p/[secret]/layout.tsx
+++ b/src/app/p/[secret]/layout.tsx
@@ -5,6 +5,7 @@ import { createTRPCCaller } from "@/trpc/server";
import { timingSafeStringEqual } from "@/lib/timing-safe-compare";
import { AdminMobileNav } from "@/components/admin/AdminMobileNav";
import { AdminSidebarNav } from "@/components/admin/AdminSidebarNav";
+import { ClerkThemeProvider } from "@/components/providers/ClerkThemeProvider";
import {
LayoutDashboard,
Users,
@@ -80,31 +81,43 @@ export default async function AdminLayout({ children, params }: AdminLayoutProps
}));
return (
- // Admin stays permanently dark regardless of the visitor site's theme
- // toggle — a moderator's ops tool, not a marketing surface — but now
- // pinned to PawFeed's own dark palette (the `dark` class resolves the
- // real design tokens) instead of a generic, disconnected zinc scaffold.
-
- {/* Mobile topbar + drawer — hidden md: and up */}
-
+ // ClerkThemeProvider mounts Clerk's client SDK, which keeps the short-lived
+ // __session cookie refreshed in the background. Without it (as before),
+ // this route tree never renewed the token client-side — the initial page
+ // load kept working (Clerk's server-side "handshake" reissues the token on
+ // full document navigations) but subsequent tRPC XHRs (e.g. legal.publish)
+ // started failing with UNAUTHORIZED/401 a few minutes into a session, since
+ // that handshake only runs for navigations, not fetch calls. This does
+ // re-add the ~240 KiB Clerk client bundle that (app)/layout.tsx's
+ // SpeedUp-Plan P0 deliberately kept off non-admin routes — acceptable here
+ // since the admin panel is an internal ops tool, not perf-critical.
+
+ {/* Admin stays permanently dark regardless of the visitor site's theme
+ toggle — a moderator's ops tool, not a marketing surface — but now
+ pinned to PawFeed's own dark palette (the `dark` class resolves the
+ real design tokens) instead of a generic, disconnected zinc scaffold. */}
+
+ {/* Mobile topbar + drawer — hidden md: and up */}
+
- {/* Sidebar — hidden below md:, permanent from md: up */}
-
- {/* Content */}
- {children}
-
+ {/* Content */}
+ {children}
+
+
);
}
diff --git a/src/app/p/[secret]/legal/page.tsx b/src/app/p/[secret]/legal/page.tsx
index c0aa1a6..964e641 100644
--- a/src/app/p/[secret]/legal/page.tsx
+++ b/src/app/p/[secret]/legal/page.tsx
@@ -45,7 +45,18 @@ export default function AdminLegalPage() {
toast.success("Veröffentlicht — Owner sehen die Meldung beim nächsten Laden der App");
setChangeSummary("");
},
- onError: () => toast.error("Veröffentlichung fehlgeschlagen"),
+ // UNAUTHORIZED means the Clerk session cookie went stale (see
+ // ClerkThemeProvider in layout.tsx for the background-refresh fix) —
+ // distinct from every other failure, so surface it with an actionable
+ // message instead of the generic one. The typed text is preserved
+ // (no setChangeSummary("") here) so a reload doesn't lose it.
+ onError: (error) => {
+ if (error.data?.code === "UNAUTHORIZED") {
+ toast.error("Session abgelaufen — bitte Seite neu laden und erneut versuchen");
+ } else {
+ toast.error("Veröffentlichung fehlgeschlagen");
+ }
+ },
})
);