@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
286 lines (285 loc) • 12.7 kB
JavaScript
'use client';
import { jsx as e, jsxs as t, Fragment as J } from "react/jsx-runtime";
import f from "react";
import { Dropdown as K, DropdownTrigger as Q, DropdownMenu as T, DropdownSection as l, DropdownItem as n, User as X, Chip as Y, Avatar as Z, Button as _ } from "@heroui/react";
import { useAuth as I } from "../../../hooks/use-auth.js";
import { useOrganization as ee } from "../../../hooks/use-organization.js";
import { useSession as re } from "../../../hooks/use-session.js";
import { useConfig as ne } from "../../../hooks/use-config.js";
import { useTheme as te } from "../../../hooks/use-theme.js";
function oe(o) {
switch (o?.toLowerCase()) {
case "owner":
return "danger";
case "admin":
return "warning";
case "member":
return "primary";
case "guest":
return "secondary";
default:
return "default";
}
}
function ie(o) {
const h = o?.device?.toLowerCase() || "", d = o?.os?.toLowerCase() || "";
return h.includes("mobile") || d.includes("ios") || d.includes("android") ? /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 18h.01M8 21h8a1 1 0 001-1V4a1 1 0 00-1-1H8a1 1 0 00-1 1v16a1 1 0 001 1z" }) }) : /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) });
}
const c = {
user: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }),
settings: /* @__PURE__ */ t("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
/* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" }),
/* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" })
] }),
signOut: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" }) }),
organization: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" }) }),
theme: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" }) }),
security: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" }) })
};
function ke({
children: o,
placement: h = "bottom-end",
className: d = "",
contentClassName: x = "",
showOrganization: C = !0,
showSessionManagement: L = !1,
showThemeToggle: M = !0,
customItems: u = [],
hideDefaultItems: i = [],
onSignOut: m,
onProfileClick: k,
onSettingsClick: v,
onOrganizationSwitch: p,
footerContent: w,
isDisabled: y = !1,
closeOnSelect: N = !0
}) {
const {
user: b,
signOut: z,
isOrganizationMember: se,
userName: R,
userEmail: P
} = I(), {
organizations: j,
activeOrganization: s,
switchOrganization: B,
isOwner: O,
isAdmin: D
} = ee(), {
sessions: U,
hasMultipleSessions: V,
revokeSession: S,
deviceInfo: ae
} = re(), { components: E } = ne(), { mode: $, toggleMode: W } = te(), A = E.UserProfile;
if (A)
return /* @__PURE__ */ e(A, { children: o, placement: h, className: d, contentClassName: x, showOrganization: C, showSessionManagement: L, showThemeToggle: M, customItems: u, hideDefaultItems: i, onSignOut: m, onProfileClick: k, onSettingsClick: v, onOrganizationSwitch: p, footerContent: w, isDisabled: y, closeOnSelect: N });
const H = f.useCallback(async () => {
try {
m ? m() : await z();
} catch (r) {
console.error("Sign out failed:", r);
}
}, [z, m]), F = f.useCallback(async (r) => {
try {
p ? p(r) : await B(r);
} catch (a) {
console.error("Organization switch failed:", a);
}
}, [B, p]), q = f.useCallback((r) => {
switch (r) {
case "profile":
k?.();
break;
case "settings":
v?.();
break;
case "sign-out":
H();
break;
case "toggle-theme":
W();
break;
default:
const a = u.find((G) => G.key === r);
a?.onClick ? a.onClick() : a?.href && (window.location.href = a.href);
break;
}
}, [k, v, H, W, u]);
if (!b) return null;
const g = f.useMemo(() => s ? O ? "owner" : D ? "admin" : "member" : null, [s, O, D]);
return /* @__PURE__ */ t(
K,
{
placement: h,
className: d,
isDisabled: y,
closeOnSelect: N,
children: [
/* @__PURE__ */ e(Q, { children: o }),
/* @__PURE__ */ t(
T,
{
"aria-label": "User menu",
onAction: q,
className: x,
children: [
/* @__PURE__ */ e(l, { showDivider: !0, children: /* @__PURE__ */ e(
n,
{
isReadOnly: !0,
className: "h-14 gap-2 opacity-100",
children: /* @__PURE__ */ e(
X,
{
name: R,
description: P,
avatarProps: {
size: "sm",
src: b.profileImageUrl
},
classNames: {
name: "text-default-600",
description: "text-default-500"
}
}
)
},
"user-info"
) }),
C && s && /* @__PURE__ */ t(l, { title: "Organization", showDivider: !0, children: [
/* @__PURE__ */ e(
n,
{
isReadOnly: !0,
className: "opacity-100",
startContent: c.organization,
endContent: g && /* @__PURE__ */ e(
Y,
{
size: "sm",
color: oe(g),
variant: "flat",
children: g
}
),
children: /* @__PURE__ */ t("div", { className: "flex flex-col", children: [
/* @__PURE__ */ e("span", { className: "text-small", children: s.name }),
/* @__PURE__ */ e("span", { className: "text-tiny text-default-400", children: s.slug })
] })
},
"current-org"
),
j.length > 1 && /* @__PURE__ */ e(J, { children: j.filter((r) => r.id !== s.id).map((r) => /* @__PURE__ */ t(
n,
{
onPress: () => F(r.id),
startContent: /* @__PURE__ */ e(
Z,
{
size: "sm",
src: r.logoUrl,
name: r.name
}
),
children: [
"Switch to ",
r.name
]
},
`switch-${r.id}`
)) })
] }),
L && V && /* @__PURE__ */ e(l, { title: "Sessions", showDivider: !0, children: U.slice(0, 3).map((r) => /* @__PURE__ */ e(
n,
{
startContent: ie(r.deviceInfo),
endContent: r.id !== U[0]?.id && /* @__PURE__ */ e(
_,
{
size: "sm",
variant: "light",
color: "danger",
onPress: () => S(r.id),
children: "End"
}
),
className: "text-small",
children: /* @__PURE__ */ t("div", { className: "flex flex-col", children: [
/* @__PURE__ */ e("span", { children: r.deviceInfo?.browser || "Unknown Browser" }),
/* @__PURE__ */ e("span", { className: "text-tiny text-default-400", children: r.deviceInfo?.os || "Unknown OS" })
] })
},
`session-${r.id}`
)) }),
/* @__PURE__ */ t(l, { showDivider: !0, children: [
!i.includes("profile") && /* @__PURE__ */ e(
n,
{
startContent: c.user,
children: "Profile"
},
"profile"
),
!i.includes("settings") && /* @__PURE__ */ e(
n,
{
startContent: c.settings,
children: "Settings"
},
"settings"
),
!i.includes("security") && /* @__PURE__ */ e(
n,
{
startContent: c.security,
children: "Security"
},
"security"
),
M && !i.includes("theme") && /* @__PURE__ */ e(
n,
{
startContent: c.theme,
children: $ === "dark" ? "Light Mode" : "Dark Mode"
},
"toggle-theme"
),
u.map((r) => /* @__PURE__ */ e(
n,
{
startContent: r.startContent || r.icon,
endContent: r.endContent,
color: r.color,
variant: r.variant,
isDisabled: r.isDisabled,
showDivider: r.showDivider,
children: /* @__PURE__ */ t("div", { className: "flex flex-col", children: [
/* @__PURE__ */ e("span", { children: r.label }),
r.description && /* @__PURE__ */ e("span", { className: "text-tiny text-default-400", children: r.description })
] })
},
r.key
))
] }),
/* @__PURE__ */ e(l, { children: !i.includes("signOut") && /* @__PURE__ */ e(
n,
{
color: "danger",
startContent: c.signOut,
children: "Sign Out"
},
"sign-out"
) }),
w && /* @__PURE__ */ e(l, { children: /* @__PURE__ */ e(n, { isReadOnly: !0, className: "opacity-100", children: w }, "footer") })
]
}
)
]
}
);
}
export {
ke as UserProfile
};
//# sourceMappingURL=user-profile.js.map