chore: harden deps, env validation, admin errors, and redis warnings
Align nodemailer with Auth.js peers, bump patch deps, validate env on deploy builds, add admin error boundary, and warn when Redis is missing in production. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
c865e6f699
commit
c46dadeda4
10 files changed
+876
-461
No files matched your search
@@ -0,0 +1,69 @@
|
||||
"use client";
|
||||
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { LayoutDashboard, RefreshCw } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useEffect } from "react";
|
||||
|
||||
/**
|
||||
* Admin route-segment error boundary. Renders inside the admin layout shell.
|
||||
*/
|
||||
export default function AdminErrorPage({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}) {
|
||||
const t = useTranslations("pages.error");
|
||||
const tNav = useTranslations("admin.nav");
|
||||
|
||||
useEffect(() => {
|
||||
console.error(error);
|
||||
Sentry.captureException(error);
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="rounded-xl border p-8 max-w-lg mx-auto mt-8 text-center"
|
||||
style={{
|
||||
borderColor: "var(--admin-border, rgba(0,0,0,0.08))",
|
||||
background: "var(--admin-surface, #fff)",
|
||||
}}
|
||||
role="alert"
|
||||
>
|
||||
<p
|
||||
className="text-sm font-bold uppercase tracking-wider mb-2"
|
||||
style={{ color: "var(--admin-muted, #6b7280)" }}
|
||||
>
|
||||
{t("code")}
|
||||
</p>
|
||||
<h1 className="text-xl font-extrabold mb-2">{t("title")}</h1>
|
||||
<p className="text-sm mb-1" style={{ color: "var(--admin-muted, #6b7280)" }}>
|
||||
{t("subtitle")}
|
||||
</p>
|
||||
<p className="text-sm mb-6" style={{ color: "var(--admin-muted, #6b7280)" }}>
|
||||
{t("body")}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3 justify-center">
|
||||
<button type="button" className="btn btn-primary" onClick={() => reset()}>
|
||||
<RefreshCw className="size-4" aria-hidden />
|
||||
{t("tryAgain")}
|
||||
</button>
|
||||
<Link className="btn btn-outline" href="/admin">
|
||||
<LayoutDashboard className="size-4" aria-hidden />
|
||||
{tNav("dashboard")}
|
||||
</Link>
|
||||
</div>
|
||||
{error.digest ? (
|
||||
<p
|
||||
className="mt-6 text-xs font-mono"
|
||||
style={{ color: "var(--admin-muted, #9ca3af)" }}
|
||||
>
|
||||
{t("reference", { digest: error.digest })}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user