@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
369 lines (368 loc) • 11.7 kB
JavaScript
'use client';
import { jsx as e, jsxs as l } from "react/jsx-runtime";
import "@emotion/styled";
import { Button as E } from "../../ui/button/button.js";
import { Card as k, CardHeader as N, CardBody as b } from "../../ui/card/card.js";
import { motion as v } from "framer-motion";
import c from "react";
import { useConfig as S } from "../../../hooks/use-config.js";
import { useTheme as D } from "../../../hooks/use-theme.js";
var L = Object.defineProperty, C = (t, r, o) => r in t ? L(t, r, { enumerable: !0, configurable: !0, writable: !0, value: o }) : t[r] = o, f = (t, r, o) => C(t, typeof r != "symbol" ? r + "" : r, o);
function B({
error: t,
errorInfo: r,
resetError: o,
showDetails: s = !1,
title: n = "Something went wrong",
subtitle: i = "An unexpected error occurred while processing your request.",
className: u = ""
}) {
const { getColorValue: g } = D(), { organizationSettings: h } = S(), [d, x] = c.useState(!1), w = c.useMemo(() => {
const a = t.message.toLowerCase();
return a.includes("network") || a.includes("fetch") ? "network" : a.includes("auth") || a.includes("unauthorized") ? "auth" : a.includes("permission") || a.includes("forbidden") ? "permission" : a.includes("timeout") ? "timeout" : "unknown";
}, [t.message]), p = {
network: {
title: "Connection Problem",
subtitle: "Please check your internet connection and try again.",
action: "Retry"
},
auth: {
title: "Authentication Error",
subtitle: "Please sign in again to continue.",
action: "Sign In"
},
permission: {
title: "Access Denied",
subtitle: "You don't have permission to access this resource.",
action: "Go Back"
},
timeout: {
title: "Request Timeout",
subtitle: "The request took too long to complete. Please try again.",
action: "Retry"
},
unknown: {
title: n,
subtitle: i,
action: "Retry"
}
}[w], y = () => {
switch (w) {
case "network":
return /* @__PURE__ */ e(
"svg",
{
className: "w-12 h-12 text-warning-500",
fill: "none",
stroke: "currentColor",
viewBox: "0 0 24 24",
children: /* @__PURE__ */ e(
"path",
{
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 2,
d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.732 16.5c-.77.833.192 2.5 1.732 2.5z"
}
)
}
);
case "auth":
return /* @__PURE__ */ e(
"svg",
{
className: "w-12 h-12 text-danger-500",
fill: "none",
stroke: "currentColor",
viewBox: "0 0 24 24",
children: /* @__PURE__ */ e(
"path",
{
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 2,
d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
}
)
}
);
case "permission":
return /* @__PURE__ */ e(
"svg",
{
className: "w-12 h-12 text-warning-500",
fill: "none",
stroke: "currentColor",
viewBox: "0 0 24 24",
children: /* @__PURE__ */ e(
"path",
{
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 2,
d: "M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728L5.636 5.636m12.728 12.728L5.636 5.636"
}
)
}
);
case "timeout":
return /* @__PURE__ */ e(
"svg",
{
className: "w-12 h-12 text-warning-500",
fill: "none",
stroke: "currentColor",
viewBox: "0 0 24 24",
children: /* @__PURE__ */ e(
"path",
{
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 2,
d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
}
)
}
);
default:
return /* @__PURE__ */ e(
"svg",
{
className: "w-12 h-12 text-danger-500",
fill: "none",
stroke: "currentColor",
viewBox: "0 0 24 24",
children: /* @__PURE__ */ e(
"path",
{
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 2,
d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.732 16.5c-.77.833.192 2.5 1.732 2.5z"
}
)
}
);
}
};
return /* @__PURE__ */ e(
v.div,
{
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
className: `flex items-center justify-center min-h-64 p-4 ${u}`,
children: /* @__PURE__ */ l(k, { className: "w-full max-w-md", children: [
/* @__PURE__ */ l(N, { className: "flex flex-col items-center text-center", children: [
h?.branding?.logoUrl && /* @__PURE__ */ e(
"img",
{
src: h.branding.logoUrl,
alt: "Logo",
className: "h-8 w-auto mb-4"
}
),
/* @__PURE__ */ e("div", { className: "mb-4", children: y() }),
/* @__PURE__ */ e("h3", { className: "text-xl font-semibold text-foreground mb-2", children: p.title }),
/* @__PURE__ */ e("p", { className: "text-default-500 text-sm mb-4", children: p.subtitle })
] }),
/* @__PURE__ */ e(b, { className: "pt-0", children: /* @__PURE__ */ l("div", { className: "space-y-4", children: [
/* @__PURE__ */ l("div", { className: "flex flex-col gap-2", children: [
/* @__PURE__ */ e(
E,
{
color: "primary",
variant: "solid",
size: "lg",
className: "w-full",
onPress: o,
children: p.action
}
),
s && /* @__PURE__ */ e(
E,
{
variant: "light",
size: "sm",
onPress: () => x(!d),
children: d ? "Hide Details" : "Show Details"
}
)
] }),
s && d && /* @__PURE__ */ e(
v.div,
{
initial: { opacity: 0, height: 0 },
animate: { opacity: 1, height: "auto" },
exit: { opacity: 0, height: 0 },
className: "mt-4 p-3 bg-default-100 dark:bg-default-800 rounded-lg",
children: /* @__PURE__ */ l("div", { className: "space-y-2", children: [
/* @__PURE__ */ l("div", { children: [
/* @__PURE__ */ e("span", { className: "text-xs font-medium text-default-600", children: "Error Message:" }),
/* @__PURE__ */ e("p", { className: "text-xs text-default-500 mt-1 font-mono", children: t.message })
] }),
t.stack && /* @__PURE__ */ l("div", { children: [
/* @__PURE__ */ e("span", { className: "text-xs font-medium text-default-600", children: "Stack Trace:" }),
/* @__PURE__ */ e("pre", { className: "text-xs text-default-500 mt-1 overflow-auto max-h-32 font-mono", children: t.stack })
] })
] })
}
)
] }) })
] })
}
);
}
class m extends c.Component {
constructor(r) {
super(r), f(this, "retryTimeoutId", null), f(this, "reportError", async (o, s) => {
const { errorReportingUrl: n } = this.props;
if (n)
try {
await fetch(n, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
error: {
message: o.message,
stack: o.stack,
name: o.name
},
errorInfo: s,
errorId: this.state.errorId,
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
userAgent: navigator.userAgent,
url: window.location.href
})
});
} catch (i) {
console.error("Failed to report error:", i);
}
}), f(this, "resetError", () => {
const { onRetry: o } = this.props;
this.retryTimeoutId && clearTimeout(this.retryTimeoutId), this.setState({
hasError: !1,
error: null,
errorInfo: null,
errorId: ""
}), o?.();
}), this.state = {
hasError: !1,
error: null,
errorInfo: null,
errorId: ""
};
}
static getDerivedStateFromError(r) {
return {
hasError: !0,
error: r,
errorId: Date.now().toString(36) + Math.random().toString(36).substr(2)
};
}
componentDidCatch(r, o) {
const {
onError: s,
logErrors: n = !0,
reportErrors: i = !1,
errorReportingUrl: u
} = this.props;
this.setState({
errorInfo: o
}), n && (console.group("🚨 Error Boundary Caught Error"), console.error("Error:", r), console.error("Error Info:", o), console.error("Component Stack:", o.componentStack), console.groupEnd()), s?.(r, o), i && u && this.reportError(r, o);
}
render() {
const { hasError: r, error: o, errorInfo: s } = this.state, {
children: n,
fallback: i = B,
showDetails: u = !1,
title: g,
subtitle: h,
className: d
} = this.props;
return r && o ? /* @__PURE__ */ e(
i,
{
error: o,
errorInfo: s,
resetError: this.resetError,
showDetails: u,
title: g,
subtitle: h,
className: d
}
) : n;
}
}
function R() {
const [t, r] = c.useState(null), o = c.useCallback((s) => {
r(s);
}, []);
return c.useEffect(() => {
if (t)
throw t;
}, [t]), o;
}
function F(t, r) {
const o = (s) => /* @__PURE__ */ e(m, { ...r, children: /* @__PURE__ */ e(t, { ...s }) });
return o.displayName = `withErrorBoundary(${t.displayName || t.name})`, o;
}
function V({
children: t,
...r
}) {
return /* @__PURE__ */ e(
m,
{
title: "Authentication Error",
subtitle: "There was a problem with the authentication process.",
showDetails: process.env.NODE_ENV === "development",
reportErrors: process.env.NODE_ENV === "production",
...r,
children: t
}
);
}
function W({
children: t,
...r
}) {
return /* @__PURE__ */ e(
m,
{
title: "Form Error",
subtitle: "There was a problem processing your form submission.",
showDetails: process.env.NODE_ENV === "development",
...r,
children: t
}
);
}
function U({
children: t,
...r
}) {
return /* @__PURE__ */ e(
m,
{
title: "Service Error",
subtitle: "There was a problem connecting to our services.",
showDetails: process.env.NODE_ENV === "development",
reportErrors: process.env.NODE_ENV === "production",
...r,
children: t
}
);
}
var q = m;
export {
U as ApiErrorBoundary,
V as AuthErrorBoundary,
m as ErrorBoundary,
W as FormErrorBoundary,
q as default,
R as useAsyncError,
F as withErrorBoundary
};
//# sourceMappingURL=error-boundary.js.map