+ {typeof user?.avatarUrl === 'string' && user?.avatarUrl ? (
+
{user?.name?.[0]?.toUpperCase() || user?.email?.[0]?.toUpperCase()}
diff --git a/package-lock.json b/package-lock.json
index 76c104f7..8df804eb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2909,7 +2909,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2943,7 +2942,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -2977,7 +2975,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3043,7 +3040,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6876,7 +6872,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6893,7 +6888,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6910,7 +6904,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6927,7 +6920,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6944,7 +6936,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6961,7 +6952,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6978,7 +6968,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6995,7 +6984,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7012,7 +7000,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7029,7 +7016,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7046,7 +7032,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7063,7 +7048,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7080,7 +7064,6 @@
"cpu": [
"mips64el"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7097,7 +7080,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7114,7 +7096,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7131,7 +7112,6 @@
"cpu": [
"s390x"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7148,7 +7128,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7165,7 +7144,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7182,7 +7160,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7199,7 +7176,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7216,7 +7192,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7233,7 +7208,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
diff --git a/sdks/urbackend-react/dist/index.d.mts b/sdks/urbackend-react/dist/index.d.mts
index b13ac82b..0ef81d52 100644
--- a/sdks/urbackend-react/dist/index.d.mts
+++ b/sdks/urbackend-react/dist/index.d.mts
@@ -83,9 +83,74 @@ interface GuestRouteProps {
*/
declare const GuestRoute: React.FC
;
+type AuthProvider = 'google' | 'github';
+type ThemeMode = 'light' | 'dark';
+interface AuthColors {
+ background: string;
+ surface: string;
+ text: string;
+ textMuted: string;
+ border: string;
+ inputBackground: string;
+ primary: string;
+ primaryText: string;
+ footerBackground: string;
+ dividerText: string;
+ socialButtonBackground: string;
+}
+interface AuthBranding {
+ brandName?: string;
+ appName?: string;
+ title?: string;
+ subtitle?: string;
+ logo?: React.ReactNode | string;
+ primaryColor?: string;
+}
+interface AuthLabels {
+ loginTab: string;
+ signupTab: string;
+ loginTitle: string;
+ signupTitle: string;
+ forgotTitle: string;
+ resetTitle: string;
+ loginButton: string;
+ signupButton: string;
+ forgotButton: string;
+ resetButton: string;
+ emailLabel: string;
+ emailPlaceholder: string;
+ passwordLabel: string;
+ passwordPlaceholder: string;
+ nameLabel: string;
+ namePlaceholder: string;
+ otpLabel: string;
+ otpPlaceholder: string;
+ forgotPasswordLink: string;
+ socialDivider: string;
+ googleButton: string;
+ githubButton: string;
+ footerSigninPrompt: string;
+ footerSignupPrompt: string;
+ footerForgotPrompt: string;
+ noAuthMethods: string;
+ signInTitle?: string;
+ signUpTitle?: string;
+ signInTab?: string;
+ signUpTab?: string;
+ signInButton?: string;
+ signUpButton?: string;
+}
interface UrAuthProps {
- providers?: ('google' | 'github')[];
- theme?: 'light' | 'dark';
+ providers?: AuthProvider[] | {
+ google?: boolean;
+ github?: boolean;
+ emailPassword?: boolean;
+ };
+ enableEmailPassword?: boolean;
+ theme?: ThemeMode;
+ colors?: Partial;
+ branding?: AuthBranding;
+ labels?: Partial;
onSuccess?: () => void;
}
declare const UrAuth: React.FC;
diff --git a/sdks/urbackend-react/dist/index.d.ts b/sdks/urbackend-react/dist/index.d.ts
index b13ac82b..0ef81d52 100644
--- a/sdks/urbackend-react/dist/index.d.ts
+++ b/sdks/urbackend-react/dist/index.d.ts
@@ -83,9 +83,74 @@ interface GuestRouteProps {
*/
declare const GuestRoute: React.FC;
+type AuthProvider = 'google' | 'github';
+type ThemeMode = 'light' | 'dark';
+interface AuthColors {
+ background: string;
+ surface: string;
+ text: string;
+ textMuted: string;
+ border: string;
+ inputBackground: string;
+ primary: string;
+ primaryText: string;
+ footerBackground: string;
+ dividerText: string;
+ socialButtonBackground: string;
+}
+interface AuthBranding {
+ brandName?: string;
+ appName?: string;
+ title?: string;
+ subtitle?: string;
+ logo?: React.ReactNode | string;
+ primaryColor?: string;
+}
+interface AuthLabels {
+ loginTab: string;
+ signupTab: string;
+ loginTitle: string;
+ signupTitle: string;
+ forgotTitle: string;
+ resetTitle: string;
+ loginButton: string;
+ signupButton: string;
+ forgotButton: string;
+ resetButton: string;
+ emailLabel: string;
+ emailPlaceholder: string;
+ passwordLabel: string;
+ passwordPlaceholder: string;
+ nameLabel: string;
+ namePlaceholder: string;
+ otpLabel: string;
+ otpPlaceholder: string;
+ forgotPasswordLink: string;
+ socialDivider: string;
+ googleButton: string;
+ githubButton: string;
+ footerSigninPrompt: string;
+ footerSignupPrompt: string;
+ footerForgotPrompt: string;
+ noAuthMethods: string;
+ signInTitle?: string;
+ signUpTitle?: string;
+ signInTab?: string;
+ signUpTab?: string;
+ signInButton?: string;
+ signUpButton?: string;
+}
interface UrAuthProps {
- providers?: ('google' | 'github')[];
- theme?: 'light' | 'dark';
+ providers?: AuthProvider[] | {
+ google?: boolean;
+ github?: boolean;
+ emailPassword?: boolean;
+ };
+ enableEmailPassword?: boolean;
+ theme?: ThemeMode;
+ colors?: Partial;
+ branding?: AuthBranding;
+ labels?: Partial;
onSuccess?: () => void;
}
declare const UrAuth: React.FC;
diff --git a/sdks/urbackend-react/dist/index.js b/sdks/urbackend-react/dist/index.js
index 9444079b..fc9479aa 100644
--- a/sdks/urbackend-react/dist/index.js
+++ b/sdks/urbackend-react/dist/index.js
@@ -410,9 +410,69 @@ var Toast = ({ message, type, onClose, isDark = false }) => {
// src/components/UrAuth.tsx
var import_jsx_runtime4 = require("react/jsx-runtime");
+var defaultLabels = {
+ loginTab: "Login",
+ signupTab: "Sign Up",
+ loginTitle: "Welcome back",
+ signupTitle: "Create your account",
+ forgotTitle: "Reset Password",
+ resetTitle: "Enter Reset Code",
+ loginButton: "Log In",
+ signupButton: "Create Account",
+ forgotButton: "Send Reset Code",
+ resetButton: "Reset Password",
+ emailLabel: "Email address",
+ emailPlaceholder: "Enter your email address",
+ passwordLabel: "Password",
+ passwordPlaceholder: "Enter your password",
+ nameLabel: "Full Name",
+ namePlaceholder: "Enter your name",
+ otpLabel: "6-digit OTP Code",
+ otpPlaceholder: "Enter reset code",
+ forgotPasswordLink: "Forgot password?",
+ socialDivider: "OR",
+ googleButton: "Continue with Google",
+ githubButton: "Continue with GitHub",
+ footerSigninPrompt: "Don't have an account yet?",
+ footerSignupPrompt: "Already have an account?",
+ footerForgotPrompt: "Remember your password?",
+ noAuthMethods: "No authentication methods are enabled for this screen."
+};
+var defaultThemeColors = {
+ light: {
+ background: "#ffffff",
+ surface: "#ffffff",
+ text: "#0f172a",
+ textMuted: "#64748b",
+ border: "#e2e8f0",
+ inputBackground: "#ffffff",
+ primary: "#111111",
+ primaryText: "#ffffff",
+ footerBackground: "#f8fafc",
+ dividerText: "#94a3b8",
+ socialButtonBackground: "#ffffff"
+ },
+ dark: {
+ background: "#1a1a1a",
+ surface: "#1a1a1a",
+ text: "#ffffff",
+ textMuted: "#a1a1aa",
+ border: "#333333",
+ inputBackground: "#2a2a2a",
+ primary: "#ffffff",
+ primaryText: "#111111",
+ footerBackground: "#222222",
+ dividerText: "#94a3b8",
+ socialButtonBackground: "#2a2a2a"
+ }
+};
var UrAuth = ({
providers = ["google", "github"],
+ enableEmailPassword = true,
theme = "light",
+ colors,
+ branding,
+ labels,
onSuccess
}) => {
const { login, signUp, socialLogin, requestPasswordReset, resetPassword, isLoading, error, clearError } = useAuth();
@@ -422,11 +482,47 @@ var UrAuth = ({
const [otp, setOtp] = (0, import_react5.useState)("");
const [name, setName] = (0, import_react5.useState)("");
const [toast, setToast] = (0, import_react5.useState)(null);
+ const text = {
+ ...defaultLabels,
+ ...labels,
+ loginTab: labels?.signInTab || labels?.loginTab || defaultLabels.loginTab,
+ loginTitle: labels?.signInTitle || labels?.loginTitle || defaultLabels.loginTitle,
+ loginButton: labels?.signInButton || labels?.loginButton || defaultLabels.loginButton,
+ signupTab: labels?.signUpTab || labels?.signupTab || defaultLabels.signupTab,
+ signupTitle: labels?.signUpTitle || labels?.signupTitle || defaultLabels.signupTitle,
+ signupButton: labels?.signUpButton || labels?.signupButton || defaultLabels.signupButton
+ };
+ const themeColors = { ...defaultThemeColors[theme], ...colors };
+ const primaryColor = branding?.primaryColor || themeColors.primary;
+ let isGoogleEnabled = true;
+ let isGithubEnabled = true;
+ let isEmailPasswordEnabled = enableEmailPassword;
+ if (providers) {
+ if (Array.isArray(providers)) {
+ isGoogleEnabled = providers.includes("google");
+ isGithubEnabled = providers.includes("github");
+ } else if (typeof providers === "object") {
+ isGoogleEnabled = !!providers.google;
+ isGithubEnabled = !!providers.github;
+ isEmailPasswordEnabled = providers.emailPassword !== void 0 ? providers.emailPassword : false;
+ }
+ }
+ const hasPasswordAuth = isEmailPasswordEnabled;
+ const hasSocialAuth = isGoogleEnabled || isGithubEnabled;
+ const brandName = branding?.brandName || branding?.appName || branding?.title || "urBackend";
+ const headerTitle = branding?.title || brandName;
+ const headerSubtitle = branding?.subtitle || (mode === "signin" ? text.loginTitle : mode === "signup" ? text.signupTitle : mode === "forgot" ? text.forgotTitle : text.resetTitle);
+ const showSwitcher = hasPasswordAuth;
(0, import_react5.useEffect)(() => {
if (error) {
setToast({ message: error, type: "error" });
}
}, [error]);
+ (0, import_react5.useEffect)(() => {
+ if (!hasPasswordAuth && mode !== "signin") {
+ setMode("signin");
+ }
+ }, [hasPasswordAuth, mode]);
const handleSubmit = async (e) => {
e.preventDefault();
try {
@@ -453,28 +549,58 @@ var UrAuth = ({
} catch (err) {
}
};
- const isDark = theme === "dark";
- const bg = isDark ? "#1a1a1a" : "#ffffff";
- const text = isDark ? "#ffffff" : "#0f172a";
- const textMuted = isDark ? "#a1a1aa" : "#64748b";
- const border = isDark ? "#333" : "#e2e8f0";
- const inputBg = isDark ? "#2a2a2a" : "#ffffff";
const styles = {
wrapper: {
width: "100%",
maxWidth: "420px",
margin: "0 auto",
borderRadius: "0",
- background: bg,
- boxShadow: isDark ? "0 20px 40px rgba(0,0,0,0.5)" : "0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)",
- border: `1px solid ${border}`,
+ background: themeColors.background,
+ boxShadow: theme === "dark" ? "0 20px 40px rgba(0,0,0,0.5)" : "0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)",
+ border: `1px solid ${themeColors.border}`,
overflow: "hidden",
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
- color: text
+ color: themeColors.text
},
body: {
padding: "32px 32px 24px 32px"
},
+ header: {
+ textAlign: "center",
+ marginBottom: "28px"
+ },
+ brandRow: {
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ gap: "12px",
+ marginBottom: "10px"
+ },
+ brandLogo: {
+ width: "44px",
+ height: "44px",
+ borderRadius: "12px",
+ display: "inline-flex",
+ alignItems: "center",
+ justifyContent: "center",
+ background: theme === "dark" ? "#2a2a2a" : "#f1f5f9",
+ color: themeColors.text,
+ overflow: "hidden"
+ },
+ brandTitle: {
+ margin: 0,
+ fontSize: "26px",
+ lineHeight: 1.1,
+ fontWeight: 800,
+ color: themeColors.text
+ },
+ brandSubtitle: {
+ margin: "0 auto",
+ maxWidth: "320px",
+ fontSize: "14px",
+ lineHeight: 1.5,
+ color: themeColors.textMuted
+ },
switcherContainer: {
display: "flex",
alignItems: "center",
@@ -483,7 +609,7 @@ var UrAuth = ({
},
switcher: {
display: "inline-flex",
- background: isDark ? "#2a2a2a" : "#f1f5f9",
+ background: theme === "dark" ? "#2a2a2a" : "#f1f5f9",
padding: "4px",
borderRadius: "0"
},
@@ -496,9 +622,9 @@ var UrAuth = ({
fontSize: "13px",
fontWeight: 600,
cursor: "pointer",
- color: active ? text : textMuted,
- background: active ? isDark ? "#444" : "#ffffff" : "transparent",
- boxShadow: active ? isDark ? "0 2px 4px rgba(0,0,0,0.2)" : "0 2px 8px rgba(0,0,0,0.05)" : "none",
+ color: active ? themeColors.text : themeColors.textMuted,
+ background: active ? theme === "dark" ? "#444444" : "#ffffff" : "transparent",
+ boxShadow: active ? theme === "dark" ? "0 2px 4px rgba(0,0,0,0.2)" : "0 2px 8px rgba(0,0,0,0.05)" : "none",
border: "none",
transition: "all 0.2s ease"
}),
@@ -514,12 +640,12 @@ var UrAuth = ({
label: {
fontSize: "13px",
fontWeight: 600,
- color: isDark ? "#ddd" : "#334155"
+ color: theme === "dark" ? "#dddddd" : "#334155"
},
forgotLink: {
fontSize: "12px",
fontWeight: 600,
- color: text,
+ color: themeColors.text,
cursor: "pointer",
textDecoration: "none",
background: "none",
@@ -530,9 +656,9 @@ var UrAuth = ({
width: "100%",
padding: "12px 16px",
borderRadius: "0",
- border: `1px solid ${border}`,
- background: inputBg,
- color: text,
+ border: `1px solid ${themeColors.border}`,
+ background: themeColors.inputBackground,
+ color: themeColors.text,
fontSize: "14px",
boxSizing: "border-box",
outline: "none",
@@ -542,8 +668,8 @@ var UrAuth = ({
width: "100%",
padding: "14px",
borderRadius: "0",
- background: "linear-gradient(180deg, #2a2a2a 0%, #111111 100%)",
- color: "#ffffff",
+ background: `linear-gradient(180deg, ${primaryColor} 0%, ${theme === "dark" ? "#111111" : "#111111"} 100%)`,
+ color: themeColors.primaryText,
fontSize: "15px",
fontWeight: 600,
border: "none",
@@ -556,7 +682,7 @@ var UrAuth = ({
display: "flex",
alignItems: "center",
margin: "24px 0",
- color: "#94a3b8",
+ color: themeColors.dividerText,
fontSize: "11px",
fontWeight: 600,
letterSpacing: "1px"
@@ -564,7 +690,7 @@ var UrAuth = ({
dividerLine: {
flex: 1,
height: "1px",
- background: border
+ background: themeColors.border
},
dividerText: {
padding: "0 12px"
@@ -573,9 +699,9 @@ var UrAuth = ({
width: "100%",
padding: "12px",
borderRadius: "0",
- border: `1px solid ${border}`,
- background: isDark ? "#2a2a2a" : "#ffffff",
- color: text,
+ border: `1px solid ${themeColors.border}`,
+ background: themeColors.socialButtonBackground,
+ color: themeColors.text,
fontSize: "14px",
fontWeight: 600,
display: "flex",
@@ -584,19 +710,19 @@ var UrAuth = ({
gap: "10px",
marginBottom: "12px",
cursor: "pointer",
- boxShadow: isDark ? "none" : "0 1px 2px rgba(0,0,0,0.02)",
+ boxShadow: theme === "dark" ? "none" : "0 1px 2px rgba(0,0,0,0.02)",
transition: "background 0.2s ease"
},
footer: {
- background: isDark ? "#222" : "#f8fafc",
+ background: themeColors.footerBackground,
padding: "24px",
textAlign: "center",
- borderTop: `1px solid ${border}`,
+ borderTop: `1px solid ${themeColors.border}`,
fontSize: "13px",
- color: textMuted
+ color: themeColors.textMuted
},
footerLink: {
- color: text,
+ color: themeColors.text,
fontWeight: 600,
textDecoration: "underline",
cursor: "pointer",
@@ -612,14 +738,37 @@ var UrAuth = ({
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })
] });
- const GithubIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: isDark ? "#fff" : "#000", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" }) });
+ const GithubIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: theme === "dark" ? "#fff" : "#000", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" }) });
+ const renderSocialButtons = () => {
+ if (!hasSocialAuth) {
+ return null;
+ }
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
+ hasPasswordAuth && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.divider, children: [
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.dividerLine }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles.dividerText, children: text.socialDivider }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.dividerLine })
+ ] }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
+ isGoogleEnabled && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { style: styles.socialBtn, onClick: () => socialLogin("google"), type: "button", children: [
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GoogleIcon, {}),
+ text.googleButton
+ ] }),
+ isGithubEnabled && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { style: styles.socialBtn, onClick: () => socialLogin("github"), type: "button", children: [
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GithubIcon, {}),
+ text.githubButton
+ ] })
+ ] })
+ ] });
+ };
+ const footerPrompt = mode === "signin" ? text.footerSigninPrompt : mode === "signup" ? text.footerSignupPrompt : text.footerForgotPrompt;
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.wrapper, children: [
toast && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
Toast,
{
message: toast.message,
type: toast.type,
- isDark,
+ isDark: theme === "dark",
onClose: () => {
setToast(null);
if (toast.type === "error") clearError();
@@ -627,7 +776,12 @@ var UrAuth = ({
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.body, children: [
- (mode === "signin" || mode === "signup") && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.switcherContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.switcher, children: [
+ (branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle || headerTitle || headerSubtitle) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.header, children: [
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.brandRow, children: branding?.logo ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.brandLogo, children: typeof branding.logo === "string" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("img", { src: branding.logo, alt: brandName, style: { width: "100%", height: "100%", objectFit: "contain" } }) : branding.logo }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.brandLogo, "aria-hidden": "true", children: brandName.slice(0, 1).toUpperCase() }) }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { style: styles.brandTitle, children: headerTitle }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.brandSubtitle, children: headerSubtitle })
+ ] }),
+ showSwitcher && (mode === "signin" || mode === "signup") && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.switcherContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.switcher, children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"button",
{
@@ -643,7 +797,7 @@ var UrAuth = ({
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "10 17 15 12 10 7" }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "15", y1: "12", x2: "3", y2: "12" })
] }),
- "Login"
+ text.loginTab
]
}
),
@@ -663,24 +817,25 @@ var UrAuth = ({
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "19", y1: "8", x2: "19", y2: "14" }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "22", y1: "11", x2: "16", y2: "11" })
] }),
- "Sign Up"
+ text.signupTab
]
}
)
] }) }),
(mode === "forgot" || mode === "reset") && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { style: { margin: "0 0 8px", fontSize: "20px", fontWeight: 700, color: text }, children: mode === "forgot" ? "Reset Password" : "Enter Reset Code" }),
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: { margin: 0, fontSize: "14px", color: textMuted }, children: mode === "forgot" ? "Enter your email and we'll send a code" : `Enter the code sent to ${email}` })
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { style: { margin: "0 0 8px", fontSize: "20px", fontWeight: 700, color: themeColors.text }, children: mode === "forgot" ? text.forgotTitle : text.resetTitle }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: { margin: 0, fontSize: "14px", color: themeColors.textMuted }, children: mode === "forgot" ? text.loginTitle : `Enter the code sent to ${email}` })
] }),
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("form", { onSubmit: handleSubmit, children: [
+ !hasPasswordAuth && !hasSocialAuth && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { textAlign: "center", color: themeColors.textMuted, fontSize: "14px", lineHeight: 1.5 }, children: text.noAuthMethods }),
+ hasPasswordAuth && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("form", { onSubmit: handleSubmit, children: [
mode === "signup" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.field, children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.labelRow, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: "Full Name" }) }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.labelRow, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: text.nameLabel }) }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"input",
{
style: styles.input,
type: "text",
- placeholder: "Enter your name",
+ placeholder: text.namePlaceholder,
value: name,
onChange: (e) => setName(e.target.value),
required: true
@@ -688,13 +843,13 @@ var UrAuth = ({
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.field, children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.labelRow, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: "Email address" }) }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.labelRow, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: text.emailLabel }) }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"input",
{
style: styles.input,
type: "email",
- placeholder: "Enter your email address",
+ placeholder: text.emailPlaceholder,
value: email,
onChange: (e) => setEmail(e.target.value),
required: true,
@@ -702,40 +857,40 @@ var UrAuth = ({
}
)
] }),
- mode === "reset" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.field, children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.labelRow, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: "6-digit OTP Code" }) }),
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
- "input",
- {
- style: styles.input,
- type: "text",
- placeholder: "Enter reset code",
- value: otp,
- onChange: (e) => setOtp(e.target.value),
- required: true
- }
- )
- ] }),
(mode === "signin" || mode === "signup" || mode === "reset") && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.field, children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.labelRow, children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: mode === "reset" ? "New Password" : "Password" }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: mode === "reset" ? text.passwordLabel : text.passwordLabel }),
mode === "signin" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", style: styles.forgotLink, onClick: () => {
setMode("forgot");
clearError();
- }, children: "Forgot password?" })
+ }, children: text.forgotPasswordLink })
] }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"input",
{
style: styles.input,
type: "password",
- placeholder: mode === "reset" ? "Enter new password" : "Enter your password",
+ placeholder: text.passwordPlaceholder,
value: password,
onChange: (e) => setPassword(e.target.value),
required: true
}
)
] }),
+ mode === "reset" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.field, children: [
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.labelRow, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { style: styles.label, children: text.otpLabel }) }),
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
+ "input",
+ {
+ style: styles.input,
+ type: "text",
+ placeholder: text.otpPlaceholder,
+ value: otp,
+ onChange: (e) => setOtp(e.target.value),
+ required: true
+ }
+ )
+ ] }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"button",
{
@@ -745,30 +900,14 @@ var UrAuth = ({
onMouseDown: (e) => e.currentTarget.style.transform = "scale(0.98)",
onMouseUp: (e) => e.currentTarget.style.transform = "scale(1)",
onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)",
- children: isLoading ? "Processing..." : mode === "signin" ? "Log In" : mode === "signup" ? "Create Account" : mode === "forgot" ? "Send Reset Code" : "Reset Password"
+ children: isLoading ? "Processing..." : mode === "signin" ? text.loginButton : mode === "signup" ? text.signupButton : mode === "forgot" ? text.forgotButton : text.resetButton
}
)
] }),
- (mode === "signin" || mode === "signup") && providers && providers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.divider, children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.dividerLine }),
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles.dividerText, children: "OR" }),
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.dividerLine })
- ] }),
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
- providers.includes("google") && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { style: styles.socialBtn, onClick: () => socialLogin("google"), type: "button", children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GoogleIcon, {}),
- "Continue with Google"
- ] }),
- providers.includes("github") && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { style: styles.socialBtn, onClick: () => socialLogin("github"), type: "button", children: [
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GithubIcon, {}),
- "Continue with GitHub"
- ] })
- ] })
- ] })
+ (mode === "signin" || mode === "signup") && renderSocialButtons()
] }),
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.footer, children: [
- mode === "signin" ? "Don't have an account yet?" : mode === "signup" ? "Already have an account?" : "Remember your password?",
+ hasPasswordAuth && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.footer, children: [
+ footerPrompt,
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"button",
{
@@ -778,7 +917,7 @@ var UrAuth = ({
setMode(mode === "signin" ? "signup" : "signin");
clearError();
},
- children: mode === "signin" ? "Sign up" : "Log in"
+ children: mode === "signin" ? text.signupTab : text.loginTab
}
)
] })
diff --git a/sdks/urbackend-react/dist/index.js.map b/sdks/urbackend-react/dist/index.js.map
index 258422d7..0e3b78de 100644
--- a/sdks/urbackend-react/dist/index.js.map
+++ b/sdks/urbackend-react/dist/index.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../src/index.ts","../src/context.tsx","../src/hooks.ts","../src/components.tsx","../src/components/UrAuth.tsx","../src/components/Toast.tsx","../src/components/UrUserButton.tsx"],"sourcesContent":["export { UrProvider, useUrContext } from './context';\nexport type { UrProviderProps } from './context';\n\nexport { useAuth, useUser, useDb, useStorage } from './hooks';\nexport { ProtectedRoute, GuestRoute } from './components';\nexport type { ProtectedRouteProps, GuestRouteProps } from './components';\n\nexport { UrAuth } from './components/UrAuth';\nexport type { UrAuthProps } from './components/UrAuth';\n\nexport * from './components/UrUserButton';\n\nexport * from '@urbackend/sdk'; // re-export types so users don't need to import from sdk directly","import React, { createContext, useContext, useEffect, useState, useMemo } from 'react';\r\nimport { UrBackendClient, AuthModule, DatabaseModule, StorageModule } from '@urbackend/sdk';\r\nimport type { AuthUser } from '@urbackend/sdk';\r\n\r\ninterface UrContextValue {\r\n client: UrBackendClient | null;\r\n auth: AuthModule | null;\r\n db: DatabaseModule | null;\r\n storage: StorageModule | null;\r\n user: AuthUser | null;\r\n setUser: React.Dispatch>;\r\n isInitializing: boolean;\r\n isLoading: boolean;\r\n setIsLoading: React.Dispatch>;\r\n error: string | null;\r\n setError: React.Dispatch>;\r\n}\r\n\r\nconst UrContext = createContext(undefined);\r\n\r\nexport interface UrProviderProps {\r\n apiKey: string;\r\n baseUrl?: string;\r\n children: React.ReactNode;\r\n}\r\n\r\nexport const UrProvider: React.FC = ({ apiKey, baseUrl, children }) => {\r\n const [user, setUser] = useState(null);\r\n const [isInitializing, setIsInitializing] = useState(true);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n const { client, auth, db, storage } = useMemo(() => {\r\n const _client = new UrBackendClient({ apiKey, baseUrl });\r\n return {\r\n client: _client,\r\n auth: new AuthModule(_client),\r\n db: new DatabaseModule(_client),\r\n storage: new StorageModule(_client),\r\n };\r\n }, [apiKey, baseUrl]);\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n\r\n const initAuth = async () => {\r\n try {\r\n // Hydrate from localStorage first as a fallback for environments without cookies\r\n if (typeof window !== 'undefined') {\r\n const savedToken = localStorage.getItem('ur_auth_token');\r\n if (savedToken) auth.setToken(savedToken);\r\n }\r\n\r\n // Check for social auth callback params\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hashParams = new URLSearchParams(window.location.hash.substring(1));\r\n const token = hashParams.get('token');\r\n const rtCode = urlParams.get('rtCode');\r\n const error = urlParams.get('error');\r\n\r\n if (error) {\r\n console.error('Social Auth Error:', error);\r\n if (mounted) setError(error);\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else if (token) {\r\n // Social auth succeeded, establish session immediately\r\n auth.setToken(token);\r\n if (typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n \r\n if (rtCode) {\r\n // Exchange for long-lived refresh token\r\n try {\r\n const exRes = await auth.socialExchange({ token, rtCode });\r\n const exToken = (exRes as any).accessToken || (exRes as any).token;\r\n if (exToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', exToken);\r\n } catch (err: any) {\r\n console.error('Failed to exchange refresh token', err);\r\n if (mounted) setError(err.message || 'Failed to complete social login');\r\n throw err;\r\n }\r\n }\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else {\r\n // Attempt to silently refresh session using the HTTP-only cookie\r\n try {\r\n const res = await auth.refreshToken();\r\n const newToken = res.accessToken || (res as any).token;\r\n if (newToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', newToken);\r\n } catch (e) {\r\n // If refresh fails, me() will catch it\r\n }\r\n }\r\n \r\n const currentUser = await auth.me();\r\n if (mounted) {\r\n setUser(currentUser);\r\n }\r\n } catch (error: any) {\r\n if (mounted) {\r\n setUser(null);\r\n // Don't set global error for initial me() check failure (usually just means not logged in)\r\n }\r\n } finally {\r\n if (mounted) {\r\n setIsInitializing(false);\r\n }\r\n }\r\n };\r\n\r\n initAuth();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [auth]);\r\n\r\n const value: UrContextValue = {\r\n client,\r\n auth,\r\n db,\r\n storage,\r\n user,\r\n setUser,\r\n isInitializing,\r\n isLoading,\r\n setIsLoading,\r\n error,\r\n setError,\r\n };\r\n\r\n return {children} ;\r\n};\r\n\r\nexport const useUrContext = () => {\r\n const context = useContext(UrContext);\r\n if (!context) {\r\n throw new Error('useUrContext must be used within an UrProvider');\r\n }\r\n return context;\r\n};\r\n","import { useCallback } from 'react';\r\nimport { useUrContext } from './context';\r\nimport type { \r\n LoginPayload, \r\n SignUpPayload, \r\n ChangePasswordPayload,\r\n VerifyEmailPayload,\r\n RequestPasswordResetPayload,\r\n ResetPasswordPayload\r\n} from '@urbackend/sdk';\r\n\r\nexport const useAuth = () => {\r\n const { auth, user, setUser, isInitializing, isLoading, setIsLoading, error, setError } = useUrContext();\r\n\r\n if (!auth) {\r\n throw new Error('Auth module not initialized. Make sure you are inside UrProvider.');\r\n }\r\n\r\n const login = useCallback(async (payload: LoginPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const res = await auth.login(payload);\r\n const token = res.accessToken || (res as any).token;\r\n if (token && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n const currentUser = await auth.me();\r\n setUser(currentUser);\r\n } catch (err: any) {\r\n setError(err.message || 'Login failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const signUp = useCallback(async (payload: SignUpPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const newUser = await auth.signUp(payload);\r\n return newUser;\r\n } catch (err: any) {\r\n setError(err.message || 'Sign up failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setIsLoading, setError]);\r\n\r\n const logout = useCallback(async () => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n await auth.logout();\r\n if (typeof window !== 'undefined') localStorage.removeItem('ur_auth_token');\r\n setUser(null);\r\n } catch (err: any) {\r\n setError(err.message || 'Logout failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const socialLogin = useCallback((provider: 'google' | 'github') => {\r\n setError(null);\r\n const url = auth.socialStart(provider);\r\n window.location.href = url;\r\n }, [auth, setError]);\r\n \r\n const verifyEmail = useCallback(async (payload: VerifyEmailPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.verifyEmail(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Email verification failed');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const changePassword = useCallback(async (payload: ChangePasswordPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.changePassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to change password');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const requestPasswordReset = useCallback(async (payload: RequestPasswordResetPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.requestPasswordReset(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to request password reset');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const resetPassword = useCallback(async (payload: ResetPasswordPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.resetPassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to reset password');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const clearError = useCallback(() => setError(null), [setError]);\r\n\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n login,\r\n signUp,\r\n logout,\r\n socialLogin,\r\n verifyEmail,\r\n changePassword,\r\n requestPasswordReset,\r\n resetPassword,\r\n clearError,\r\n authApi: auth // Escape hatch to underlying SDK\r\n };\r\n};\r\n\r\nexport const useUser = () => {\r\n const { user, isInitializing, isLoading, error } = useUrContext();\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n };\r\n};\r\n\r\nexport const useDb = () => {\r\n const { db } = useUrContext();\r\n if (!db) {\r\n throw new Error('Database module not initialized.');\r\n }\r\n return db;\r\n};\r\n\r\nexport const useStorage = () => {\r\n const { storage } = useUrContext();\r\n if (!storage) {\r\n throw new Error('Storage module not initialized.');\r\n }\r\n return storage;\r\n};\r\n","import React, { useEffect } from 'react';\r\nimport { useUser } from './hooks';\r\n\r\nexport interface ProtectedRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to be authenticated.\r\n * If the user is not authenticated after initialization, they will be redirected,\r\n * or the fallback will be rendered (or nothing if fallback is not provided and no window redirect occurs).\r\n */\r\nexport const ProtectedRoute: React.FC = ({ \r\n children, \r\n redirectTo = '/login', \r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && !isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (!isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n\r\nexport interface GuestRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to NOT be authenticated (e.g. for Login pages).\r\n * If the user IS authenticated, they will be redirected to the specified route.\r\n */\r\nexport const GuestRoute: React.FC = ({\r\n children,\r\n redirectTo = '/dashboard',\r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n","import React, { useState, useEffect } from 'react';\r\nimport { useAuth } from '../hooks';\r\nimport { Toast } from './Toast';\r\n\r\nexport interface UrAuthProps {\r\n providers?: ('google' | 'github')[];\r\n theme?: 'light' | 'dark'; // Dark mode not perfectly matched to image, but kept for API compat\r\n onSuccess?: () => void;\r\n}\r\n\r\nexport const UrAuth: React.FC = ({ \r\n providers = ['google', 'github'], \r\n theme = 'light',\r\n onSuccess\r\n}) => {\r\n const { login, signUp, socialLogin, requestPasswordReset, resetPassword, isLoading, error, clearError } = useAuth();\r\n const [mode, setMode] = useState<'signin' | 'signup' | 'forgot' | 'reset'>('signin');\r\n const [email, setEmail] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [otp, setOtp] = useState('');\r\n const [name, setName] = useState('');\r\n const [toast, setToast] = useState<{message: string, type: 'success' | 'error'} | null>(null);\r\n\r\n useEffect(() => {\r\n if (error) {\r\n setToast({ message: error, type: 'error' });\r\n }\r\n }, [error]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n if (mode === 'signin') {\r\n await login({ email, password });\r\n setToast({ message: 'Welcome back!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'signup') {\r\n await signUp({ email, password, name });\r\n // Auto-login after signup for convenience\r\n await login({ email, password });\r\n setToast({ message: 'Account created successfully!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'forgot') {\r\n await requestPasswordReset({ email });\r\n setToast({ message: 'Reset code sent to your email', type: 'success' });\r\n setMode('reset');\r\n } else if (mode === 'reset') {\r\n await resetPassword({ email, otp, newPassword: password });\r\n setToast({ message: 'Password reset successfully', type: 'success' });\r\n setMode('signin');\r\n setPassword('');\r\n setOtp('');\r\n }\r\n } catch (err: any) {\r\n // Error is now handled and stored globally by useAuth hook, which triggers the useEffect toast\r\n }\r\n };\r\n\r\n const isDark = theme === 'dark';\r\n const bg = isDark ? '#1a1a1a' : '#ffffff';\r\n const text = isDark ? '#ffffff' : '#0f172a';\r\n const textMuted = isDark ? '#a1a1aa' : '#64748b';\r\n const border = isDark ? '#333' : '#e2e8f0';\r\n const inputBg = isDark ? '#2a2a2a' : '#ffffff';\r\n \r\n const styles = {\r\n wrapper: {\r\n width: '100%',\r\n maxWidth: '420px',\r\n margin: '0 auto',\r\n borderRadius: '0',\r\n background: bg,\r\n boxShadow: isDark ? '0 20px 40px rgba(0,0,0,0.5)' : '0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)',\r\n border: `1px solid ${border}`,\r\n overflow: 'hidden',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n color: text,\r\n },\r\n body: {\r\n padding: '32px 32px 24px 32px',\r\n },\r\n switcherContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n marginBottom: '32px'\r\n },\r\n switcher: {\r\n display: 'inline-flex',\r\n background: isDark ? '#2a2a2a' : '#f1f5f9',\r\n padding: '4px',\r\n borderRadius: '0',\r\n },\r\n switchBtn: (active: boolean) => ({\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n padding: '8px 20px',\r\n borderRadius: '0',\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n color: active ? text : textMuted,\r\n background: active ? (isDark ? '#444' : '#ffffff') : 'transparent',\r\n boxShadow: active ? (isDark ? '0 2px 4px rgba(0,0,0,0.2)' : '0 2px 8px rgba(0,0,0,0.05)') : 'none',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n }),\r\n field: {\r\n marginBottom: '20px',\r\n },\r\n labelRow: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n marginBottom: '8px',\r\n },\r\n label: {\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n color: isDark ? '#ddd' : '#334155',\r\n },\r\n forgotLink: {\r\n fontSize: '12px',\r\n fontWeight: 600,\r\n color: text,\r\n cursor: 'pointer',\r\n textDecoration: 'none',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n borderRadius: '0',\r\n border: `1px solid ${border}`,\r\n background: inputBg,\r\n color: text,\r\n fontSize: '14px',\r\n boxSizing: 'border-box' as const,\r\n outline: 'none',\r\n transition: 'border-color 0.2s ease',\r\n },\r\n primaryBtn: {\r\n width: '100%',\r\n padding: '14px',\r\n borderRadius: '0',\r\n background: 'linear-gradient(180deg, #2a2a2a 0%, #111111 100%)',\r\n color: '#ffffff',\r\n fontSize: '15px',\r\n fontWeight: 600,\r\n border: 'none',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\r\n cursor: 'pointer',\r\n marginTop: '8px',\r\n transition: 'transform 0.1s ease',\r\n },\r\n divider: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n margin: '24px 0',\r\n color: '#94a3b8',\r\n fontSize: '11px',\r\n fontWeight: 600,\r\n letterSpacing: '1px',\r\n },\r\n dividerLine: {\r\n flex: 1,\r\n height: '1px',\r\n background: border,\r\n },\r\n dividerText: {\r\n padding: '0 12px',\r\n },\r\n socialBtn: {\r\n width: '100%',\r\n padding: '12px',\r\n borderRadius: '0',\r\n border: `1px solid ${border}`,\r\n background: isDark ? '#2a2a2a' : '#ffffff',\r\n color: text,\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '10px',\r\n marginBottom: '12px',\r\n cursor: 'pointer',\r\n boxShadow: isDark ? 'none' : '0 1px 2px rgba(0,0,0,0.02)',\r\n transition: 'background 0.2s ease',\r\n },\r\n footer: {\r\n background: isDark ? '#222' : '#f8fafc',\r\n padding: '24px',\r\n textAlign: 'center' as const,\r\n borderTop: `1px solid ${border}`,\r\n fontSize: '13px',\r\n color: textMuted,\r\n },\r\n footerLink: {\r\n color: text,\r\n fontWeight: 600,\r\n textDecoration: 'underline',\r\n cursor: 'pointer',\r\n marginLeft: '4px',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n }\r\n };\r\n\r\n const GoogleIcon = () => (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n\r\n const GithubIcon = () => (\r\n \r\n \r\n \r\n );\r\n\r\n return (\r\n \r\n {toast && (\r\n
{\r\n setToast(null);\r\n if (toast.type === 'error') clearError();\r\n }} \r\n />\r\n )}\r\n \r\n \r\n {(mode === 'signin' || mode === 'signup') && (\r\n
\r\n
\r\n
{ setMode('signin'); clearError(); }}\r\n >\r\n \r\n Login\r\n \r\n
{ setMode('signup'); clearError(); }}\r\n >\r\n \r\n Sign Up\r\n \r\n
\r\n
\r\n )}\r\n\r\n {(mode === 'forgot' || mode === 'reset') && (\r\n
\r\n
\r\n {mode === 'forgot' ? 'Reset Password' : 'Enter Reset Code'}\r\n \r\n
\r\n {mode === 'forgot' ? \"Enter your email and we'll send a code\" : `Enter the code sent to ${email}`}\r\n
\r\n
\r\n )}\r\n\r\n
\r\n\r\n {(mode === 'signin' || mode === 'signup') && providers && providers.length > 0 && (\r\n <>\r\n
\r\n\r\n
\r\n {providers.includes('google') && (\r\n socialLogin('google')} type=\"button\">\r\n \r\n Continue with Google\r\n \r\n )}\r\n {providers.includes('github') && (\r\n socialLogin('github')} type=\"button\">\r\n \r\n Continue with GitHub\r\n \r\n )}\r\n
\r\n >\r\n )}\r\n
\r\n\r\n \r\n {mode === 'signin' ? \"Don't have an account yet?\" \r\n : mode === 'signup' ? \"Already have an account?\"\r\n : \"Remember your password?\"}\r\n {\r\n setMode(mode === 'signin' ? 'signup' : 'signin');\r\n clearError();\r\n }}\r\n >\r\n {mode === 'signin' ? 'Sign up' : 'Log in'}\r\n \r\n
\r\n \r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\n\r\ninterface ToastProps {\r\n message: string;\r\n type: 'success' | 'error';\r\n onClose: () => void;\r\n isDark?: boolean;\r\n}\r\n\r\nexport const Toast: React.FC = ({ message, type, onClose, isDark = false }) => {\r\n const [isVisible, setIsVisible] = useState(false);\r\n const [isLeaving, setIsLeaving] = useState(false);\r\n\r\n useEffect(() => {\r\n // Trigger enter animation on mount\r\n requestAnimationFrame(() => {\r\n setIsVisible(true);\r\n });\r\n\r\n let innerTimer: ReturnType;\r\n const timer = setTimeout(() => {\r\n setIsLeaving(true);\r\n innerTimer = setTimeout(onClose, 300); // Wait for exit animation\r\n }, 4000);\r\n\r\n return () => {\r\n clearTimeout(timer);\r\n if (innerTimer) clearTimeout(innerTimer);\r\n };\r\n }, [onClose]);\r\n\r\n const bgColor = isDark ? 'rgba(30, 30, 30, 0.9)' : 'rgba(255, 255, 255, 0.9)';\r\n const borderColor = type === 'success' ? 'rgba(34, 197, 94, 0.5)' : 'rgba(239, 68, 68, 0.5)';\r\n const iconColor = type === 'success' ? '#22c55e' : '#ef4444';\r\n const textColor = isDark ? '#fff' : '#000';\r\n\r\n return (\r\n <>\r\n \r\n \r\n {type === 'success' ? (\r\n
\r\n \r\n \r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n \r\n )}\r\n {message}\r\n
\r\n >\r\n );\r\n};\r\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useUser, useAuth } from '../hooks';\n\nexport interface UrUserButtonProps {\n /**\n * Shape of the profile avatar. Defaults to 'square' as requested.\n */\n shape?: 'square' | 'circle';\n /**\n * Position of the button on the screen. Defaults to 'top-right'.\n * Use 'inline' if you want to place it within a normal flex/grid layout instead of absolute positioning.\n */\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'inline';\n /**\n * Called when \"Profile\" is clicked.\n */\n onProfileClick?: () => void;\n /**\n * Called when \"Settings\" is clicked.\n */\n onSettingsClick?: () => void;\n /**\n * Z-index for the fixed container. Defaults to 999.\n */\n zIndex?: number;\n}\n\nexport const UrUserButton: React.FC = ({\n shape = 'square',\n position = 'top-right',\n onProfileClick,\n onSettingsClick,\n zIndex = 999,\n}) => {\n const { user } = useUser();\n const { logout } = useAuth();\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n if (!user) return null; // Only render if logged in\n\n const borderRadius = shape === 'circle' ? '50%' : '0px';\n const isFixed = position !== 'inline';\n\n const positionStyles: React.CSSProperties = isFixed\n ? {\n position: 'fixed',\n zIndex,\n top: position.includes('top') ? '24px' : 'auto',\n bottom: position.includes('bottom') ? '24px' : 'auto',\n right: position.includes('right') ? '24px' : 'auto',\n left: position.includes('left') ? '24px' : 'auto',\n }\n : { position: 'relative' };\n\n const dropdownStyles: React.CSSProperties = {\n position: 'absolute',\n top: position.includes('top') || position === 'inline' ? 'calc(100% + 8px)' : 'auto',\n bottom: position.includes('bottom') ? 'calc(100% + 8px)' : 'auto',\n right: position.includes('right') || position === 'inline' ? '0' : 'auto',\n left: position.includes('left') ? '0' : 'auto',\n background: '#ffffff',\n border: '1px solid #e2e8f0',\n borderRadius: '0px',\n boxShadow: '0 10px 25px rgba(0,0,0,0.1)',\n width: '220px',\n display: isOpen ? 'block' : 'none',\n overflow: 'hidden',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n };\n\n const getInitials = () => {\n return user.name?.[0]?.toUpperCase() || user.email?.[0]?.toUpperCase() || 'U';\n };\n\n return (\n \n
setIsOpen(!isOpen)}\n style={{\n width: '40px',\n height: '40px',\n padding: 0,\n border: '1px solid #e2e8f0',\n background: '#f8fafc',\n borderRadius,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n boxShadow: '0 2px 5px rgba(0,0,0,0.05)',\n transition: 'transform 0.1s ease',\n }}\n >\n {user.avatarUrl ? (\n \n ) : (\n \n {getInitials()}\n \n )}\n \n\n
\n {/* User Info Header */}\n
\n
\n {user.name || 'User'}\n
\n
\n {user.email}\n
\n
\n\n {/* Action List */}\n
\n {onProfileClick && (\n
{\n setIsOpen(false);\n onProfileClick();\n }}\n style={{\n width: '100%',\n textAlign: 'left',\n padding: '10px 12px',\n background: 'transparent',\n border: 'none',\n fontSize: '14px',\n color: '#334155',\n cursor: 'pointer',\n borderRadius: '0px',\n display: 'block',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\n >\n Profile\n \n )}\n\n {onSettingsClick && (\n
{\n setIsOpen(false);\n onSettingsClick();\n }}\n style={{\n width: '100%',\n textAlign: 'left',\n padding: '10px 12px',\n background: 'transparent',\n border: 'none',\n fontSize: '14px',\n color: '#334155',\n cursor: 'pointer',\n borderRadius: '0px',\n display: 'block',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\n >\n Settings\n \n )}\n\n
\n\n
{\n setIsOpen(false);\n logout();\n }}\n style={{\n width: '100%',\n textAlign: 'left',\n padding: '10px 12px',\n background: 'transparent',\n border: 'none',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n cursor: 'pointer',\n borderRadius: '0px',\n display: 'block',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.background = '#fef2f2')}\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\n >\n Logout\n \n
\n
\n
\n );\n};\n"],"mappings":"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","names":["error","import_react","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime"]}
\ No newline at end of file
+{"version":3,"sources":["../src/index.ts","../src/context.tsx","../src/hooks.ts","../src/components.tsx","../src/components/UrAuth.tsx","../src/components/Toast.tsx","../src/components/UrUserButton.tsx"],"sourcesContent":["export { UrProvider, useUrContext } from './context';\r\nexport type { UrProviderProps } from './context';\r\n\r\nexport { useAuth, useUser, useDb, useStorage } from './hooks';\r\nexport { ProtectedRoute, GuestRoute } from './components';\r\nexport type { ProtectedRouteProps, GuestRouteProps } from './components';\r\n\r\nexport { UrAuth } from './components/UrAuth';\r\nexport type { UrAuthProps } from './components/UrAuth';\r\n\r\nexport * from './components/UrUserButton';\r\n\r\nexport * from '@urbackend/sdk'; // re-export types so users don't need to import from sdk directly","import React, { createContext, useContext, useEffect, useState, useMemo } from 'react';\r\nimport { UrBackendClient, AuthModule, DatabaseModule, StorageModule } from '@urbackend/sdk';\r\nimport type { AuthUser } from '@urbackend/sdk';\r\n\r\ninterface UrContextValue {\r\n client: UrBackendClient | null;\r\n auth: AuthModule | null;\r\n db: DatabaseModule | null;\r\n storage: StorageModule | null;\r\n user: AuthUser | null;\r\n setUser: React.Dispatch>;\r\n isInitializing: boolean;\r\n isLoading: boolean;\r\n setIsLoading: React.Dispatch>;\r\n error: string | null;\r\n setError: React.Dispatch>;\r\n}\r\n\r\nconst UrContext = createContext(undefined);\r\n\r\nexport interface UrProviderProps {\r\n apiKey: string;\r\n baseUrl?: string;\r\n children: React.ReactNode;\r\n}\r\n\r\nexport const UrProvider: React.FC = ({ apiKey, baseUrl, children }) => {\r\n const [user, setUser] = useState(null);\r\n const [isInitializing, setIsInitializing] = useState(true);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n const { client, auth, db, storage } = useMemo(() => {\r\n const _client = new UrBackendClient({ apiKey, baseUrl });\r\n return {\r\n client: _client,\r\n auth: new AuthModule(_client),\r\n db: new DatabaseModule(_client),\r\n storage: new StorageModule(_client),\r\n };\r\n }, [apiKey, baseUrl]);\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n\r\n const initAuth = async () => {\r\n try {\r\n // Hydrate from localStorage first as a fallback for environments without cookies\r\n if (typeof window !== 'undefined') {\r\n const savedToken = localStorage.getItem('ur_auth_token');\r\n if (savedToken) auth.setToken(savedToken);\r\n }\r\n\r\n // Check for social auth callback params\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hashParams = new URLSearchParams(window.location.hash.substring(1));\r\n const token = hashParams.get('token');\r\n const rtCode = urlParams.get('rtCode');\r\n const error = urlParams.get('error');\r\n\r\n if (error) {\r\n console.error('Social Auth Error:', error);\r\n if (mounted) setError(error);\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else if (token) {\r\n // Social auth succeeded, establish session immediately\r\n auth.setToken(token);\r\n if (typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n \r\n if (rtCode) {\r\n // Exchange for long-lived refresh token\r\n try {\r\n const exRes = await auth.socialExchange({ token, rtCode });\r\n const exToken = (exRes as any).accessToken || (exRes as any).token;\r\n if (exToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', exToken);\r\n } catch (err: any) {\r\n console.error('Failed to exchange refresh token', err);\r\n if (mounted) setError(err.message || 'Failed to complete social login');\r\n throw err;\r\n }\r\n }\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else {\r\n // Attempt to silently refresh session using the HTTP-only cookie\r\n try {\r\n const res = await auth.refreshToken();\r\n const newToken = res.accessToken || (res as any).token;\r\n if (newToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', newToken);\r\n } catch (e) {\r\n // If refresh fails, me() will catch it\r\n }\r\n }\r\n \r\n const currentUser = await auth.me();\r\n if (mounted) {\r\n setUser(currentUser);\r\n }\r\n } catch (error: any) {\r\n if (mounted) {\r\n setUser(null);\r\n // Don't set global error for initial me() check failure (usually just means not logged in)\r\n }\r\n } finally {\r\n if (mounted) {\r\n setIsInitializing(false);\r\n }\r\n }\r\n };\r\n\r\n initAuth();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [auth]);\r\n\r\n const value: UrContextValue = {\r\n client,\r\n auth,\r\n db,\r\n storage,\r\n user,\r\n setUser,\r\n isInitializing,\r\n isLoading,\r\n setIsLoading,\r\n error,\r\n setError,\r\n };\r\n\r\n return {children} ;\r\n};\r\n\r\nexport const useUrContext = () => {\r\n const context = useContext(UrContext);\r\n if (!context) {\r\n throw new Error('useUrContext must be used within an UrProvider');\r\n }\r\n return context;\r\n};\r\n","import { useCallback } from 'react';\r\nimport { useUrContext } from './context';\r\nimport type { \r\n LoginPayload, \r\n SignUpPayload, \r\n ChangePasswordPayload,\r\n VerifyEmailPayload,\r\n RequestPasswordResetPayload,\r\n ResetPasswordPayload\r\n} from '@urbackend/sdk';\r\n\r\nexport const useAuth = () => {\r\n const { auth, user, setUser, isInitializing, isLoading, setIsLoading, error, setError } = useUrContext();\r\n\r\n if (!auth) {\r\n throw new Error('Auth module not initialized. Make sure you are inside UrProvider.');\r\n }\r\n\r\n const login = useCallback(async (payload: LoginPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const res = await auth.login(payload);\r\n const token = res.accessToken || (res as any).token;\r\n if (token && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n const currentUser = await auth.me();\r\n setUser(currentUser);\r\n } catch (err: any) {\r\n setError(err.message || 'Login failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const signUp = useCallback(async (payload: SignUpPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const newUser = await auth.signUp(payload);\r\n return newUser;\r\n } catch (err: any) {\r\n setError(err.message || 'Sign up failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setIsLoading, setError]);\r\n\r\n const logout = useCallback(async () => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n await auth.logout();\r\n if (typeof window !== 'undefined') localStorage.removeItem('ur_auth_token');\r\n setUser(null);\r\n } catch (err: any) {\r\n setError(err.message || 'Logout failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const socialLogin = useCallback((provider: 'google' | 'github') => {\r\n setError(null);\r\n const url = auth.socialStart(provider);\r\n window.location.href = url;\r\n }, [auth, setError]);\r\n \r\n const verifyEmail = useCallback(async (payload: VerifyEmailPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.verifyEmail(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Email verification failed');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const changePassword = useCallback(async (payload: ChangePasswordPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.changePassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to change password');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const requestPasswordReset = useCallback(async (payload: RequestPasswordResetPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.requestPasswordReset(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to request password reset');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const resetPassword = useCallback(async (payload: ResetPasswordPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.resetPassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to reset password');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const clearError = useCallback(() => setError(null), [setError]);\r\n\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n login,\r\n signUp,\r\n logout,\r\n socialLogin,\r\n verifyEmail,\r\n changePassword,\r\n requestPasswordReset,\r\n resetPassword,\r\n clearError,\r\n authApi: auth // Escape hatch to underlying SDK\r\n };\r\n};\r\n\r\nexport const useUser = () => {\r\n const { user, isInitializing, isLoading, error } = useUrContext();\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n };\r\n};\r\n\r\nexport const useDb = () => {\r\n const { db } = useUrContext();\r\n if (!db) {\r\n throw new Error('Database module not initialized.');\r\n }\r\n return db;\r\n};\r\n\r\nexport const useStorage = () => {\r\n const { storage } = useUrContext();\r\n if (!storage) {\r\n throw new Error('Storage module not initialized.');\r\n }\r\n return storage;\r\n};\r\n","import React, { useEffect } from 'react';\r\nimport { useUser } from './hooks';\r\n\r\nexport interface ProtectedRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to be authenticated.\r\n * If the user is not authenticated after initialization, they will be redirected,\r\n * or the fallback will be rendered (or nothing if fallback is not provided and no window redirect occurs).\r\n */\r\nexport const ProtectedRoute: React.FC = ({ \r\n children, \r\n redirectTo = '/login', \r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && !isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (!isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n\r\nexport interface GuestRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to NOT be authenticated (e.g. for Login pages).\r\n * If the user IS authenticated, they will be redirected to the specified route.\r\n */\r\nexport const GuestRoute: React.FC = ({\r\n children,\r\n redirectTo = '/dashboard',\r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\nimport { useAuth } from '../hooks';\r\nimport { Toast } from './Toast';\r\n\r\ntype AuthProvider = 'google' | 'github';\r\ntype ThemeMode = 'light' | 'dark';\r\n\r\ninterface AuthColors {\r\n background: string;\r\n surface: string;\r\n text: string;\r\n textMuted: string;\r\n border: string;\r\n inputBackground: string;\r\n primary: string;\r\n primaryText: string;\r\n footerBackground: string;\r\n dividerText: string;\r\n socialButtonBackground: string;\r\n}\r\n\r\ninterface AuthBranding {\r\n brandName?: string;\r\n appName?: string;\r\n title?: string;\r\n subtitle?: string;\r\n logo?: React.ReactNode | string;\r\n primaryColor?: string;\r\n}\r\n\r\ninterface AuthLabels {\r\n loginTab: string;\r\n signupTab: string;\r\n loginTitle: string;\r\n signupTitle: string;\r\n forgotTitle: string;\r\n resetTitle: string;\r\n loginButton: string;\r\n signupButton: string;\r\n forgotButton: string;\r\n resetButton: string;\r\n emailLabel: string;\r\n emailPlaceholder: string;\r\n passwordLabel: string;\r\n passwordPlaceholder: string;\r\n nameLabel: string;\r\n namePlaceholder: string;\r\n otpLabel: string;\r\n otpPlaceholder: string;\r\n forgotPasswordLink: string;\r\n socialDivider: string;\r\n googleButton: string;\r\n githubButton: string;\r\n footerSigninPrompt: string;\r\n footerSignupPrompt: string;\r\n footerForgotPrompt: string;\r\n noAuthMethods: string;\r\n // Aliases support\r\n signInTitle?: string;\r\n signUpTitle?: string;\r\n signInTab?: string;\r\n signUpTab?: string;\r\n signInButton?: string;\r\n signUpButton?: string;\r\n}\r\n\r\nexport interface UrAuthProps {\r\n providers?: AuthProvider[] | {\r\n google?: boolean;\r\n github?: boolean;\r\n emailPassword?: boolean;\r\n };\r\n enableEmailPassword?: boolean;\r\n theme?: ThemeMode;\r\n colors?: Partial;\r\n branding?: AuthBranding;\r\n labels?: Partial;\r\n onSuccess?: () => void;\r\n}\r\n\r\nconst defaultLabels: AuthLabels = {\r\n loginTab: 'Login',\r\n signupTab: 'Sign Up',\r\n loginTitle: 'Welcome back',\r\n signupTitle: 'Create your account',\r\n forgotTitle: 'Reset Password',\r\n resetTitle: 'Enter Reset Code',\r\n loginButton: 'Log In',\r\n signupButton: 'Create Account',\r\n forgotButton: 'Send Reset Code',\r\n resetButton: 'Reset Password',\r\n emailLabel: 'Email address',\r\n emailPlaceholder: 'Enter your email address',\r\n passwordLabel: 'Password',\r\n passwordPlaceholder: 'Enter your password',\r\n nameLabel: 'Full Name',\r\n namePlaceholder: 'Enter your name',\r\n otpLabel: '6-digit OTP Code',\r\n otpPlaceholder: 'Enter reset code',\r\n forgotPasswordLink: 'Forgot password?',\r\n socialDivider: 'OR',\r\n googleButton: 'Continue with Google',\r\n githubButton: 'Continue with GitHub',\r\n footerSigninPrompt: \"Don't have an account yet?\",\r\n footerSignupPrompt: 'Already have an account?',\r\n footerForgotPrompt: 'Remember your password?',\r\n noAuthMethods: 'No authentication methods are enabled for this screen.',\r\n};\r\n\r\nconst defaultThemeColors: Record = {\r\n light: {\r\n background: '#ffffff',\r\n surface: '#ffffff',\r\n text: '#0f172a',\r\n textMuted: '#64748b',\r\n border: '#e2e8f0',\r\n inputBackground: '#ffffff',\r\n primary: '#111111',\r\n primaryText: '#ffffff',\r\n footerBackground: '#f8fafc',\r\n dividerText: '#94a3b8',\r\n socialButtonBackground: '#ffffff',\r\n },\r\n dark: {\r\n background: '#1a1a1a',\r\n surface: '#1a1a1a',\r\n text: '#ffffff',\r\n textMuted: '#a1a1aa',\r\n border: '#333333',\r\n inputBackground: '#2a2a2a',\r\n primary: '#ffffff',\r\n primaryText: '#111111',\r\n footerBackground: '#222222',\r\n dividerText: '#94a3b8',\r\n socialButtonBackground: '#2a2a2a',\r\n },\r\n};\r\n\r\nexport const UrAuth: React.FC = ({ \r\n providers = ['google', 'github'], \r\n enableEmailPassword = true,\r\n theme = 'light',\r\n colors,\r\n branding,\r\n labels,\r\n onSuccess\r\n}) => {\r\n const { login, signUp, socialLogin, requestPasswordReset, resetPassword, isLoading, error, clearError } = useAuth();\r\n const [mode, setMode] = useState<'signin' | 'signup' | 'forgot' | 'reset'>('signin');\r\n const [email, setEmail] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [otp, setOtp] = useState('');\r\n const [name, setName] = useState('');\r\n const [toast, setToast] = useState<{message: string, type: 'success' | 'error'} | null>(null);\r\n\r\n const text = {\r\n ...defaultLabels,\r\n ...labels,\r\n loginTab: labels?.signInTab || labels?.loginTab || defaultLabels.loginTab,\r\n loginTitle: labels?.signInTitle || labels?.loginTitle || defaultLabels.loginTitle,\r\n loginButton: labels?.signInButton || labels?.loginButton || defaultLabels.loginButton,\r\n signupTab: labels?.signUpTab || labels?.signupTab || defaultLabels.signupTab,\r\n signupTitle: labels?.signUpTitle || labels?.signupTitle || defaultLabels.signupTitle,\r\n signupButton: labels?.signUpButton || labels?.signupButton || defaultLabels.signupButton,\r\n };\r\n\r\n const themeColors = { ...defaultThemeColors[theme], ...colors };\r\n const primaryColor = branding?.primaryColor || themeColors.primary;\r\n\r\n let isGoogleEnabled = true;\r\n let isGithubEnabled = true;\r\n let isEmailPasswordEnabled = enableEmailPassword;\r\n\r\n if (providers) {\r\n if (Array.isArray(providers)) {\r\n isGoogleEnabled = providers.includes('google');\r\n isGithubEnabled = providers.includes('github');\r\n } else if (typeof providers === 'object') {\r\n isGoogleEnabled = !!providers.google;\r\n isGithubEnabled = !!providers.github;\r\n isEmailPasswordEnabled = providers.emailPassword !== undefined ? providers.emailPassword : false;\r\n }\r\n }\r\n\r\n const hasPasswordAuth = isEmailPasswordEnabled;\r\n const hasSocialAuth = isGoogleEnabled || isGithubEnabled;\r\n const brandName = branding?.brandName || branding?.appName || branding?.title || 'urBackend';\r\n const headerTitle = branding?.title || brandName;\r\n const headerSubtitle = branding?.subtitle || (mode === 'signin'\r\n ? text.loginTitle\r\n : mode === 'signup'\r\n ? text.signupTitle\r\n : mode === 'forgot'\r\n ? text.forgotTitle\r\n : text.resetTitle);\r\n const showSwitcher = hasPasswordAuth;\r\n\r\n useEffect(() => {\r\n if (error) {\r\n setToast({ message: error, type: 'error' });\r\n }\r\n }, [error]);\r\n\r\n useEffect(() => {\r\n if (!hasPasswordAuth && mode !== 'signin') {\r\n setMode('signin');\r\n }\r\n }, [hasPasswordAuth, mode]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n if (mode === 'signin') {\r\n await login({ email, password });\r\n setToast({ message: 'Welcome back!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'signup') {\r\n await signUp({ email, password, name });\r\n await login({ email, password });\r\n setToast({ message: 'Account created successfully!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'forgot') {\r\n await requestPasswordReset({ email });\r\n setToast({ message: 'Reset code sent to your email', type: 'success' });\r\n setMode('reset');\r\n } else if (mode === 'reset') {\r\n await resetPassword({ email, otp, newPassword: password });\r\n setToast({ message: 'Password reset successfully', type: 'success' });\r\n setMode('signin');\r\n setPassword('');\r\n setOtp('');\r\n }\r\n } catch (err: any) {\r\n // Errors are surfaced via the shared auth hook state.\r\n }\r\n };\r\n\r\n const styles = {\r\n wrapper: {\r\n width: '100%',\r\n maxWidth: '420px',\r\n margin: '0 auto',\r\n borderRadius: '0',\r\n background: themeColors.background,\r\n boxShadow: theme === 'dark' ? '0 20px 40px rgba(0,0,0,0.5)' : '0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)',\r\n border: `1px solid ${themeColors.border}`,\r\n overflow: 'hidden',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n color: themeColors.text,\r\n },\r\n body: {\r\n padding: '32px 32px 24px 32px',\r\n },\r\n header: {\r\n textAlign: 'center' as const,\r\n marginBottom: '28px',\r\n },\r\n brandRow: {\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n gap: '12px',\r\n marginBottom: '10px',\r\n },\r\n brandLogo: {\r\n width: '44px',\r\n height: '44px',\r\n borderRadius: '12px',\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n background: theme === 'dark' ? '#2a2a2a' : '#f1f5f9',\r\n color: themeColors.text,\r\n overflow: 'hidden' as const,\r\n },\r\n brandTitle: {\r\n margin: 0,\r\n fontSize: '26px',\r\n lineHeight: 1.1,\r\n fontWeight: 800,\r\n color: themeColors.text,\r\n },\r\n brandSubtitle: {\r\n margin: '0 auto',\r\n maxWidth: '320px',\r\n fontSize: '14px',\r\n lineHeight: 1.5,\r\n color: themeColors.textMuted,\r\n },\r\n switcherContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n marginBottom: '32px'\r\n },\r\n switcher: {\r\n display: 'inline-flex',\r\n background: theme === 'dark' ? '#2a2a2a' : '#f1f5f9',\r\n padding: '4px',\r\n borderRadius: '0',\r\n },\r\n switchBtn: (active: boolean) => ({\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n padding: '8px 20px',\r\n borderRadius: '0',\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n color: active ? themeColors.text : themeColors.textMuted,\r\n background: active ? (theme === 'dark' ? '#444444' : '#ffffff') : 'transparent',\r\n boxShadow: active ? (theme === 'dark' ? '0 2px 4px rgba(0,0,0,0.2)' : '0 2px 8px rgba(0,0,0,0.05)') : 'none',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n }),\r\n field: {\r\n marginBottom: '20px',\r\n },\r\n labelRow: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n marginBottom: '8px',\r\n },\r\n label: {\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n color: theme === 'dark' ? '#dddddd' : '#334155',\r\n },\r\n forgotLink: {\r\n fontSize: '12px',\r\n fontWeight: 600,\r\n color: themeColors.text,\r\n cursor: 'pointer',\r\n textDecoration: 'none',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n borderRadius: '0',\r\n border: `1px solid ${themeColors.border}`,\r\n background: themeColors.inputBackground,\r\n color: themeColors.text,\r\n fontSize: '14px',\r\n boxSizing: 'border-box' as const,\r\n outline: 'none',\r\n transition: 'border-color 0.2s ease',\r\n },\r\n primaryBtn: {\r\n width: '100%',\r\n padding: '14px',\r\n borderRadius: '0',\r\n background: `linear-gradient(180deg, ${primaryColor} 0%, ${theme === 'dark' ? '#111111' : '#111111'} 100%)`,\r\n color: themeColors.primaryText,\r\n fontSize: '15px',\r\n fontWeight: 600,\r\n border: 'none',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\r\n cursor: 'pointer',\r\n marginTop: '8px',\r\n transition: 'transform 0.1s ease',\r\n },\r\n divider: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n margin: '24px 0',\r\n color: themeColors.dividerText,\r\n fontSize: '11px',\r\n fontWeight: 600,\r\n letterSpacing: '1px',\r\n },\r\n dividerLine: {\r\n flex: 1,\r\n height: '1px',\r\n background: themeColors.border,\r\n },\r\n dividerText: {\r\n padding: '0 12px',\r\n },\r\n socialBtn: {\r\n width: '100%',\r\n padding: '12px',\r\n borderRadius: '0',\r\n border: `1px solid ${themeColors.border}`,\r\n background: themeColors.socialButtonBackground,\r\n color: themeColors.text,\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '10px',\r\n marginBottom: '12px',\r\n cursor: 'pointer',\r\n boxShadow: theme === 'dark' ? 'none' : '0 1px 2px rgba(0,0,0,0.02)',\r\n transition: 'background 0.2s ease',\r\n },\r\n footer: {\r\n background: themeColors.footerBackground,\r\n padding: '24px',\r\n textAlign: 'center' as const,\r\n borderTop: `1px solid ${themeColors.border}`,\r\n fontSize: '13px',\r\n color: themeColors.textMuted,\r\n },\r\n footerLink: {\r\n color: themeColors.text,\r\n fontWeight: 600,\r\n textDecoration: 'underline',\r\n cursor: 'pointer',\r\n marginLeft: '4px',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n }\r\n };\r\n\r\n const GoogleIcon = () => (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n\r\n const GithubIcon = () => (\r\n \r\n \r\n \r\n );\r\n\r\n const renderSocialButtons = () => {\r\n if (!hasSocialAuth) {\r\n return null;\r\n }\r\n\r\n return (\r\n <>\r\n {hasPasswordAuth && (\r\n \r\n
\r\n
{text.socialDivider} \r\n
\r\n
\r\n )}\r\n\r\n \r\n {isGoogleEnabled && (\r\n socialLogin('google')} type=\"button\">\r\n \r\n {text.googleButton}\r\n \r\n )}\r\n {isGithubEnabled && (\r\n socialLogin('github')} type=\"button\">\r\n \r\n {text.githubButton}\r\n \r\n )}\r\n
\r\n >\r\n );\r\n };\r\n\r\n const footerPrompt = mode === 'signin'\r\n ? text.footerSigninPrompt\r\n : mode === 'signup'\r\n ? text.footerSignupPrompt\r\n : text.footerForgotPrompt;\r\n\r\n return (\r\n \r\n {toast && (\r\n
{\r\n setToast(null);\r\n if (toast.type === 'error') clearError();\r\n }} \r\n />\r\n )}\r\n \r\n \r\n {(branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle || headerTitle || headerSubtitle) && (\r\n
\r\n
\r\n {branding?.logo ? (\r\n
\r\n {typeof branding.logo === 'string' ? (\r\n
\r\n ) : (\r\n branding.logo\r\n )}\r\n
\r\n ) : (\r\n
\r\n {brandName.slice(0, 1).toUpperCase()}\r\n
\r\n )}\r\n
\r\n
{headerTitle} \r\n
{headerSubtitle}
\r\n
\r\n )}\r\n\r\n {showSwitcher && (mode === 'signin' || mode === 'signup') && (\r\n
\r\n
\r\n
{ setMode('signin'); clearError(); }}\r\n >\r\n \r\n {text.loginTab}\r\n \r\n
{ setMode('signup'); clearError(); }}\r\n >\r\n \r\n {text.signupTab}\r\n \r\n
\r\n
\r\n )}\r\n\r\n {(mode === 'forgot' || mode === 'reset') && (\r\n
\r\n
\r\n {mode === 'forgot' ? text.forgotTitle : text.resetTitle}\r\n \r\n
\r\n {mode === 'forgot' ? text.loginTitle : `Enter the code sent to ${email}`}\r\n
\r\n
\r\n )}\r\n\r\n {!hasPasswordAuth && !hasSocialAuth && (\r\n
\r\n {text.noAuthMethods}\r\n
\r\n )}\r\n\r\n {hasPasswordAuth && (\r\n
\r\n )}\r\n\r\n {(mode === 'signin' || mode === 'signup') && renderSocialButtons()}\r\n
\r\n\r\n {hasPasswordAuth && (\r\n \r\n {footerPrompt}\r\n {\r\n setMode(mode === 'signin' ? 'signup' : 'signin');\r\n clearError();\r\n }}\r\n >\r\n {mode === 'signin' ? text.signupTab : text.loginTab}\r\n \r\n
\r\n )}\r\n \r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\n\r\ninterface ToastProps {\r\n message: string;\r\n type: 'success' | 'error';\r\n onClose: () => void;\r\n isDark?: boolean;\r\n}\r\n\r\nexport const Toast: React.FC = ({ message, type, onClose, isDark = false }) => {\r\n const [isVisible, setIsVisible] = useState(false);\r\n const [isLeaving, setIsLeaving] = useState(false);\r\n\r\n useEffect(() => {\r\n // Trigger enter animation on mount\r\n requestAnimationFrame(() => {\r\n setIsVisible(true);\r\n });\r\n\r\n let innerTimer: ReturnType;\r\n const timer = setTimeout(() => {\r\n setIsLeaving(true);\r\n innerTimer = setTimeout(onClose, 300); // Wait for exit animation\r\n }, 4000);\r\n\r\n return () => {\r\n clearTimeout(timer);\r\n if (innerTimer) clearTimeout(innerTimer);\r\n };\r\n }, [onClose]);\r\n\r\n const bgColor = isDark ? 'rgba(30, 30, 30, 0.9)' : 'rgba(255, 255, 255, 0.9)';\r\n const borderColor = type === 'success' ? 'rgba(34, 197, 94, 0.5)' : 'rgba(239, 68, 68, 0.5)';\r\n const iconColor = type === 'success' ? '#22c55e' : '#ef4444';\r\n const textColor = isDark ? '#fff' : '#000';\r\n\r\n return (\r\n <>\r\n \r\n \r\n {type === 'success' ? (\r\n
\r\n \r\n \r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n \r\n )}\r\n {message}\r\n
\r\n >\r\n );\r\n};\r\n","import React, { useState, useRef, useEffect } from 'react';\r\nimport { useUser, useAuth } from '../hooks';\r\n\r\nexport interface UrUserButtonProps {\r\n /**\r\n * Shape of the profile avatar. Defaults to 'square' as requested.\r\n */\r\n shape?: 'square' | 'circle';\r\n /**\r\n * Position of the button on the screen. Defaults to 'top-right'.\r\n * Use 'inline' if you want to place it within a normal flex/grid layout instead of absolute positioning.\r\n */\r\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'inline';\r\n /**\r\n * Called when \"Profile\" is clicked.\r\n */\r\n onProfileClick?: () => void;\r\n /**\r\n * Called when \"Settings\" is clicked.\r\n */\r\n onSettingsClick?: () => void;\r\n /**\r\n * Z-index for the fixed container. Defaults to 999.\r\n */\r\n zIndex?: number;\r\n}\r\n\r\nexport const UrUserButton: React.FC = ({\r\n shape = 'square',\r\n position = 'top-right',\r\n onProfileClick,\r\n onSettingsClick,\r\n zIndex = 999,\r\n}) => {\r\n const { user } = useUser();\r\n const { logout } = useAuth();\r\n const [isOpen, setIsOpen] = useState(false);\r\n const containerRef = useRef(null);\r\n\r\n useEffect(() => {\r\n const handleClickOutside = (event: MouseEvent) => {\r\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\r\n setIsOpen(false);\r\n }\r\n };\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => document.removeEventListener('mousedown', handleClickOutside);\r\n }, []);\r\n\r\n if (!user) return null; // Only render if logged in\r\n\r\n const borderRadius = shape === 'circle' ? '50%' : '0px';\r\n const isFixed = position !== 'inline';\r\n\r\n const positionStyles: React.CSSProperties = isFixed\r\n ? {\r\n position: 'fixed',\r\n zIndex,\r\n top: position.includes('top') ? '24px' : 'auto',\r\n bottom: position.includes('bottom') ? '24px' : 'auto',\r\n right: position.includes('right') ? '24px' : 'auto',\r\n left: position.includes('left') ? '24px' : 'auto',\r\n }\r\n : { position: 'relative' };\r\n\r\n const dropdownStyles: React.CSSProperties = {\r\n position: 'absolute',\r\n top: position.includes('top') || position === 'inline' ? 'calc(100% + 8px)' : 'auto',\r\n bottom: position.includes('bottom') ? 'calc(100% + 8px)' : 'auto',\r\n right: position.includes('right') || position === 'inline' ? '0' : 'auto',\r\n left: position.includes('left') ? '0' : 'auto',\r\n background: '#ffffff',\r\n border: '1px solid #e2e8f0',\r\n borderRadius: '0px',\r\n boxShadow: '0 10px 25px rgba(0,0,0,0.1)',\r\n width: '220px',\r\n display: isOpen ? 'block' : 'none',\r\n overflow: 'hidden',\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n };\r\n\r\n const getInitials = () => {\r\n return user.name?.[0]?.toUpperCase() || user.email?.[0]?.toUpperCase() || 'U';\r\n };\r\n\r\n return (\r\n \r\n
setIsOpen(!isOpen)}\r\n style={{\r\n width: '40px',\r\n height: '40px',\r\n padding: 0,\r\n border: '1px solid #e2e8f0',\r\n background: '#f8fafc',\r\n borderRadius,\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n overflow: 'hidden',\r\n boxShadow: '0 2px 5px rgba(0,0,0,0.05)',\r\n transition: 'transform 0.1s ease',\r\n }}\r\n >\r\n {user.avatarUrl ? (\r\n \r\n ) : (\r\n \r\n {getInitials()}\r\n \r\n )}\r\n \r\n\r\n
\r\n {/* User Info Header */}\r\n
\r\n
\r\n {user.name || 'User'}\r\n
\r\n
\r\n {user.email}\r\n
\r\n
\r\n\r\n {/* Action List */}\r\n
\r\n {onProfileClick && (\r\n
{\r\n setIsOpen(false);\r\n onProfileClick();\r\n }}\r\n style={{\r\n width: '100%',\r\n textAlign: 'left',\r\n padding: '10px 12px',\r\n background: 'transparent',\r\n border: 'none',\r\n fontSize: '14px',\r\n color: '#334155',\r\n cursor: 'pointer',\r\n borderRadius: '0px',\r\n display: 'block',\r\n }}\r\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\r\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\r\n >\r\n Profile\r\n \r\n )}\r\n\r\n {onSettingsClick && (\r\n
{\r\n setIsOpen(false);\r\n onSettingsClick();\r\n }}\r\n style={{\r\n width: '100%',\r\n textAlign: 'left',\r\n padding: '10px 12px',\r\n background: 'transparent',\r\n border: 'none',\r\n fontSize: '14px',\r\n color: '#334155',\r\n cursor: 'pointer',\r\n borderRadius: '0px',\r\n display: 'block',\r\n }}\r\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\r\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\r\n >\r\n Settings\r\n \r\n )}\r\n\r\n
\r\n\r\n
{\r\n setIsOpen(false);\r\n logout();\r\n }}\r\n style={{\r\n width: '100%',\r\n textAlign: 'left',\r\n padding: '10px 12px',\r\n background: 'transparent',\r\n border: 'none',\r\n fontSize: '14px',\r\n color: '#ef4444',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n borderRadius: '0px',\r\n display: 'block',\r\n }}\r\n onMouseEnter={(e) => (e.currentTarget.style.background = '#fef2f2')}\r\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\r\n >\r\n Logout\r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n"],"mappings":"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","names":["error","import_react","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime"]}
\ No newline at end of file
diff --git a/sdks/urbackend-react/dist/index.mjs b/sdks/urbackend-react/dist/index.mjs
index c890d9a7..b2358536 100644
--- a/sdks/urbackend-react/dist/index.mjs
+++ b/sdks/urbackend-react/dist/index.mjs
@@ -294,7 +294,7 @@ var GuestRoute = ({
};
// src/components/UrAuth.tsx
-import { useState as useState3, useEffect as useEffect4 } from "react";
+import { useEffect as useEffect4, useState as useState3 } from "react";
// src/components/Toast.tsx
import { useEffect as useEffect3, useState as useState2 } from "react";
@@ -374,9 +374,69 @@ var Toast = ({ message, type, onClose, isDark = false }) => {
// src/components/UrAuth.tsx
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
+var defaultLabels = {
+ loginTab: "Login",
+ signupTab: "Sign Up",
+ loginTitle: "Welcome back",
+ signupTitle: "Create your account",
+ forgotTitle: "Reset Password",
+ resetTitle: "Enter Reset Code",
+ loginButton: "Log In",
+ signupButton: "Create Account",
+ forgotButton: "Send Reset Code",
+ resetButton: "Reset Password",
+ emailLabel: "Email address",
+ emailPlaceholder: "Enter your email address",
+ passwordLabel: "Password",
+ passwordPlaceholder: "Enter your password",
+ nameLabel: "Full Name",
+ namePlaceholder: "Enter your name",
+ otpLabel: "6-digit OTP Code",
+ otpPlaceholder: "Enter reset code",
+ forgotPasswordLink: "Forgot password?",
+ socialDivider: "OR",
+ googleButton: "Continue with Google",
+ githubButton: "Continue with GitHub",
+ footerSigninPrompt: "Don't have an account yet?",
+ footerSignupPrompt: "Already have an account?",
+ footerForgotPrompt: "Remember your password?",
+ noAuthMethods: "No authentication methods are enabled for this screen."
+};
+var defaultThemeColors = {
+ light: {
+ background: "#ffffff",
+ surface: "#ffffff",
+ text: "#0f172a",
+ textMuted: "#64748b",
+ border: "#e2e8f0",
+ inputBackground: "#ffffff",
+ primary: "#111111",
+ primaryText: "#ffffff",
+ footerBackground: "#f8fafc",
+ dividerText: "#94a3b8",
+ socialButtonBackground: "#ffffff"
+ },
+ dark: {
+ background: "#1a1a1a",
+ surface: "#1a1a1a",
+ text: "#ffffff",
+ textMuted: "#a1a1aa",
+ border: "#333333",
+ inputBackground: "#2a2a2a",
+ primary: "#ffffff",
+ primaryText: "#111111",
+ footerBackground: "#222222",
+ dividerText: "#94a3b8",
+ socialButtonBackground: "#2a2a2a"
+ }
+};
var UrAuth = ({
providers = ["google", "github"],
+ enableEmailPassword = true,
theme = "light",
+ colors,
+ branding,
+ labels,
onSuccess
}) => {
const { login, signUp, socialLogin, requestPasswordReset, resetPassword, isLoading, error, clearError } = useAuth();
@@ -386,11 +446,47 @@ var UrAuth = ({
const [otp, setOtp] = useState3("");
const [name, setName] = useState3("");
const [toast, setToast] = useState3(null);
+ const text = {
+ ...defaultLabels,
+ ...labels,
+ loginTab: labels?.signInTab || labels?.loginTab || defaultLabels.loginTab,
+ loginTitle: labels?.signInTitle || labels?.loginTitle || defaultLabels.loginTitle,
+ loginButton: labels?.signInButton || labels?.loginButton || defaultLabels.loginButton,
+ signupTab: labels?.signUpTab || labels?.signupTab || defaultLabels.signupTab,
+ signupTitle: labels?.signUpTitle || labels?.signupTitle || defaultLabels.signupTitle,
+ signupButton: labels?.signUpButton || labels?.signupButton || defaultLabels.signupButton
+ };
+ const themeColors = { ...defaultThemeColors[theme], ...colors };
+ const primaryColor = branding?.primaryColor || themeColors.primary;
+ let isGoogleEnabled = true;
+ let isGithubEnabled = true;
+ let isEmailPasswordEnabled = enableEmailPassword;
+ if (providers) {
+ if (Array.isArray(providers)) {
+ isGoogleEnabled = providers.includes("google");
+ isGithubEnabled = providers.includes("github");
+ } else if (typeof providers === "object") {
+ isGoogleEnabled = !!providers.google;
+ isGithubEnabled = !!providers.github;
+ isEmailPasswordEnabled = providers.emailPassword !== void 0 ? providers.emailPassword : false;
+ }
+ }
+ const hasPasswordAuth = isEmailPasswordEnabled;
+ const hasSocialAuth = isGoogleEnabled || isGithubEnabled;
+ const brandName = branding?.brandName || branding?.appName || branding?.title || "urBackend";
+ const headerTitle = branding?.title || brandName;
+ const headerSubtitle = branding?.subtitle || (mode === "signin" ? text.loginTitle : mode === "signup" ? text.signupTitle : mode === "forgot" ? text.forgotTitle : text.resetTitle);
+ const showSwitcher = hasPasswordAuth;
useEffect4(() => {
if (error) {
setToast({ message: error, type: "error" });
}
}, [error]);
+ useEffect4(() => {
+ if (!hasPasswordAuth && mode !== "signin") {
+ setMode("signin");
+ }
+ }, [hasPasswordAuth, mode]);
const handleSubmit = async (e) => {
e.preventDefault();
try {
@@ -417,28 +513,58 @@ var UrAuth = ({
} catch (err) {
}
};
- const isDark = theme === "dark";
- const bg = isDark ? "#1a1a1a" : "#ffffff";
- const text = isDark ? "#ffffff" : "#0f172a";
- const textMuted = isDark ? "#a1a1aa" : "#64748b";
- const border = isDark ? "#333" : "#e2e8f0";
- const inputBg = isDark ? "#2a2a2a" : "#ffffff";
const styles = {
wrapper: {
width: "100%",
maxWidth: "420px",
margin: "0 auto",
borderRadius: "0",
- background: bg,
- boxShadow: isDark ? "0 20px 40px rgba(0,0,0,0.5)" : "0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)",
- border: `1px solid ${border}`,
+ background: themeColors.background,
+ boxShadow: theme === "dark" ? "0 20px 40px rgba(0,0,0,0.5)" : "0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)",
+ border: `1px solid ${themeColors.border}`,
overflow: "hidden",
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
- color: text
+ color: themeColors.text
},
body: {
padding: "32px 32px 24px 32px"
},
+ header: {
+ textAlign: "center",
+ marginBottom: "28px"
+ },
+ brandRow: {
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ gap: "12px",
+ marginBottom: "10px"
+ },
+ brandLogo: {
+ width: "44px",
+ height: "44px",
+ borderRadius: "12px",
+ display: "inline-flex",
+ alignItems: "center",
+ justifyContent: "center",
+ background: theme === "dark" ? "#2a2a2a" : "#f1f5f9",
+ color: themeColors.text,
+ overflow: "hidden"
+ },
+ brandTitle: {
+ margin: 0,
+ fontSize: "26px",
+ lineHeight: 1.1,
+ fontWeight: 800,
+ color: themeColors.text
+ },
+ brandSubtitle: {
+ margin: "0 auto",
+ maxWidth: "320px",
+ fontSize: "14px",
+ lineHeight: 1.5,
+ color: themeColors.textMuted
+ },
switcherContainer: {
display: "flex",
alignItems: "center",
@@ -447,7 +573,7 @@ var UrAuth = ({
},
switcher: {
display: "inline-flex",
- background: isDark ? "#2a2a2a" : "#f1f5f9",
+ background: theme === "dark" ? "#2a2a2a" : "#f1f5f9",
padding: "4px",
borderRadius: "0"
},
@@ -460,9 +586,9 @@ var UrAuth = ({
fontSize: "13px",
fontWeight: 600,
cursor: "pointer",
- color: active ? text : textMuted,
- background: active ? isDark ? "#444" : "#ffffff" : "transparent",
- boxShadow: active ? isDark ? "0 2px 4px rgba(0,0,0,0.2)" : "0 2px 8px rgba(0,0,0,0.05)" : "none",
+ color: active ? themeColors.text : themeColors.textMuted,
+ background: active ? theme === "dark" ? "#444444" : "#ffffff" : "transparent",
+ boxShadow: active ? theme === "dark" ? "0 2px 4px rgba(0,0,0,0.2)" : "0 2px 8px rgba(0,0,0,0.05)" : "none",
border: "none",
transition: "all 0.2s ease"
}),
@@ -478,12 +604,12 @@ var UrAuth = ({
label: {
fontSize: "13px",
fontWeight: 600,
- color: isDark ? "#ddd" : "#334155"
+ color: theme === "dark" ? "#dddddd" : "#334155"
},
forgotLink: {
fontSize: "12px",
fontWeight: 600,
- color: text,
+ color: themeColors.text,
cursor: "pointer",
textDecoration: "none",
background: "none",
@@ -494,9 +620,9 @@ var UrAuth = ({
width: "100%",
padding: "12px 16px",
borderRadius: "0",
- border: `1px solid ${border}`,
- background: inputBg,
- color: text,
+ border: `1px solid ${themeColors.border}`,
+ background: themeColors.inputBackground,
+ color: themeColors.text,
fontSize: "14px",
boxSizing: "border-box",
outline: "none",
@@ -506,8 +632,8 @@ var UrAuth = ({
width: "100%",
padding: "14px",
borderRadius: "0",
- background: "linear-gradient(180deg, #2a2a2a 0%, #111111 100%)",
- color: "#ffffff",
+ background: `linear-gradient(180deg, ${primaryColor} 0%, ${theme === "dark" ? "#111111" : "#111111"} 100%)`,
+ color: themeColors.primaryText,
fontSize: "15px",
fontWeight: 600,
border: "none",
@@ -520,7 +646,7 @@ var UrAuth = ({
display: "flex",
alignItems: "center",
margin: "24px 0",
- color: "#94a3b8",
+ color: themeColors.dividerText,
fontSize: "11px",
fontWeight: 600,
letterSpacing: "1px"
@@ -528,7 +654,7 @@ var UrAuth = ({
dividerLine: {
flex: 1,
height: "1px",
- background: border
+ background: themeColors.border
},
dividerText: {
padding: "0 12px"
@@ -537,9 +663,9 @@ var UrAuth = ({
width: "100%",
padding: "12px",
borderRadius: "0",
- border: `1px solid ${border}`,
- background: isDark ? "#2a2a2a" : "#ffffff",
- color: text,
+ border: `1px solid ${themeColors.border}`,
+ background: themeColors.socialButtonBackground,
+ color: themeColors.text,
fontSize: "14px",
fontWeight: 600,
display: "flex",
@@ -548,19 +674,19 @@ var UrAuth = ({
gap: "10px",
marginBottom: "12px",
cursor: "pointer",
- boxShadow: isDark ? "none" : "0 1px 2px rgba(0,0,0,0.02)",
+ boxShadow: theme === "dark" ? "none" : "0 1px 2px rgba(0,0,0,0.02)",
transition: "background 0.2s ease"
},
footer: {
- background: isDark ? "#222" : "#f8fafc",
+ background: themeColors.footerBackground,
padding: "24px",
textAlign: "center",
- borderTop: `1px solid ${border}`,
+ borderTop: `1px solid ${themeColors.border}`,
fontSize: "13px",
- color: textMuted
+ color: themeColors.textMuted
},
footerLink: {
- color: text,
+ color: themeColors.text,
fontWeight: 600,
textDecoration: "underline",
cursor: "pointer",
@@ -576,14 +702,37 @@ var UrAuth = ({
/* @__PURE__ */ jsx4("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }),
/* @__PURE__ */ jsx4("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })
] });
- const GithubIcon = () => /* @__PURE__ */ jsx4("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: isDark ? "#fff" : "#000", children: /* @__PURE__ */ jsx4("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" }) });
+ const GithubIcon = () => /* @__PURE__ */ jsx4("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: theme === "dark" ? "#fff" : "#000", children: /* @__PURE__ */ jsx4("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" }) });
+ const renderSocialButtons = () => {
+ if (!hasSocialAuth) {
+ return null;
+ }
+ return /* @__PURE__ */ jsxs2(Fragment3, { children: [
+ hasPasswordAuth && /* @__PURE__ */ jsxs2("div", { style: styles.divider, children: [
+ /* @__PURE__ */ jsx4("div", { style: styles.dividerLine }),
+ /* @__PURE__ */ jsx4("span", { style: styles.dividerText, children: text.socialDivider }),
+ /* @__PURE__ */ jsx4("div", { style: styles.dividerLine })
+ ] }),
+ /* @__PURE__ */ jsxs2("div", { children: [
+ isGoogleEnabled && /* @__PURE__ */ jsxs2("button", { style: styles.socialBtn, onClick: () => socialLogin("google"), type: "button", children: [
+ /* @__PURE__ */ jsx4(GoogleIcon, {}),
+ text.googleButton
+ ] }),
+ isGithubEnabled && /* @__PURE__ */ jsxs2("button", { style: styles.socialBtn, onClick: () => socialLogin("github"), type: "button", children: [
+ /* @__PURE__ */ jsx4(GithubIcon, {}),
+ text.githubButton
+ ] })
+ ] })
+ ] });
+ };
+ const footerPrompt = mode === "signin" ? text.footerSigninPrompt : mode === "signup" ? text.footerSignupPrompt : text.footerForgotPrompt;
return /* @__PURE__ */ jsxs2("div", { style: styles.wrapper, children: [
toast && /* @__PURE__ */ jsx4(
Toast,
{
message: toast.message,
type: toast.type,
- isDark,
+ isDark: theme === "dark",
onClose: () => {
setToast(null);
if (toast.type === "error") clearError();
@@ -591,7 +740,12 @@ var UrAuth = ({
}
),
/* @__PURE__ */ jsxs2("div", { style: styles.body, children: [
- (mode === "signin" || mode === "signup") && /* @__PURE__ */ jsx4("div", { style: styles.switcherContainer, children: /* @__PURE__ */ jsxs2("div", { style: styles.switcher, children: [
+ (branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle || headerTitle || headerSubtitle) && /* @__PURE__ */ jsxs2("div", { style: styles.header, children: [
+ /* @__PURE__ */ jsx4("div", { style: styles.brandRow, children: branding?.logo ? /* @__PURE__ */ jsx4("div", { style: styles.brandLogo, children: typeof branding.logo === "string" ? /* @__PURE__ */ jsx4("img", { src: branding.logo, alt: brandName, style: { width: "100%", height: "100%", objectFit: "contain" } }) : branding.logo }) : /* @__PURE__ */ jsx4("div", { style: styles.brandLogo, "aria-hidden": "true", children: brandName.slice(0, 1).toUpperCase() }) }),
+ /* @__PURE__ */ jsx4("h1", { style: styles.brandTitle, children: headerTitle }),
+ /* @__PURE__ */ jsx4("p", { style: styles.brandSubtitle, children: headerSubtitle })
+ ] }),
+ showSwitcher && (mode === "signin" || mode === "signup") && /* @__PURE__ */ jsx4("div", { style: styles.switcherContainer, children: /* @__PURE__ */ jsxs2("div", { style: styles.switcher, children: [
/* @__PURE__ */ jsxs2(
"button",
{
@@ -607,7 +761,7 @@ var UrAuth = ({
/* @__PURE__ */ jsx4("polyline", { points: "10 17 15 12 10 7" }),
/* @__PURE__ */ jsx4("line", { x1: "15", y1: "12", x2: "3", y2: "12" })
] }),
- "Login"
+ text.loginTab
]
}
),
@@ -627,24 +781,25 @@ var UrAuth = ({
/* @__PURE__ */ jsx4("line", { x1: "19", y1: "8", x2: "19", y2: "14" }),
/* @__PURE__ */ jsx4("line", { x1: "22", y1: "11", x2: "16", y2: "11" })
] }),
- "Sign Up"
+ text.signupTab
]
}
)
] }) }),
(mode === "forgot" || mode === "reset") && /* @__PURE__ */ jsxs2("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
- /* @__PURE__ */ jsx4("h2", { style: { margin: "0 0 8px", fontSize: "20px", fontWeight: 700, color: text }, children: mode === "forgot" ? "Reset Password" : "Enter Reset Code" }),
- /* @__PURE__ */ jsx4("p", { style: { margin: 0, fontSize: "14px", color: textMuted }, children: mode === "forgot" ? "Enter your email and we'll send a code" : `Enter the code sent to ${email}` })
+ /* @__PURE__ */ jsx4("h2", { style: { margin: "0 0 8px", fontSize: "20px", fontWeight: 700, color: themeColors.text }, children: mode === "forgot" ? text.forgotTitle : text.resetTitle }),
+ /* @__PURE__ */ jsx4("p", { style: { margin: 0, fontSize: "14px", color: themeColors.textMuted }, children: mode === "forgot" ? text.loginTitle : `Enter the code sent to ${email}` })
] }),
- /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, children: [
+ !hasPasswordAuth && !hasSocialAuth && /* @__PURE__ */ jsx4("div", { style: { textAlign: "center", color: themeColors.textMuted, fontSize: "14px", lineHeight: 1.5 }, children: text.noAuthMethods }),
+ hasPasswordAuth && /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, children: [
mode === "signup" && /* @__PURE__ */ jsxs2("div", { style: styles.field, children: [
- /* @__PURE__ */ jsx4("div", { style: styles.labelRow, children: /* @__PURE__ */ jsx4("label", { style: styles.label, children: "Full Name" }) }),
+ /* @__PURE__ */ jsx4("div", { style: styles.labelRow, children: /* @__PURE__ */ jsx4("label", { style: styles.label, children: text.nameLabel }) }),
/* @__PURE__ */ jsx4(
"input",
{
style: styles.input,
type: "text",
- placeholder: "Enter your name",
+ placeholder: text.namePlaceholder,
value: name,
onChange: (e) => setName(e.target.value),
required: true
@@ -652,13 +807,13 @@ var UrAuth = ({
)
] }),
/* @__PURE__ */ jsxs2("div", { style: styles.field, children: [
- /* @__PURE__ */ jsx4("div", { style: styles.labelRow, children: /* @__PURE__ */ jsx4("label", { style: styles.label, children: "Email address" }) }),
+ /* @__PURE__ */ jsx4("div", { style: styles.labelRow, children: /* @__PURE__ */ jsx4("label", { style: styles.label, children: text.emailLabel }) }),
/* @__PURE__ */ jsx4(
"input",
{
style: styles.input,
type: "email",
- placeholder: "Enter your email address",
+ placeholder: text.emailPlaceholder,
value: email,
onChange: (e) => setEmail(e.target.value),
required: true,
@@ -666,40 +821,40 @@ var UrAuth = ({
}
)
] }),
- mode === "reset" && /* @__PURE__ */ jsxs2("div", { style: styles.field, children: [
- /* @__PURE__ */ jsx4("div", { style: styles.labelRow, children: /* @__PURE__ */ jsx4("label", { style: styles.label, children: "6-digit OTP Code" }) }),
- /* @__PURE__ */ jsx4(
- "input",
- {
- style: styles.input,
- type: "text",
- placeholder: "Enter reset code",
- value: otp,
- onChange: (e) => setOtp(e.target.value),
- required: true
- }
- )
- ] }),
(mode === "signin" || mode === "signup" || mode === "reset") && /* @__PURE__ */ jsxs2("div", { style: styles.field, children: [
/* @__PURE__ */ jsxs2("div", { style: styles.labelRow, children: [
- /* @__PURE__ */ jsx4("label", { style: styles.label, children: mode === "reset" ? "New Password" : "Password" }),
+ /* @__PURE__ */ jsx4("label", { style: styles.label, children: mode === "reset" ? text.passwordLabel : text.passwordLabel }),
mode === "signin" && /* @__PURE__ */ jsx4("button", { type: "button", style: styles.forgotLink, onClick: () => {
setMode("forgot");
clearError();
- }, children: "Forgot password?" })
+ }, children: text.forgotPasswordLink })
] }),
/* @__PURE__ */ jsx4(
"input",
{
style: styles.input,
type: "password",
- placeholder: mode === "reset" ? "Enter new password" : "Enter your password",
+ placeholder: text.passwordPlaceholder,
value: password,
onChange: (e) => setPassword(e.target.value),
required: true
}
)
] }),
+ mode === "reset" && /* @__PURE__ */ jsxs2("div", { style: styles.field, children: [
+ /* @__PURE__ */ jsx4("div", { style: styles.labelRow, children: /* @__PURE__ */ jsx4("label", { style: styles.label, children: text.otpLabel }) }),
+ /* @__PURE__ */ jsx4(
+ "input",
+ {
+ style: styles.input,
+ type: "text",
+ placeholder: text.otpPlaceholder,
+ value: otp,
+ onChange: (e) => setOtp(e.target.value),
+ required: true
+ }
+ )
+ ] }),
/* @__PURE__ */ jsx4(
"button",
{
@@ -709,30 +864,14 @@ var UrAuth = ({
onMouseDown: (e) => e.currentTarget.style.transform = "scale(0.98)",
onMouseUp: (e) => e.currentTarget.style.transform = "scale(1)",
onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)",
- children: isLoading ? "Processing..." : mode === "signin" ? "Log In" : mode === "signup" ? "Create Account" : mode === "forgot" ? "Send Reset Code" : "Reset Password"
+ children: isLoading ? "Processing..." : mode === "signin" ? text.loginButton : mode === "signup" ? text.signupButton : mode === "forgot" ? text.forgotButton : text.resetButton
}
)
] }),
- (mode === "signin" || mode === "signup") && providers && providers.length > 0 && /* @__PURE__ */ jsxs2(Fragment3, { children: [
- /* @__PURE__ */ jsxs2("div", { style: styles.divider, children: [
- /* @__PURE__ */ jsx4("div", { style: styles.dividerLine }),
- /* @__PURE__ */ jsx4("span", { style: styles.dividerText, children: "OR" }),
- /* @__PURE__ */ jsx4("div", { style: styles.dividerLine })
- ] }),
- /* @__PURE__ */ jsxs2("div", { children: [
- providers.includes("google") && /* @__PURE__ */ jsxs2("button", { style: styles.socialBtn, onClick: () => socialLogin("google"), type: "button", children: [
- /* @__PURE__ */ jsx4(GoogleIcon, {}),
- "Continue with Google"
- ] }),
- providers.includes("github") && /* @__PURE__ */ jsxs2("button", { style: styles.socialBtn, onClick: () => socialLogin("github"), type: "button", children: [
- /* @__PURE__ */ jsx4(GithubIcon, {}),
- "Continue with GitHub"
- ] })
- ] })
- ] })
+ (mode === "signin" || mode === "signup") && renderSocialButtons()
] }),
- /* @__PURE__ */ jsxs2("div", { style: styles.footer, children: [
- mode === "signin" ? "Don't have an account yet?" : mode === "signup" ? "Already have an account?" : "Remember your password?",
+ hasPasswordAuth && /* @__PURE__ */ jsxs2("div", { style: styles.footer, children: [
+ footerPrompt,
/* @__PURE__ */ jsx4(
"button",
{
@@ -742,7 +881,7 @@ var UrAuth = ({
setMode(mode === "signin" ? "signup" : "signin");
clearError();
},
- children: mode === "signin" ? "Sign up" : "Log in"
+ children: mode === "signin" ? text.signupTab : text.loginTab
}
)
] })
diff --git a/sdks/urbackend-react/dist/index.mjs.map b/sdks/urbackend-react/dist/index.mjs.map
index 0dec3712..021540d5 100644
--- a/sdks/urbackend-react/dist/index.mjs.map
+++ b/sdks/urbackend-react/dist/index.mjs.map
@@ -1 +1 @@
-{"version":3,"sources":["../src/context.tsx","../src/hooks.ts","../src/components.tsx","../src/components/UrAuth.tsx","../src/components/Toast.tsx","../src/components/UrUserButton.tsx","../src/index.ts"],"sourcesContent":["import React, { createContext, useContext, useEffect, useState, useMemo } from 'react';\r\nimport { UrBackendClient, AuthModule, DatabaseModule, StorageModule } from '@urbackend/sdk';\r\nimport type { AuthUser } from '@urbackend/sdk';\r\n\r\ninterface UrContextValue {\r\n client: UrBackendClient | null;\r\n auth: AuthModule | null;\r\n db: DatabaseModule | null;\r\n storage: StorageModule | null;\r\n user: AuthUser | null;\r\n setUser: React.Dispatch>;\r\n isInitializing: boolean;\r\n isLoading: boolean;\r\n setIsLoading: React.Dispatch>;\r\n error: string | null;\r\n setError: React.Dispatch>;\r\n}\r\n\r\nconst UrContext = createContext(undefined);\r\n\r\nexport interface UrProviderProps {\r\n apiKey: string;\r\n baseUrl?: string;\r\n children: React.ReactNode;\r\n}\r\n\r\nexport const UrProvider: React.FC = ({ apiKey, baseUrl, children }) => {\r\n const [user, setUser] = useState(null);\r\n const [isInitializing, setIsInitializing] = useState(true);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n const { client, auth, db, storage } = useMemo(() => {\r\n const _client = new UrBackendClient({ apiKey, baseUrl });\r\n return {\r\n client: _client,\r\n auth: new AuthModule(_client),\r\n db: new DatabaseModule(_client),\r\n storage: new StorageModule(_client),\r\n };\r\n }, [apiKey, baseUrl]);\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n\r\n const initAuth = async () => {\r\n try {\r\n // Hydrate from localStorage first as a fallback for environments without cookies\r\n if (typeof window !== 'undefined') {\r\n const savedToken = localStorage.getItem('ur_auth_token');\r\n if (savedToken) auth.setToken(savedToken);\r\n }\r\n\r\n // Check for social auth callback params\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hashParams = new URLSearchParams(window.location.hash.substring(1));\r\n const token = hashParams.get('token');\r\n const rtCode = urlParams.get('rtCode');\r\n const error = urlParams.get('error');\r\n\r\n if (error) {\r\n console.error('Social Auth Error:', error);\r\n if (mounted) setError(error);\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else if (token) {\r\n // Social auth succeeded, establish session immediately\r\n auth.setToken(token);\r\n if (typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n \r\n if (rtCode) {\r\n // Exchange for long-lived refresh token\r\n try {\r\n const exRes = await auth.socialExchange({ token, rtCode });\r\n const exToken = (exRes as any).accessToken || (exRes as any).token;\r\n if (exToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', exToken);\r\n } catch (err: any) {\r\n console.error('Failed to exchange refresh token', err);\r\n if (mounted) setError(err.message || 'Failed to complete social login');\r\n throw err;\r\n }\r\n }\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else {\r\n // Attempt to silently refresh session using the HTTP-only cookie\r\n try {\r\n const res = await auth.refreshToken();\r\n const newToken = res.accessToken || (res as any).token;\r\n if (newToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', newToken);\r\n } catch (e) {\r\n // If refresh fails, me() will catch it\r\n }\r\n }\r\n \r\n const currentUser = await auth.me();\r\n if (mounted) {\r\n setUser(currentUser);\r\n }\r\n } catch (error: any) {\r\n if (mounted) {\r\n setUser(null);\r\n // Don't set global error for initial me() check failure (usually just means not logged in)\r\n }\r\n } finally {\r\n if (mounted) {\r\n setIsInitializing(false);\r\n }\r\n }\r\n };\r\n\r\n initAuth();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [auth]);\r\n\r\n const value: UrContextValue = {\r\n client,\r\n auth,\r\n db,\r\n storage,\r\n user,\r\n setUser,\r\n isInitializing,\r\n isLoading,\r\n setIsLoading,\r\n error,\r\n setError,\r\n };\r\n\r\n return {children} ;\r\n};\r\n\r\nexport const useUrContext = () => {\r\n const context = useContext(UrContext);\r\n if (!context) {\r\n throw new Error('useUrContext must be used within an UrProvider');\r\n }\r\n return context;\r\n};\r\n","import { useCallback } from 'react';\r\nimport { useUrContext } from './context';\r\nimport type { \r\n LoginPayload, \r\n SignUpPayload, \r\n ChangePasswordPayload,\r\n VerifyEmailPayload,\r\n RequestPasswordResetPayload,\r\n ResetPasswordPayload\r\n} from '@urbackend/sdk';\r\n\r\nexport const useAuth = () => {\r\n const { auth, user, setUser, isInitializing, isLoading, setIsLoading, error, setError } = useUrContext();\r\n\r\n if (!auth) {\r\n throw new Error('Auth module not initialized. Make sure you are inside UrProvider.');\r\n }\r\n\r\n const login = useCallback(async (payload: LoginPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const res = await auth.login(payload);\r\n const token = res.accessToken || (res as any).token;\r\n if (token && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n const currentUser = await auth.me();\r\n setUser(currentUser);\r\n } catch (err: any) {\r\n setError(err.message || 'Login failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const signUp = useCallback(async (payload: SignUpPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const newUser = await auth.signUp(payload);\r\n return newUser;\r\n } catch (err: any) {\r\n setError(err.message || 'Sign up failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setIsLoading, setError]);\r\n\r\n const logout = useCallback(async () => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n await auth.logout();\r\n if (typeof window !== 'undefined') localStorage.removeItem('ur_auth_token');\r\n setUser(null);\r\n } catch (err: any) {\r\n setError(err.message || 'Logout failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const socialLogin = useCallback((provider: 'google' | 'github') => {\r\n setError(null);\r\n const url = auth.socialStart(provider);\r\n window.location.href = url;\r\n }, [auth, setError]);\r\n \r\n const verifyEmail = useCallback(async (payload: VerifyEmailPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.verifyEmail(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Email verification failed');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const changePassword = useCallback(async (payload: ChangePasswordPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.changePassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to change password');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const requestPasswordReset = useCallback(async (payload: RequestPasswordResetPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.requestPasswordReset(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to request password reset');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const resetPassword = useCallback(async (payload: ResetPasswordPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.resetPassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to reset password');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const clearError = useCallback(() => setError(null), [setError]);\r\n\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n login,\r\n signUp,\r\n logout,\r\n socialLogin,\r\n verifyEmail,\r\n changePassword,\r\n requestPasswordReset,\r\n resetPassword,\r\n clearError,\r\n authApi: auth // Escape hatch to underlying SDK\r\n };\r\n};\r\n\r\nexport const useUser = () => {\r\n const { user, isInitializing, isLoading, error } = useUrContext();\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n };\r\n};\r\n\r\nexport const useDb = () => {\r\n const { db } = useUrContext();\r\n if (!db) {\r\n throw new Error('Database module not initialized.');\r\n }\r\n return db;\r\n};\r\n\r\nexport const useStorage = () => {\r\n const { storage } = useUrContext();\r\n if (!storage) {\r\n throw new Error('Storage module not initialized.');\r\n }\r\n return storage;\r\n};\r\n","import React, { useEffect } from 'react';\r\nimport { useUser } from './hooks';\r\n\r\nexport interface ProtectedRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to be authenticated.\r\n * If the user is not authenticated after initialization, they will be redirected,\r\n * or the fallback will be rendered (or nothing if fallback is not provided and no window redirect occurs).\r\n */\r\nexport const ProtectedRoute: React.FC = ({ \r\n children, \r\n redirectTo = '/login', \r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && !isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (!isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n\r\nexport interface GuestRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to NOT be authenticated (e.g. for Login pages).\r\n * If the user IS authenticated, they will be redirected to the specified route.\r\n */\r\nexport const GuestRoute: React.FC = ({\r\n children,\r\n redirectTo = '/dashboard',\r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n","import React, { useState, useEffect } from 'react';\r\nimport { useAuth } from '../hooks';\r\nimport { Toast } from './Toast';\r\n\r\nexport interface UrAuthProps {\r\n providers?: ('google' | 'github')[];\r\n theme?: 'light' | 'dark'; // Dark mode not perfectly matched to image, but kept for API compat\r\n onSuccess?: () => void;\r\n}\r\n\r\nexport const UrAuth: React.FC = ({ \r\n providers = ['google', 'github'], \r\n theme = 'light',\r\n onSuccess\r\n}) => {\r\n const { login, signUp, socialLogin, requestPasswordReset, resetPassword, isLoading, error, clearError } = useAuth();\r\n const [mode, setMode] = useState<'signin' | 'signup' | 'forgot' | 'reset'>('signin');\r\n const [email, setEmail] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [otp, setOtp] = useState('');\r\n const [name, setName] = useState('');\r\n const [toast, setToast] = useState<{message: string, type: 'success' | 'error'} | null>(null);\r\n\r\n useEffect(() => {\r\n if (error) {\r\n setToast({ message: error, type: 'error' });\r\n }\r\n }, [error]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n if (mode === 'signin') {\r\n await login({ email, password });\r\n setToast({ message: 'Welcome back!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'signup') {\r\n await signUp({ email, password, name });\r\n // Auto-login after signup for convenience\r\n await login({ email, password });\r\n setToast({ message: 'Account created successfully!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'forgot') {\r\n await requestPasswordReset({ email });\r\n setToast({ message: 'Reset code sent to your email', type: 'success' });\r\n setMode('reset');\r\n } else if (mode === 'reset') {\r\n await resetPassword({ email, otp, newPassword: password });\r\n setToast({ message: 'Password reset successfully', type: 'success' });\r\n setMode('signin');\r\n setPassword('');\r\n setOtp('');\r\n }\r\n } catch (err: any) {\r\n // Error is now handled and stored globally by useAuth hook, which triggers the useEffect toast\r\n }\r\n };\r\n\r\n const isDark = theme === 'dark';\r\n const bg = isDark ? '#1a1a1a' : '#ffffff';\r\n const text = isDark ? '#ffffff' : '#0f172a';\r\n const textMuted = isDark ? '#a1a1aa' : '#64748b';\r\n const border = isDark ? '#333' : '#e2e8f0';\r\n const inputBg = isDark ? '#2a2a2a' : '#ffffff';\r\n \r\n const styles = {\r\n wrapper: {\r\n width: '100%',\r\n maxWidth: '420px',\r\n margin: '0 auto',\r\n borderRadius: '0',\r\n background: bg,\r\n boxShadow: isDark ? '0 20px 40px rgba(0,0,0,0.5)' : '0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)',\r\n border: `1px solid ${border}`,\r\n overflow: 'hidden',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n color: text,\r\n },\r\n body: {\r\n padding: '32px 32px 24px 32px',\r\n },\r\n switcherContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n marginBottom: '32px'\r\n },\r\n switcher: {\r\n display: 'inline-flex',\r\n background: isDark ? '#2a2a2a' : '#f1f5f9',\r\n padding: '4px',\r\n borderRadius: '0',\r\n },\r\n switchBtn: (active: boolean) => ({\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n padding: '8px 20px',\r\n borderRadius: '0',\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n color: active ? text : textMuted,\r\n background: active ? (isDark ? '#444' : '#ffffff') : 'transparent',\r\n boxShadow: active ? (isDark ? '0 2px 4px rgba(0,0,0,0.2)' : '0 2px 8px rgba(0,0,0,0.05)') : 'none',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n }),\r\n field: {\r\n marginBottom: '20px',\r\n },\r\n labelRow: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n marginBottom: '8px',\r\n },\r\n label: {\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n color: isDark ? '#ddd' : '#334155',\r\n },\r\n forgotLink: {\r\n fontSize: '12px',\r\n fontWeight: 600,\r\n color: text,\r\n cursor: 'pointer',\r\n textDecoration: 'none',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n borderRadius: '0',\r\n border: `1px solid ${border}`,\r\n background: inputBg,\r\n color: text,\r\n fontSize: '14px',\r\n boxSizing: 'border-box' as const,\r\n outline: 'none',\r\n transition: 'border-color 0.2s ease',\r\n },\r\n primaryBtn: {\r\n width: '100%',\r\n padding: '14px',\r\n borderRadius: '0',\r\n background: 'linear-gradient(180deg, #2a2a2a 0%, #111111 100%)',\r\n color: '#ffffff',\r\n fontSize: '15px',\r\n fontWeight: 600,\r\n border: 'none',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\r\n cursor: 'pointer',\r\n marginTop: '8px',\r\n transition: 'transform 0.1s ease',\r\n },\r\n divider: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n margin: '24px 0',\r\n color: '#94a3b8',\r\n fontSize: '11px',\r\n fontWeight: 600,\r\n letterSpacing: '1px',\r\n },\r\n dividerLine: {\r\n flex: 1,\r\n height: '1px',\r\n background: border,\r\n },\r\n dividerText: {\r\n padding: '0 12px',\r\n },\r\n socialBtn: {\r\n width: '100%',\r\n padding: '12px',\r\n borderRadius: '0',\r\n border: `1px solid ${border}`,\r\n background: isDark ? '#2a2a2a' : '#ffffff',\r\n color: text,\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '10px',\r\n marginBottom: '12px',\r\n cursor: 'pointer',\r\n boxShadow: isDark ? 'none' : '0 1px 2px rgba(0,0,0,0.02)',\r\n transition: 'background 0.2s ease',\r\n },\r\n footer: {\r\n background: isDark ? '#222' : '#f8fafc',\r\n padding: '24px',\r\n textAlign: 'center' as const,\r\n borderTop: `1px solid ${border}`,\r\n fontSize: '13px',\r\n color: textMuted,\r\n },\r\n footerLink: {\r\n color: text,\r\n fontWeight: 600,\r\n textDecoration: 'underline',\r\n cursor: 'pointer',\r\n marginLeft: '4px',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n }\r\n };\r\n\r\n const GoogleIcon = () => (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n\r\n const GithubIcon = () => (\r\n \r\n \r\n \r\n );\r\n\r\n return (\r\n \r\n {toast && (\r\n
{\r\n setToast(null);\r\n if (toast.type === 'error') clearError();\r\n }} \r\n />\r\n )}\r\n \r\n \r\n {(mode === 'signin' || mode === 'signup') && (\r\n
\r\n
\r\n
{ setMode('signin'); clearError(); }}\r\n >\r\n \r\n Login\r\n \r\n
{ setMode('signup'); clearError(); }}\r\n >\r\n \r\n Sign Up\r\n \r\n
\r\n
\r\n )}\r\n\r\n {(mode === 'forgot' || mode === 'reset') && (\r\n
\r\n
\r\n {mode === 'forgot' ? 'Reset Password' : 'Enter Reset Code'}\r\n \r\n
\r\n {mode === 'forgot' ? \"Enter your email and we'll send a code\" : `Enter the code sent to ${email}`}\r\n
\r\n
\r\n )}\r\n\r\n
\r\n\r\n {(mode === 'signin' || mode === 'signup') && providers && providers.length > 0 && (\r\n <>\r\n
\r\n\r\n
\r\n {providers.includes('google') && (\r\n socialLogin('google')} type=\"button\">\r\n \r\n Continue with Google\r\n \r\n )}\r\n {providers.includes('github') && (\r\n socialLogin('github')} type=\"button\">\r\n \r\n Continue with GitHub\r\n \r\n )}\r\n
\r\n >\r\n )}\r\n
\r\n\r\n \r\n {mode === 'signin' ? \"Don't have an account yet?\" \r\n : mode === 'signup' ? \"Already have an account?\"\r\n : \"Remember your password?\"}\r\n {\r\n setMode(mode === 'signin' ? 'signup' : 'signin');\r\n clearError();\r\n }}\r\n >\r\n {mode === 'signin' ? 'Sign up' : 'Log in'}\r\n \r\n
\r\n \r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\n\r\ninterface ToastProps {\r\n message: string;\r\n type: 'success' | 'error';\r\n onClose: () => void;\r\n isDark?: boolean;\r\n}\r\n\r\nexport const Toast: React.FC = ({ message, type, onClose, isDark = false }) => {\r\n const [isVisible, setIsVisible] = useState(false);\r\n const [isLeaving, setIsLeaving] = useState(false);\r\n\r\n useEffect(() => {\r\n // Trigger enter animation on mount\r\n requestAnimationFrame(() => {\r\n setIsVisible(true);\r\n });\r\n\r\n let innerTimer: ReturnType;\r\n const timer = setTimeout(() => {\r\n setIsLeaving(true);\r\n innerTimer = setTimeout(onClose, 300); // Wait for exit animation\r\n }, 4000);\r\n\r\n return () => {\r\n clearTimeout(timer);\r\n if (innerTimer) clearTimeout(innerTimer);\r\n };\r\n }, [onClose]);\r\n\r\n const bgColor = isDark ? 'rgba(30, 30, 30, 0.9)' : 'rgba(255, 255, 255, 0.9)';\r\n const borderColor = type === 'success' ? 'rgba(34, 197, 94, 0.5)' : 'rgba(239, 68, 68, 0.5)';\r\n const iconColor = type === 'success' ? '#22c55e' : '#ef4444';\r\n const textColor = isDark ? '#fff' : '#000';\r\n\r\n return (\r\n <>\r\n \r\n \r\n {type === 'success' ? (\r\n
\r\n \r\n \r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n \r\n )}\r\n {message}\r\n
\r\n >\r\n );\r\n};\r\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useUser, useAuth } from '../hooks';\n\nexport interface UrUserButtonProps {\n /**\n * Shape of the profile avatar. Defaults to 'square' as requested.\n */\n shape?: 'square' | 'circle';\n /**\n * Position of the button on the screen. Defaults to 'top-right'.\n * Use 'inline' if you want to place it within a normal flex/grid layout instead of absolute positioning.\n */\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'inline';\n /**\n * Called when \"Profile\" is clicked.\n */\n onProfileClick?: () => void;\n /**\n * Called when \"Settings\" is clicked.\n */\n onSettingsClick?: () => void;\n /**\n * Z-index for the fixed container. Defaults to 999.\n */\n zIndex?: number;\n}\n\nexport const UrUserButton: React.FC = ({\n shape = 'square',\n position = 'top-right',\n onProfileClick,\n onSettingsClick,\n zIndex = 999,\n}) => {\n const { user } = useUser();\n const { logout } = useAuth();\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n if (!user) return null; // Only render if logged in\n\n const borderRadius = shape === 'circle' ? '50%' : '0px';\n const isFixed = position !== 'inline';\n\n const positionStyles: React.CSSProperties = isFixed\n ? {\n position: 'fixed',\n zIndex,\n top: position.includes('top') ? '24px' : 'auto',\n bottom: position.includes('bottom') ? '24px' : 'auto',\n right: position.includes('right') ? '24px' : 'auto',\n left: position.includes('left') ? '24px' : 'auto',\n }\n : { position: 'relative' };\n\n const dropdownStyles: React.CSSProperties = {\n position: 'absolute',\n top: position.includes('top') || position === 'inline' ? 'calc(100% + 8px)' : 'auto',\n bottom: position.includes('bottom') ? 'calc(100% + 8px)' : 'auto',\n right: position.includes('right') || position === 'inline' ? '0' : 'auto',\n left: position.includes('left') ? '0' : 'auto',\n background: '#ffffff',\n border: '1px solid #e2e8f0',\n borderRadius: '0px',\n boxShadow: '0 10px 25px rgba(0,0,0,0.1)',\n width: '220px',\n display: isOpen ? 'block' : 'none',\n overflow: 'hidden',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n };\n\n const getInitials = () => {\n return user.name?.[0]?.toUpperCase() || user.email?.[0]?.toUpperCase() || 'U';\n };\n\n return (\n \n
setIsOpen(!isOpen)}\n style={{\n width: '40px',\n height: '40px',\n padding: 0,\n border: '1px solid #e2e8f0',\n background: '#f8fafc',\n borderRadius,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n boxShadow: '0 2px 5px rgba(0,0,0,0.05)',\n transition: 'transform 0.1s ease',\n }}\n >\n {user.avatarUrl ? (\n \n ) : (\n \n {getInitials()}\n \n )}\n \n\n
\n {/* User Info Header */}\n
\n
\n {user.name || 'User'}\n
\n
\n {user.email}\n
\n
\n\n {/* Action List */}\n
\n {onProfileClick && (\n
{\n setIsOpen(false);\n onProfileClick();\n }}\n style={{\n width: '100%',\n textAlign: 'left',\n padding: '10px 12px',\n background: 'transparent',\n border: 'none',\n fontSize: '14px',\n color: '#334155',\n cursor: 'pointer',\n borderRadius: '0px',\n display: 'block',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\n >\n Profile\n \n )}\n\n {onSettingsClick && (\n
{\n setIsOpen(false);\n onSettingsClick();\n }}\n style={{\n width: '100%',\n textAlign: 'left',\n padding: '10px 12px',\n background: 'transparent',\n border: 'none',\n fontSize: '14px',\n color: '#334155',\n cursor: 'pointer',\n borderRadius: '0px',\n display: 'block',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\n >\n Settings\n \n )}\n\n
\n\n
{\n setIsOpen(false);\n logout();\n }}\n style={{\n width: '100%',\n textAlign: 'left',\n padding: '10px 12px',\n background: 'transparent',\n border: 'none',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n cursor: 'pointer',\n borderRadius: '0px',\n display: 'block',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.background = '#fef2f2')}\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\n >\n Logout\n \n
\n
\n
\n );\n};\n","export { UrProvider, useUrContext } from './context';\nexport type { UrProviderProps } from './context';\n\nexport { useAuth, useUser, useDb, useStorage } from './hooks';\nexport { ProtectedRoute, GuestRoute } from './components';\nexport type { ProtectedRouteProps, GuestRouteProps } from './components';\n\nexport { UrAuth } from './components/UrAuth';\nexport type { UrAuthProps } from './components/UrAuth';\n\nexport * from './components/UrUserButton';\n\nexport * from '@urbackend/sdk'; // re-export types so users don't need to import from sdk directly"],"mappings":"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","names":["error","useEffect","jsx","useEffect","useState","useEffect","useEffect","useState","Fragment","jsx","Fragment","jsx","jsxs","useState","useEffect","useState","useEffect","jsx","jsxs","useState","useEffect"]}
\ No newline at end of file
+{"version":3,"sources":["../src/context.tsx","../src/hooks.ts","../src/components.tsx","../src/components/UrAuth.tsx","../src/components/Toast.tsx","../src/components/UrUserButton.tsx","../src/index.ts"],"sourcesContent":["import React, { createContext, useContext, useEffect, useState, useMemo } from 'react';\r\nimport { UrBackendClient, AuthModule, DatabaseModule, StorageModule } from '@urbackend/sdk';\r\nimport type { AuthUser } from '@urbackend/sdk';\r\n\r\ninterface UrContextValue {\r\n client: UrBackendClient | null;\r\n auth: AuthModule | null;\r\n db: DatabaseModule | null;\r\n storage: StorageModule | null;\r\n user: AuthUser | null;\r\n setUser: React.Dispatch>;\r\n isInitializing: boolean;\r\n isLoading: boolean;\r\n setIsLoading: React.Dispatch>;\r\n error: string | null;\r\n setError: React.Dispatch>;\r\n}\r\n\r\nconst UrContext = createContext(undefined);\r\n\r\nexport interface UrProviderProps {\r\n apiKey: string;\r\n baseUrl?: string;\r\n children: React.ReactNode;\r\n}\r\n\r\nexport const UrProvider: React.FC = ({ apiKey, baseUrl, children }) => {\r\n const [user, setUser] = useState(null);\r\n const [isInitializing, setIsInitializing] = useState(true);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n const { client, auth, db, storage } = useMemo(() => {\r\n const _client = new UrBackendClient({ apiKey, baseUrl });\r\n return {\r\n client: _client,\r\n auth: new AuthModule(_client),\r\n db: new DatabaseModule(_client),\r\n storage: new StorageModule(_client),\r\n };\r\n }, [apiKey, baseUrl]);\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n\r\n const initAuth = async () => {\r\n try {\r\n // Hydrate from localStorage first as a fallback for environments without cookies\r\n if (typeof window !== 'undefined') {\r\n const savedToken = localStorage.getItem('ur_auth_token');\r\n if (savedToken) auth.setToken(savedToken);\r\n }\r\n\r\n // Check for social auth callback params\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hashParams = new URLSearchParams(window.location.hash.substring(1));\r\n const token = hashParams.get('token');\r\n const rtCode = urlParams.get('rtCode');\r\n const error = urlParams.get('error');\r\n\r\n if (error) {\r\n console.error('Social Auth Error:', error);\r\n if (mounted) setError(error);\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else if (token) {\r\n // Social auth succeeded, establish session immediately\r\n auth.setToken(token);\r\n if (typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n \r\n if (rtCode) {\r\n // Exchange for long-lived refresh token\r\n try {\r\n const exRes = await auth.socialExchange({ token, rtCode });\r\n const exToken = (exRes as any).accessToken || (exRes as any).token;\r\n if (exToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', exToken);\r\n } catch (err: any) {\r\n console.error('Failed to exchange refresh token', err);\r\n if (mounted) setError(err.message || 'Failed to complete social login');\r\n throw err;\r\n }\r\n }\r\n window.history.replaceState({}, document.title, window.location.pathname);\r\n } else {\r\n // Attempt to silently refresh session using the HTTP-only cookie\r\n try {\r\n const res = await auth.refreshToken();\r\n const newToken = res.accessToken || (res as any).token;\r\n if (newToken && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', newToken);\r\n } catch (e) {\r\n // If refresh fails, me() will catch it\r\n }\r\n }\r\n \r\n const currentUser = await auth.me();\r\n if (mounted) {\r\n setUser(currentUser);\r\n }\r\n } catch (error: any) {\r\n if (mounted) {\r\n setUser(null);\r\n // Don't set global error for initial me() check failure (usually just means not logged in)\r\n }\r\n } finally {\r\n if (mounted) {\r\n setIsInitializing(false);\r\n }\r\n }\r\n };\r\n\r\n initAuth();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [auth]);\r\n\r\n const value: UrContextValue = {\r\n client,\r\n auth,\r\n db,\r\n storage,\r\n user,\r\n setUser,\r\n isInitializing,\r\n isLoading,\r\n setIsLoading,\r\n error,\r\n setError,\r\n };\r\n\r\n return {children} ;\r\n};\r\n\r\nexport const useUrContext = () => {\r\n const context = useContext(UrContext);\r\n if (!context) {\r\n throw new Error('useUrContext must be used within an UrProvider');\r\n }\r\n return context;\r\n};\r\n","import { useCallback } from 'react';\r\nimport { useUrContext } from './context';\r\nimport type { \r\n LoginPayload, \r\n SignUpPayload, \r\n ChangePasswordPayload,\r\n VerifyEmailPayload,\r\n RequestPasswordResetPayload,\r\n ResetPasswordPayload\r\n} from '@urbackend/sdk';\r\n\r\nexport const useAuth = () => {\r\n const { auth, user, setUser, isInitializing, isLoading, setIsLoading, error, setError } = useUrContext();\r\n\r\n if (!auth) {\r\n throw new Error('Auth module not initialized. Make sure you are inside UrProvider.');\r\n }\r\n\r\n const login = useCallback(async (payload: LoginPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const res = await auth.login(payload);\r\n const token = res.accessToken || (res as any).token;\r\n if (token && typeof window !== 'undefined') localStorage.setItem('ur_auth_token', token);\r\n const currentUser = await auth.me();\r\n setUser(currentUser);\r\n } catch (err: any) {\r\n setError(err.message || 'Login failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const signUp = useCallback(async (payload: SignUpPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n const newUser = await auth.signUp(payload);\r\n return newUser;\r\n } catch (err: any) {\r\n setError(err.message || 'Sign up failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setIsLoading, setError]);\r\n\r\n const logout = useCallback(async () => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n await auth.logout();\r\n if (typeof window !== 'undefined') localStorage.removeItem('ur_auth_token');\r\n setUser(null);\r\n } catch (err: any) {\r\n setError(err.message || 'Logout failed');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setUser, setIsLoading, setError]);\r\n\r\n const socialLogin = useCallback((provider: 'google' | 'github') => {\r\n setError(null);\r\n const url = auth.socialStart(provider);\r\n window.location.href = url;\r\n }, [auth, setError]);\r\n \r\n const verifyEmail = useCallback(async (payload: VerifyEmailPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.verifyEmail(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Email verification failed');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const changePassword = useCallback(async (payload: ChangePasswordPayload) => {\r\n try {\r\n setError(null);\r\n return await auth.changePassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to change password');\r\n throw err;\r\n }\r\n }, [auth, setError]);\r\n\r\n const requestPasswordReset = useCallback(async (payload: RequestPasswordResetPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.requestPasswordReset(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to request password reset');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const resetPassword = useCallback(async (payload: ResetPasswordPayload) => {\r\n try {\r\n setError(null);\r\n setIsLoading(true);\r\n return await auth.resetPassword(payload);\r\n } catch (err: any) {\r\n setError(err.message || 'Failed to reset password');\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [auth, setError, setIsLoading]);\r\n\r\n const clearError = useCallback(() => setError(null), [setError]);\r\n\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n login,\r\n signUp,\r\n logout,\r\n socialLogin,\r\n verifyEmail,\r\n changePassword,\r\n requestPasswordReset,\r\n resetPassword,\r\n clearError,\r\n authApi: auth // Escape hatch to underlying SDK\r\n };\r\n};\r\n\r\nexport const useUser = () => {\r\n const { user, isInitializing, isLoading, error } = useUrContext();\r\n return {\r\n user,\r\n isInitializing,\r\n isLoading,\r\n error,\r\n isAuthenticated: !!user,\r\n };\r\n};\r\n\r\nexport const useDb = () => {\r\n const { db } = useUrContext();\r\n if (!db) {\r\n throw new Error('Database module not initialized.');\r\n }\r\n return db;\r\n};\r\n\r\nexport const useStorage = () => {\r\n const { storage } = useUrContext();\r\n if (!storage) {\r\n throw new Error('Storage module not initialized.');\r\n }\r\n return storage;\r\n};\r\n","import React, { useEffect } from 'react';\r\nimport { useUser } from './hooks';\r\n\r\nexport interface ProtectedRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to be authenticated.\r\n * If the user is not authenticated after initialization, they will be redirected,\r\n * or the fallback will be rendered (or nothing if fallback is not provided and no window redirect occurs).\r\n */\r\nexport const ProtectedRoute: React.FC = ({ \r\n children, \r\n redirectTo = '/login', \r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && !isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (!isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n\r\nexport interface GuestRouteProps {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n fallback?: React.ReactNode;\r\n onRedirect?: () => void;\r\n}\r\n\r\n/**\r\n * A wrapper component that requires the user to NOT be authenticated (e.g. for Login pages).\r\n * If the user IS authenticated, they will be redirected to the specified route.\r\n */\r\nexport const GuestRoute: React.FC = ({\r\n children,\r\n redirectTo = '/dashboard',\r\n fallback = null,\r\n onRedirect\r\n}) => {\r\n const { isAuthenticated, isInitializing } = useUser();\r\n\r\n useEffect(() => {\r\n if (!isInitializing && isAuthenticated) {\r\n if (onRedirect) {\r\n onRedirect();\r\n } else if (typeof window !== 'undefined') {\r\n window.location.href = redirectTo;\r\n }\r\n }\r\n }, [isAuthenticated, isInitializing, redirectTo, onRedirect]);\r\n\r\n if (isInitializing) {\r\n return fallback;\r\n }\r\n\r\n if (isAuthenticated) {\r\n return fallback;\r\n }\r\n\r\n return <>{children}>;\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\nimport { useAuth } from '../hooks';\r\nimport { Toast } from './Toast';\r\n\r\ntype AuthProvider = 'google' | 'github';\r\ntype ThemeMode = 'light' | 'dark';\r\n\r\ninterface AuthColors {\r\n background: string;\r\n surface: string;\r\n text: string;\r\n textMuted: string;\r\n border: string;\r\n inputBackground: string;\r\n primary: string;\r\n primaryText: string;\r\n footerBackground: string;\r\n dividerText: string;\r\n socialButtonBackground: string;\r\n}\r\n\r\ninterface AuthBranding {\r\n brandName?: string;\r\n appName?: string;\r\n title?: string;\r\n subtitle?: string;\r\n logo?: React.ReactNode | string;\r\n primaryColor?: string;\r\n}\r\n\r\ninterface AuthLabels {\r\n loginTab: string;\r\n signupTab: string;\r\n loginTitle: string;\r\n signupTitle: string;\r\n forgotTitle: string;\r\n resetTitle: string;\r\n loginButton: string;\r\n signupButton: string;\r\n forgotButton: string;\r\n resetButton: string;\r\n emailLabel: string;\r\n emailPlaceholder: string;\r\n passwordLabel: string;\r\n passwordPlaceholder: string;\r\n nameLabel: string;\r\n namePlaceholder: string;\r\n otpLabel: string;\r\n otpPlaceholder: string;\r\n forgotPasswordLink: string;\r\n socialDivider: string;\r\n googleButton: string;\r\n githubButton: string;\r\n footerSigninPrompt: string;\r\n footerSignupPrompt: string;\r\n footerForgotPrompt: string;\r\n noAuthMethods: string;\r\n // Aliases support\r\n signInTitle?: string;\r\n signUpTitle?: string;\r\n signInTab?: string;\r\n signUpTab?: string;\r\n signInButton?: string;\r\n signUpButton?: string;\r\n}\r\n\r\nexport interface UrAuthProps {\r\n providers?: AuthProvider[] | {\r\n google?: boolean;\r\n github?: boolean;\r\n emailPassword?: boolean;\r\n };\r\n enableEmailPassword?: boolean;\r\n theme?: ThemeMode;\r\n colors?: Partial;\r\n branding?: AuthBranding;\r\n labels?: Partial;\r\n onSuccess?: () => void;\r\n}\r\n\r\nconst defaultLabels: AuthLabels = {\r\n loginTab: 'Login',\r\n signupTab: 'Sign Up',\r\n loginTitle: 'Welcome back',\r\n signupTitle: 'Create your account',\r\n forgotTitle: 'Reset Password',\r\n resetTitle: 'Enter Reset Code',\r\n loginButton: 'Log In',\r\n signupButton: 'Create Account',\r\n forgotButton: 'Send Reset Code',\r\n resetButton: 'Reset Password',\r\n emailLabel: 'Email address',\r\n emailPlaceholder: 'Enter your email address',\r\n passwordLabel: 'Password',\r\n passwordPlaceholder: 'Enter your password',\r\n nameLabel: 'Full Name',\r\n namePlaceholder: 'Enter your name',\r\n otpLabel: '6-digit OTP Code',\r\n otpPlaceholder: 'Enter reset code',\r\n forgotPasswordLink: 'Forgot password?',\r\n socialDivider: 'OR',\r\n googleButton: 'Continue with Google',\r\n githubButton: 'Continue with GitHub',\r\n footerSigninPrompt: \"Don't have an account yet?\",\r\n footerSignupPrompt: 'Already have an account?',\r\n footerForgotPrompt: 'Remember your password?',\r\n noAuthMethods: 'No authentication methods are enabled for this screen.',\r\n};\r\n\r\nconst defaultThemeColors: Record = {\r\n light: {\r\n background: '#ffffff',\r\n surface: '#ffffff',\r\n text: '#0f172a',\r\n textMuted: '#64748b',\r\n border: '#e2e8f0',\r\n inputBackground: '#ffffff',\r\n primary: '#111111',\r\n primaryText: '#ffffff',\r\n footerBackground: '#f8fafc',\r\n dividerText: '#94a3b8',\r\n socialButtonBackground: '#ffffff',\r\n },\r\n dark: {\r\n background: '#1a1a1a',\r\n surface: '#1a1a1a',\r\n text: '#ffffff',\r\n textMuted: '#a1a1aa',\r\n border: '#333333',\r\n inputBackground: '#2a2a2a',\r\n primary: '#ffffff',\r\n primaryText: '#111111',\r\n footerBackground: '#222222',\r\n dividerText: '#94a3b8',\r\n socialButtonBackground: '#2a2a2a',\r\n },\r\n};\r\n\r\nexport const UrAuth: React.FC = ({ \r\n providers = ['google', 'github'], \r\n enableEmailPassword = true,\r\n theme = 'light',\r\n colors,\r\n branding,\r\n labels,\r\n onSuccess\r\n}) => {\r\n const { login, signUp, socialLogin, requestPasswordReset, resetPassword, isLoading, error, clearError } = useAuth();\r\n const [mode, setMode] = useState<'signin' | 'signup' | 'forgot' | 'reset'>('signin');\r\n const [email, setEmail] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [otp, setOtp] = useState('');\r\n const [name, setName] = useState('');\r\n const [toast, setToast] = useState<{message: string, type: 'success' | 'error'} | null>(null);\r\n\r\n const text = {\r\n ...defaultLabels,\r\n ...labels,\r\n loginTab: labels?.signInTab || labels?.loginTab || defaultLabels.loginTab,\r\n loginTitle: labels?.signInTitle || labels?.loginTitle || defaultLabels.loginTitle,\r\n loginButton: labels?.signInButton || labels?.loginButton || defaultLabels.loginButton,\r\n signupTab: labels?.signUpTab || labels?.signupTab || defaultLabels.signupTab,\r\n signupTitle: labels?.signUpTitle || labels?.signupTitle || defaultLabels.signupTitle,\r\n signupButton: labels?.signUpButton || labels?.signupButton || defaultLabels.signupButton,\r\n };\r\n\r\n const themeColors = { ...defaultThemeColors[theme], ...colors };\r\n const primaryColor = branding?.primaryColor || themeColors.primary;\r\n\r\n let isGoogleEnabled = true;\r\n let isGithubEnabled = true;\r\n let isEmailPasswordEnabled = enableEmailPassword;\r\n\r\n if (providers) {\r\n if (Array.isArray(providers)) {\r\n isGoogleEnabled = providers.includes('google');\r\n isGithubEnabled = providers.includes('github');\r\n } else if (typeof providers === 'object') {\r\n isGoogleEnabled = !!providers.google;\r\n isGithubEnabled = !!providers.github;\r\n isEmailPasswordEnabled = providers.emailPassword !== undefined ? providers.emailPassword : false;\r\n }\r\n }\r\n\r\n const hasPasswordAuth = isEmailPasswordEnabled;\r\n const hasSocialAuth = isGoogleEnabled || isGithubEnabled;\r\n const brandName = branding?.brandName || branding?.appName || branding?.title || 'urBackend';\r\n const headerTitle = branding?.title || brandName;\r\n const headerSubtitle = branding?.subtitle || (mode === 'signin'\r\n ? text.loginTitle\r\n : mode === 'signup'\r\n ? text.signupTitle\r\n : mode === 'forgot'\r\n ? text.forgotTitle\r\n : text.resetTitle);\r\n const showSwitcher = hasPasswordAuth;\r\n\r\n useEffect(() => {\r\n if (error) {\r\n setToast({ message: error, type: 'error' });\r\n }\r\n }, [error]);\r\n\r\n useEffect(() => {\r\n if (!hasPasswordAuth && mode !== 'signin') {\r\n setMode('signin');\r\n }\r\n }, [hasPasswordAuth, mode]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n if (mode === 'signin') {\r\n await login({ email, password });\r\n setToast({ message: 'Welcome back!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'signup') {\r\n await signUp({ email, password, name });\r\n await login({ email, password });\r\n setToast({ message: 'Account created successfully!', type: 'success' });\r\n if (onSuccess) onSuccess();\r\n } else if (mode === 'forgot') {\r\n await requestPasswordReset({ email });\r\n setToast({ message: 'Reset code sent to your email', type: 'success' });\r\n setMode('reset');\r\n } else if (mode === 'reset') {\r\n await resetPassword({ email, otp, newPassword: password });\r\n setToast({ message: 'Password reset successfully', type: 'success' });\r\n setMode('signin');\r\n setPassword('');\r\n setOtp('');\r\n }\r\n } catch (err: any) {\r\n // Errors are surfaced via the shared auth hook state.\r\n }\r\n };\r\n\r\n const styles = {\r\n wrapper: {\r\n width: '100%',\r\n maxWidth: '420px',\r\n margin: '0 auto',\r\n borderRadius: '0',\r\n background: themeColors.background,\r\n boxShadow: theme === 'dark' ? '0 20px 40px rgba(0,0,0,0.5)' : '0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)',\r\n border: `1px solid ${themeColors.border}`,\r\n overflow: 'hidden',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n color: themeColors.text,\r\n },\r\n body: {\r\n padding: '32px 32px 24px 32px',\r\n },\r\n header: {\r\n textAlign: 'center' as const,\r\n marginBottom: '28px',\r\n },\r\n brandRow: {\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n gap: '12px',\r\n marginBottom: '10px',\r\n },\r\n brandLogo: {\r\n width: '44px',\r\n height: '44px',\r\n borderRadius: '12px',\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n background: theme === 'dark' ? '#2a2a2a' : '#f1f5f9',\r\n color: themeColors.text,\r\n overflow: 'hidden' as const,\r\n },\r\n brandTitle: {\r\n margin: 0,\r\n fontSize: '26px',\r\n lineHeight: 1.1,\r\n fontWeight: 800,\r\n color: themeColors.text,\r\n },\r\n brandSubtitle: {\r\n margin: '0 auto',\r\n maxWidth: '320px',\r\n fontSize: '14px',\r\n lineHeight: 1.5,\r\n color: themeColors.textMuted,\r\n },\r\n switcherContainer: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n marginBottom: '32px'\r\n },\r\n switcher: {\r\n display: 'inline-flex',\r\n background: theme === 'dark' ? '#2a2a2a' : '#f1f5f9',\r\n padding: '4px',\r\n borderRadius: '0',\r\n },\r\n switchBtn: (active: boolean) => ({\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n padding: '8px 20px',\r\n borderRadius: '0',\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n color: active ? themeColors.text : themeColors.textMuted,\r\n background: active ? (theme === 'dark' ? '#444444' : '#ffffff') : 'transparent',\r\n boxShadow: active ? (theme === 'dark' ? '0 2px 4px rgba(0,0,0,0.2)' : '0 2px 8px rgba(0,0,0,0.05)') : 'none',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n }),\r\n field: {\r\n marginBottom: '20px',\r\n },\r\n labelRow: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n marginBottom: '8px',\r\n },\r\n label: {\r\n fontSize: '13px',\r\n fontWeight: 600,\r\n color: theme === 'dark' ? '#dddddd' : '#334155',\r\n },\r\n forgotLink: {\r\n fontSize: '12px',\r\n fontWeight: 600,\r\n color: themeColors.text,\r\n cursor: 'pointer',\r\n textDecoration: 'none',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n borderRadius: '0',\r\n border: `1px solid ${themeColors.border}`,\r\n background: themeColors.inputBackground,\r\n color: themeColors.text,\r\n fontSize: '14px',\r\n boxSizing: 'border-box' as const,\r\n outline: 'none',\r\n transition: 'border-color 0.2s ease',\r\n },\r\n primaryBtn: {\r\n width: '100%',\r\n padding: '14px',\r\n borderRadius: '0',\r\n background: `linear-gradient(180deg, ${primaryColor} 0%, ${theme === 'dark' ? '#111111' : '#111111'} 100%)`,\r\n color: themeColors.primaryText,\r\n fontSize: '15px',\r\n fontWeight: 600,\r\n border: 'none',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\r\n cursor: 'pointer',\r\n marginTop: '8px',\r\n transition: 'transform 0.1s ease',\r\n },\r\n divider: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n margin: '24px 0',\r\n color: themeColors.dividerText,\r\n fontSize: '11px',\r\n fontWeight: 600,\r\n letterSpacing: '1px',\r\n },\r\n dividerLine: {\r\n flex: 1,\r\n height: '1px',\r\n background: themeColors.border,\r\n },\r\n dividerText: {\r\n padding: '0 12px',\r\n },\r\n socialBtn: {\r\n width: '100%',\r\n padding: '12px',\r\n borderRadius: '0',\r\n border: `1px solid ${themeColors.border}`,\r\n background: themeColors.socialButtonBackground,\r\n color: themeColors.text,\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '10px',\r\n marginBottom: '12px',\r\n cursor: 'pointer',\r\n boxShadow: theme === 'dark' ? 'none' : '0 1px 2px rgba(0,0,0,0.02)',\r\n transition: 'background 0.2s ease',\r\n },\r\n footer: {\r\n background: themeColors.footerBackground,\r\n padding: '24px',\r\n textAlign: 'center' as const,\r\n borderTop: `1px solid ${themeColors.border}`,\r\n fontSize: '13px',\r\n color: themeColors.textMuted,\r\n },\r\n footerLink: {\r\n color: themeColors.text,\r\n fontWeight: 600,\r\n textDecoration: 'underline',\r\n cursor: 'pointer',\r\n marginLeft: '4px',\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n }\r\n };\r\n\r\n const GoogleIcon = () => (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n\r\n const GithubIcon = () => (\r\n \r\n \r\n \r\n );\r\n\r\n const renderSocialButtons = () => {\r\n if (!hasSocialAuth) {\r\n return null;\r\n }\r\n\r\n return (\r\n <>\r\n {hasPasswordAuth && (\r\n \r\n
\r\n
{text.socialDivider} \r\n
\r\n
\r\n )}\r\n\r\n \r\n {isGoogleEnabled && (\r\n socialLogin('google')} type=\"button\">\r\n \r\n {text.googleButton}\r\n \r\n )}\r\n {isGithubEnabled && (\r\n socialLogin('github')} type=\"button\">\r\n \r\n {text.githubButton}\r\n \r\n )}\r\n
\r\n >\r\n );\r\n };\r\n\r\n const footerPrompt = mode === 'signin'\r\n ? text.footerSigninPrompt\r\n : mode === 'signup'\r\n ? text.footerSignupPrompt\r\n : text.footerForgotPrompt;\r\n\r\n return (\r\n \r\n {toast && (\r\n
{\r\n setToast(null);\r\n if (toast.type === 'error') clearError();\r\n }} \r\n />\r\n )}\r\n \r\n \r\n {(branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle || headerTitle || headerSubtitle) && (\r\n
\r\n
\r\n {branding?.logo ? (\r\n
\r\n {typeof branding.logo === 'string' ? (\r\n
\r\n ) : (\r\n branding.logo\r\n )}\r\n
\r\n ) : (\r\n
\r\n {brandName.slice(0, 1).toUpperCase()}\r\n
\r\n )}\r\n
\r\n
{headerTitle} \r\n
{headerSubtitle}
\r\n
\r\n )}\r\n\r\n {showSwitcher && (mode === 'signin' || mode === 'signup') && (\r\n
\r\n
\r\n
{ setMode('signin'); clearError(); }}\r\n >\r\n \r\n {text.loginTab}\r\n \r\n
{ setMode('signup'); clearError(); }}\r\n >\r\n \r\n {text.signupTab}\r\n \r\n
\r\n
\r\n )}\r\n\r\n {(mode === 'forgot' || mode === 'reset') && (\r\n
\r\n
\r\n {mode === 'forgot' ? text.forgotTitle : text.resetTitle}\r\n \r\n
\r\n {mode === 'forgot' ? text.loginTitle : `Enter the code sent to ${email}`}\r\n
\r\n
\r\n )}\r\n\r\n {!hasPasswordAuth && !hasSocialAuth && (\r\n
\r\n {text.noAuthMethods}\r\n
\r\n )}\r\n\r\n {hasPasswordAuth && (\r\n
\r\n )}\r\n\r\n {(mode === 'signin' || mode === 'signup') && renderSocialButtons()}\r\n
\r\n\r\n {hasPasswordAuth && (\r\n \r\n {footerPrompt}\r\n {\r\n setMode(mode === 'signin' ? 'signup' : 'signin');\r\n clearError();\r\n }}\r\n >\r\n {mode === 'signin' ? text.signupTab : text.loginTab}\r\n \r\n
\r\n )}\r\n \r\n );\r\n};\r\n","import React, { useEffect, useState } from 'react';\r\n\r\ninterface ToastProps {\r\n message: string;\r\n type: 'success' | 'error';\r\n onClose: () => void;\r\n isDark?: boolean;\r\n}\r\n\r\nexport const Toast: React.FC = ({ message, type, onClose, isDark = false }) => {\r\n const [isVisible, setIsVisible] = useState(false);\r\n const [isLeaving, setIsLeaving] = useState(false);\r\n\r\n useEffect(() => {\r\n // Trigger enter animation on mount\r\n requestAnimationFrame(() => {\r\n setIsVisible(true);\r\n });\r\n\r\n let innerTimer: ReturnType;\r\n const timer = setTimeout(() => {\r\n setIsLeaving(true);\r\n innerTimer = setTimeout(onClose, 300); // Wait for exit animation\r\n }, 4000);\r\n\r\n return () => {\r\n clearTimeout(timer);\r\n if (innerTimer) clearTimeout(innerTimer);\r\n };\r\n }, [onClose]);\r\n\r\n const bgColor = isDark ? 'rgba(30, 30, 30, 0.9)' : 'rgba(255, 255, 255, 0.9)';\r\n const borderColor = type === 'success' ? 'rgba(34, 197, 94, 0.5)' : 'rgba(239, 68, 68, 0.5)';\r\n const iconColor = type === 'success' ? '#22c55e' : '#ef4444';\r\n const textColor = isDark ? '#fff' : '#000';\r\n\r\n return (\r\n <>\r\n \r\n \r\n {type === 'success' ? (\r\n
\r\n \r\n \r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n \r\n )}\r\n {message}\r\n
\r\n >\r\n );\r\n};\r\n","import React, { useState, useRef, useEffect } from 'react';\r\nimport { useUser, useAuth } from '../hooks';\r\n\r\nexport interface UrUserButtonProps {\r\n /**\r\n * Shape of the profile avatar. Defaults to 'square' as requested.\r\n */\r\n shape?: 'square' | 'circle';\r\n /**\r\n * Position of the button on the screen. Defaults to 'top-right'.\r\n * Use 'inline' if you want to place it within a normal flex/grid layout instead of absolute positioning.\r\n */\r\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'inline';\r\n /**\r\n * Called when \"Profile\" is clicked.\r\n */\r\n onProfileClick?: () => void;\r\n /**\r\n * Called when \"Settings\" is clicked.\r\n */\r\n onSettingsClick?: () => void;\r\n /**\r\n * Z-index for the fixed container. Defaults to 999.\r\n */\r\n zIndex?: number;\r\n}\r\n\r\nexport const UrUserButton: React.FC = ({\r\n shape = 'square',\r\n position = 'top-right',\r\n onProfileClick,\r\n onSettingsClick,\r\n zIndex = 999,\r\n}) => {\r\n const { user } = useUser();\r\n const { logout } = useAuth();\r\n const [isOpen, setIsOpen] = useState(false);\r\n const containerRef = useRef(null);\r\n\r\n useEffect(() => {\r\n const handleClickOutside = (event: MouseEvent) => {\r\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\r\n setIsOpen(false);\r\n }\r\n };\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => document.removeEventListener('mousedown', handleClickOutside);\r\n }, []);\r\n\r\n if (!user) return null; // Only render if logged in\r\n\r\n const borderRadius = shape === 'circle' ? '50%' : '0px';\r\n const isFixed = position !== 'inline';\r\n\r\n const positionStyles: React.CSSProperties = isFixed\r\n ? {\r\n position: 'fixed',\r\n zIndex,\r\n top: position.includes('top') ? '24px' : 'auto',\r\n bottom: position.includes('bottom') ? '24px' : 'auto',\r\n right: position.includes('right') ? '24px' : 'auto',\r\n left: position.includes('left') ? '24px' : 'auto',\r\n }\r\n : { position: 'relative' };\r\n\r\n const dropdownStyles: React.CSSProperties = {\r\n position: 'absolute',\r\n top: position.includes('top') || position === 'inline' ? 'calc(100% + 8px)' : 'auto',\r\n bottom: position.includes('bottom') ? 'calc(100% + 8px)' : 'auto',\r\n right: position.includes('right') || position === 'inline' ? '0' : 'auto',\r\n left: position.includes('left') ? '0' : 'auto',\r\n background: '#ffffff',\r\n border: '1px solid #e2e8f0',\r\n borderRadius: '0px',\r\n boxShadow: '0 10px 25px rgba(0,0,0,0.1)',\r\n width: '220px',\r\n display: isOpen ? 'block' : 'none',\r\n overflow: 'hidden',\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n };\r\n\r\n const getInitials = () => {\r\n return user.name?.[0]?.toUpperCase() || user.email?.[0]?.toUpperCase() || 'U';\r\n };\r\n\r\n return (\r\n \r\n
setIsOpen(!isOpen)}\r\n style={{\r\n width: '40px',\r\n height: '40px',\r\n padding: 0,\r\n border: '1px solid #e2e8f0',\r\n background: '#f8fafc',\r\n borderRadius,\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n overflow: 'hidden',\r\n boxShadow: '0 2px 5px rgba(0,0,0,0.05)',\r\n transition: 'transform 0.1s ease',\r\n }}\r\n >\r\n {user.avatarUrl ? (\r\n \r\n ) : (\r\n \r\n {getInitials()}\r\n \r\n )}\r\n \r\n\r\n
\r\n {/* User Info Header */}\r\n
\r\n
\r\n {user.name || 'User'}\r\n
\r\n
\r\n {user.email}\r\n
\r\n
\r\n\r\n {/* Action List */}\r\n
\r\n {onProfileClick && (\r\n
{\r\n setIsOpen(false);\r\n onProfileClick();\r\n }}\r\n style={{\r\n width: '100%',\r\n textAlign: 'left',\r\n padding: '10px 12px',\r\n background: 'transparent',\r\n border: 'none',\r\n fontSize: '14px',\r\n color: '#334155',\r\n cursor: 'pointer',\r\n borderRadius: '0px',\r\n display: 'block',\r\n }}\r\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\r\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\r\n >\r\n Profile\r\n \r\n )}\r\n\r\n {onSettingsClick && (\r\n
{\r\n setIsOpen(false);\r\n onSettingsClick();\r\n }}\r\n style={{\r\n width: '100%',\r\n textAlign: 'left',\r\n padding: '10px 12px',\r\n background: 'transparent',\r\n border: 'none',\r\n fontSize: '14px',\r\n color: '#334155',\r\n cursor: 'pointer',\r\n borderRadius: '0px',\r\n display: 'block',\r\n }}\r\n onMouseEnter={(e) => (e.currentTarget.style.background = '#f1f5f9')}\r\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\r\n >\r\n Settings\r\n \r\n )}\r\n\r\n
\r\n\r\n
{\r\n setIsOpen(false);\r\n logout();\r\n }}\r\n style={{\r\n width: '100%',\r\n textAlign: 'left',\r\n padding: '10px 12px',\r\n background: 'transparent',\r\n border: 'none',\r\n fontSize: '14px',\r\n color: '#ef4444',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n borderRadius: '0px',\r\n display: 'block',\r\n }}\r\n onMouseEnter={(e) => (e.currentTarget.style.background = '#fef2f2')}\r\n onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}\r\n >\r\n Logout\r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","export { UrProvider, useUrContext } from './context';\r\nexport type { UrProviderProps } from './context';\r\n\r\nexport { useAuth, useUser, useDb, useStorage } from './hooks';\r\nexport { ProtectedRoute, GuestRoute } from './components';\r\nexport type { ProtectedRouteProps, GuestRouteProps } from './components';\r\n\r\nexport { UrAuth } from './components/UrAuth';\r\nexport type { UrAuthProps } from './components/UrAuth';\r\n\r\nexport * from './components/UrUserButton';\r\n\r\nexport * from '@urbackend/sdk'; // re-export types so users don't need to import from sdk directly"],"mappings":"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","names":["error","useEffect","jsx","useEffect","useEffect","useState","useEffect","useState","Fragment","jsx","Fragment","jsx","jsxs","useState","useEffect","useState","useEffect","jsx","jsxs","useState","useEffect"]}
\ No newline at end of file
diff --git a/sdks/urbackend-react/src/components/UrAuth.tsx b/sdks/urbackend-react/src/components/UrAuth.tsx
index 0c7cf91f..6754675c 100644
--- a/sdks/urbackend-react/src/components/UrAuth.tsx
+++ b/sdks/urbackend-react/src/components/UrAuth.tsx
@@ -1,16 +1,183 @@
-import React, { useState, useEffect } from 'react';
+import React, { useEffect, useState } from 'react';
import { useAuth } from '../hooks';
import { Toast } from './Toast';
+type AuthProvider = 'google' | 'github';
+type ThemeMode = 'light' | 'dark';
+
+interface AuthColors {
+ background: string;
+ surface: string;
+ text: string;
+ textMuted: string;
+ border: string;
+ inputBackground: string;
+ primary: string;
+ primaryText: string;
+ footerBackground: string;
+ dividerText: string;
+ socialButtonBackground: string;
+}
+
+interface AuthBranding {
+ brandName?: string;
+ appName?: string;
+ title?: string;
+ subtitle?: string;
+ logo?: React.ReactNode | string;
+ primaryColor?: string;
+}
+
+interface AuthLabels {
+ loginTab: string;
+ signupTab: string;
+ loginTitle: string;
+ signupTitle: string;
+ forgotTitle: string;
+ resetTitle: string;
+ loginButton: string;
+ signupButton: string;
+ forgotButton: string;
+ resetButton: string;
+ emailLabel: string;
+ emailPlaceholder: string;
+ passwordLabel: string;
+ passwordPlaceholder: string;
+ nameLabel: string;
+ namePlaceholder: string;
+ otpLabel: string;
+ otpPlaceholder: string;
+ forgotPasswordLink: string;
+ socialDivider: string;
+ googleButton: string;
+ githubButton: string;
+ footerSigninPrompt: string;
+ footerSignupPrompt: string;
+ footerForgotPrompt: string;
+ noAuthMethods: string;
+ forgotSubtitle: string;
+ resetSubtitle: string;
+ // Aliases support
+ signInTitle?: string;
+ signUpTitle?: string;
+ signInTab?: string;
+ signUpTab?: string;
+ signInButton?: string;
+ signUpButton?: string;
+}
+
export interface UrAuthProps {
- providers?: ('google' | 'github')[];
- theme?: 'light' | 'dark'; // Dark mode not perfectly matched to image, but kept for API compat
+ providers?: AuthProvider[] | {
+ google?: boolean;
+ github?: boolean;
+ emailPassword?: boolean;
+ };
+ enableEmailPassword?: boolean;
+ theme?: ThemeMode;
+ colors?: Partial;
+ branding?: AuthBranding;
+ labels?: Partial;
onSuccess?: () => void;
}
+const defaultLabels: AuthLabels = {
+ loginTab: 'Login',
+ signupTab: 'Sign Up',
+ loginTitle: 'Welcome back',
+ signupTitle: 'Create your account',
+ forgotTitle: 'Reset Password',
+ resetTitle: 'Enter Reset Code',
+ loginButton: 'Log In',
+ signupButton: 'Create Account',
+ forgotButton: 'Send Reset Code',
+ resetButton: 'Reset Password',
+ emailLabel: 'Email address',
+ emailPlaceholder: 'Enter your email address',
+ passwordLabel: 'Password',
+ passwordPlaceholder: 'Enter your password',
+ nameLabel: 'Full Name',
+ namePlaceholder: 'Enter your name',
+ otpLabel: '6-digit OTP Code',
+ otpPlaceholder: 'Enter reset code',
+ forgotPasswordLink: 'Forgot password?',
+ socialDivider: 'OR',
+ googleButton: 'Continue with Google',
+ githubButton: 'Continue with GitHub',
+ footerSigninPrompt: "Don't have an account yet?",
+ footerSignupPrompt: 'Already have an account?',
+ footerForgotPrompt: 'Remember your password?',
+ noAuthMethods: 'No authentication methods are enabled for this screen.',
+ forgotSubtitle: 'Welcome back',
+ resetSubtitle: 'Enter the code sent to {email}',
+};
+
+const defaultThemeColors: Record = {
+ light: {
+ background: '#ffffff',
+ surface: '#ffffff',
+ text: '#0f172a',
+ textMuted: '#64748b',
+ border: '#e2e8f0',
+ inputBackground: '#ffffff',
+ primary: '#111111',
+ primaryText: '#ffffff',
+ footerBackground: '#f8fafc',
+ dividerText: '#94a3b8',
+ socialButtonBackground: '#ffffff',
+ },
+ dark: {
+ background: '#1a1a1a',
+ surface: '#1a1a1a',
+ text: '#ffffff',
+ textMuted: '#a1a1aa',
+ border: '#333333',
+ inputBackground: '#2a2a2a',
+ primary: '#ffffff',
+ primaryText: '#111111',
+ footerBackground: '#222222',
+ dividerText: '#94a3b8',
+ socialButtonBackground: '#2a2a2a',
+ },
+};
+
+// Helper to adjust brightness of hex colors for professional gradient stops
+const adjustColor = (color: string, percent: number) => {
+ try {
+ if (color.startsWith('#')) {
+ let hex = color.replace('#', '');
+ if (hex.length === 3) {
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
+ }
+ let r = parseInt(hex.substring(0, 2), 16);
+ let g = parseInt(hex.substring(2, 4), 16);
+ let b = parseInt(hex.substring(4, 6), 16);
+
+ r = Math.min(255, Math.max(0, r + percent));
+ g = Math.min(255, Math.max(0, g + percent));
+ b = Math.min(255, Math.max(0, b + percent));
+
+ const rr = r.toString(16).padStart(2, '0');
+ const gg = g.toString(16).padStart(2, '0');
+ const bb = b.toString(16).padStart(2, '0');
+
+ return `#${rr}${gg}${bb}`;
+ }
+ } catch (e) {
+ // Safe fallback to original color
+ }
+ return color;
+};
+
+
+
+
export const UrAuth: React.FC = ({
providers = ['google', 'github'],
+ enableEmailPassword = true,
theme = 'light',
+ colors,
+ branding,
+ labels,
onSuccess
}) => {
const { login, signUp, socialLogin, requestPasswordReset, resetPassword, isLoading, error, clearError } = useAuth();
@@ -21,12 +188,61 @@ export const UrAuth: React.FC = ({
const [name, setName] = useState('');
const [toast, setToast] = useState<{message: string, type: 'success' | 'error'} | null>(null);
+ const text = {
+ ...defaultLabels,
+ ...labels,
+ loginTab: labels?.signInTab ?? labels?.loginTab ?? defaultLabels.loginTab,
+ loginTitle: labels?.signInTitle ?? labels?.loginTitle ?? defaultLabels.loginTitle,
+ loginButton: labels?.signInButton ?? labels?.loginButton ?? defaultLabels.loginButton,
+ signupTab: labels?.signUpTab ?? labels?.signupTab ?? defaultLabels.signupTab,
+ signupTitle: labels?.signUpTitle ?? labels?.signupTitle ?? defaultLabels.signupTitle,
+ signupButton: labels?.signUpButton ?? labels?.signupButton ?? defaultLabels.signupButton,
+};
+
+ const themeColors = { ...defaultThemeColors[theme], ...colors };
+ const primaryColor = branding?.primaryColor || themeColors.primary;
+ const secondStopColor = adjustColor(primaryColor, -15);
+
+ let isGoogleEnabled = true;
+ let isGithubEnabled = true;
+ let isEmailPasswordEnabled = enableEmailPassword;
+
+ if (providers) {
+ if (Array.isArray(providers)) {
+ isGoogleEnabled = providers.includes('google');
+ isGithubEnabled = providers.includes('github');
+ } else if (typeof providers === 'object') {
+ isGoogleEnabled = !!providers.google;
+ isGithubEnabled = !!providers.github;
+ isEmailPasswordEnabled = providers.emailPassword !== undefined ? providers.emailPassword : enableEmailPassword;
+ }
+ }
+
+ const hasPasswordAuth = isEmailPasswordEnabled;
+ const hasSocialAuth = isGoogleEnabled || isGithubEnabled;
+ const brandName = branding?.brandName || branding?.appName || branding?.title || 'urBackend';
+ const headerTitle = branding?.title || brandName;
+ const headerSubtitle = branding?.subtitle || (mode === 'signin'
+ ? text.loginTitle
+ : mode === 'signup'
+ ? text.signupTitle
+ : mode === 'forgot'
+ ? text.forgotTitle
+ : text.resetTitle);
+ const showSwitcher = hasPasswordAuth;
+
useEffect(() => {
if (error) {
setToast({ message: error, type: 'error' });
}
}, [error]);
+ useEffect(() => {
+ if (!hasPasswordAuth && mode !== 'signin') {
+ setMode('signin');
+ }
+ }, [hasPasswordAuth, mode]);
+
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
@@ -36,7 +252,6 @@ export const UrAuth: React.FC = ({
if (onSuccess) onSuccess();
} else if (mode === 'signup') {
await signUp({ email, password, name });
- // Auto-login after signup for convenience
await login({ email, password });
setToast({ message: 'Account created successfully!', type: 'success' });
if (onSuccess) onSuccess();
@@ -52,33 +267,62 @@ export const UrAuth: React.FC = ({
setOtp('');
}
} catch (err: any) {
- // Error is now handled and stored globally by useAuth hook, which triggers the useEffect toast
+ // Errors are surfaced via the shared auth hook state.
}
};
- const isDark = theme === 'dark';
- const bg = isDark ? '#1a1a1a' : '#ffffff';
- const text = isDark ? '#ffffff' : '#0f172a';
- const textMuted = isDark ? '#a1a1aa' : '#64748b';
- const border = isDark ? '#333' : '#e2e8f0';
- const inputBg = isDark ? '#2a2a2a' : '#ffffff';
-
const styles = {
wrapper: {
width: '100%',
maxWidth: '420px',
margin: '0 auto',
borderRadius: '0',
- background: bg,
- boxShadow: isDark ? '0 20px 40px rgba(0,0,0,0.5)' : '0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)',
- border: `1px solid ${border}`,
+ background: themeColors.background,
+ boxShadow: theme === 'dark' ? '0 20px 40px rgba(0,0,0,0.5)' : '0 20px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.05)',
+ border: `1px solid ${themeColors.border}`,
overflow: 'hidden',
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
- color: text,
+ color: themeColors.text,
},
body: {
padding: '32px 32px 24px 32px',
},
+ header: {
+ textAlign: 'center' as const,
+ marginBottom: '28px',
+ },
+ brandRow: {
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ gap: '12px',
+ marginBottom: '10px',
+ },
+ brandLogo: {
+ width: '44px',
+ height: '44px',
+ borderRadius: '12px',
+ display: 'inline-flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ background: theme === 'dark' ? '#2a2a2a' : '#f1f5f9',
+ color: themeColors.text,
+ overflow: 'hidden' as const,
+ },
+ brandTitle: {
+ margin: 0,
+ fontSize: '26px',
+ lineHeight: 1.1,
+ fontWeight: 800,
+ color: themeColors.text,
+ },
+ brandSubtitle: {
+ margin: '0 auto',
+ maxWidth: '320px',
+ fontSize: '14px',
+ lineHeight: 1.5,
+ color: themeColors.textMuted,
+ },
switcherContainer: {
display: 'flex',
alignItems: 'center',
@@ -87,7 +331,7 @@ export const UrAuth: React.FC = ({
},
switcher: {
display: 'inline-flex',
- background: isDark ? '#2a2a2a' : '#f1f5f9',
+ background: theme === 'dark' ? '#2a2a2a' : '#f1f5f9',
padding: '4px',
borderRadius: '0',
},
@@ -100,9 +344,9 @@ export const UrAuth: React.FC = ({
fontSize: '13px',
fontWeight: 600,
cursor: 'pointer',
- color: active ? text : textMuted,
- background: active ? (isDark ? '#444' : '#ffffff') : 'transparent',
- boxShadow: active ? (isDark ? '0 2px 4px rgba(0,0,0,0.2)' : '0 2px 8px rgba(0,0,0,0.05)') : 'none',
+ color: active ? themeColors.text : themeColors.textMuted,
+ background: active ? (theme === 'dark' ? '#444444' : '#ffffff') : 'transparent',
+ boxShadow: active ? (theme === 'dark' ? '0 2px 4px rgba(0,0,0,0.2)' : '0 2px 8px rgba(0,0,0,0.05)') : 'none',
border: 'none',
transition: 'all 0.2s ease',
}),
@@ -118,12 +362,12 @@ export const UrAuth: React.FC = ({
label: {
fontSize: '13px',
fontWeight: 600,
- color: isDark ? '#ddd' : '#334155',
+ color: theme === 'dark' ? '#dddddd' : '#334155',
},
forgotLink: {
fontSize: '12px',
fontWeight: 600,
- color: text,
+ color: themeColors.text,
cursor: 'pointer',
textDecoration: 'none',
background: 'none',
@@ -134,9 +378,9 @@ export const UrAuth: React.FC = ({
width: '100%',
padding: '12px 16px',
borderRadius: '0',
- border: `1px solid ${border}`,
- background: inputBg,
- color: text,
+ border: `1px solid ${themeColors.border}`,
+ background: themeColors.inputBackground,
+ color: themeColors.text,
fontSize: '14px',
boxSizing: 'border-box' as const,
outline: 'none',
@@ -146,8 +390,8 @@ export const UrAuth: React.FC = ({
width: '100%',
padding: '14px',
borderRadius: '0',
- background: 'linear-gradient(180deg, #2a2a2a 0%, #111111 100%)',
- color: '#ffffff',
+ background: `linear-gradient(180deg, ${primaryColor} 0%, ${secondStopColor} 100%)`,
+ color: themeColors.primaryText,
fontSize: '15px',
fontWeight: 600,
border: 'none',
@@ -160,7 +404,7 @@ export const UrAuth: React.FC = ({
display: 'flex',
alignItems: 'center',
margin: '24px 0',
- color: '#94a3b8',
+ color: themeColors.dividerText,
fontSize: '11px',
fontWeight: 600,
letterSpacing: '1px',
@@ -168,7 +412,7 @@ export const UrAuth: React.FC = ({
dividerLine: {
flex: 1,
height: '1px',
- background: border,
+ background: themeColors.border,
},
dividerText: {
padding: '0 12px',
@@ -177,9 +421,9 @@ export const UrAuth: React.FC = ({
width: '100%',
padding: '12px',
borderRadius: '0',
- border: `1px solid ${border}`,
- background: isDark ? '#2a2a2a' : '#ffffff',
- color: text,
+ border: `1px solid ${themeColors.border}`,
+ background: themeColors.socialButtonBackground,
+ color: themeColors.text,
fontSize: '14px',
fontWeight: 600,
display: 'flex',
@@ -188,19 +432,19 @@ export const UrAuth: React.FC = ({
gap: '10px',
marginBottom: '12px',
cursor: 'pointer',
- boxShadow: isDark ? 'none' : '0 1px 2px rgba(0,0,0,0.02)',
+ boxShadow: theme === 'dark' ? 'none' : '0 1px 2px rgba(0,0,0,0.02)',
transition: 'background 0.2s ease',
},
footer: {
- background: isDark ? '#222' : '#f8fafc',
+ background: themeColors.footerBackground,
padding: '24px',
textAlign: 'center' as const,
- borderTop: `1px solid ${border}`,
+ borderTop: `1px solid ${themeColors.border}`,
fontSize: '13px',
- color: textMuted,
+ color: themeColors.textMuted,
},
footerLink: {
- color: text,
+ color: themeColors.text,
fontWeight: 600,
textDecoration: 'underline',
cursor: 'pointer',
@@ -221,18 +465,57 @@ export const UrAuth: React.FC = ({
);
const GithubIcon = () => (
-
+
);
+ const renderSocialButtons = () => {
+ if (!hasSocialAuth) {
+ return null;
+ }
+
+ return (
+ <>
+ {hasPasswordAuth && (
+
+
+
{text.socialDivider}
+
+
+ )}
+
+
+ {isGoogleEnabled && (
+ socialLogin('google')} type="button">
+
+ {text.googleButton}
+
+ )}
+ {isGithubEnabled && (
+ socialLogin('github')} type="button">
+
+ {text.githubButton}
+
+ )}
+
+ >
+ );
+ };
+
+ const footerPrompt = mode === 'signin'
+ ? text.footerSigninPrompt
+ : mode === 'signup'
+ ? text.footerSignupPrompt
+ : text.footerForgotPrompt;
+
return (
{toast && (
{
setToast(null);
if (toast.type === 'error') clearError();
@@ -241,7 +524,29 @@ export const UrAuth: React.FC = ({
)}
- {(mode === 'signin' || mode === 'signup') && (
+ {(branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle || headerTitle || headerSubtitle) && (
+
+
+ {branding?.logo ? (
+
+ {typeof branding.logo === 'string' ? (
+
+ ) : (
+ branding.logo
+ )}
+
+ ) : (
+
+ {brandName.slice(0, 1).toUpperCase()}
+
+ )}
+
+
{headerTitle}
+
{headerSubtitle}
+
+ )}
+
+ {showSwitcher && (mode === 'signin' || mode === 'signup') && (
= ({
onClick={() => { setMode('signin'); clearError(); }}
>
- Login
+ {text.loginTab}
= ({
onClick={() => { setMode('signup'); clearError(); }}
>
- Sign Up
+ {text.signupTab}
@@ -266,140 +571,126 @@ export const UrAuth: React.FC
= ({
{(mode === 'forgot' || mode === 'reset') && (
-
- {mode === 'forgot' ? 'Reset Password' : 'Enter Reset Code'}
+
+ {mode === 'forgot' ? text.forgotTitle : text.resetTitle}
-
- {mode === 'forgot' ? "Enter your email and we'll send a code" : `Enter the code sent to ${email}`}
+
+ {mode === 'forgot' ? text.forgotSubtitle : text.resetSubtitle.replace('{email}', email)}
+
)}
-