@burdenoff/microfe-auth 2026.624.3 → 2026.626.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/auth/pages/AuditLogPage.js +73 -72
  2. package/dist/auth/pages/AuditLogPage.js.map +1 -1
  3. package/dist/auth/pages/EmailVerifyPage.js +58 -53
  4. package/dist/auth/pages/EmailVerifyPage.js.map +1 -1
  5. package/dist/auth/pages/LoginPage.js +222 -214
  6. package/dist/auth/pages/LoginPage.js.map +1 -1
  7. package/dist/auth/pages/MagicLinkPage.js +75 -68
  8. package/dist/auth/pages/MagicLinkPage.js.map +1 -1
  9. package/dist/auth/pages/MfaSetupPage.js +176 -138
  10. package/dist/auth/pages/MfaSetupPage.js.map +1 -1
  11. package/dist/auth/pages/MfaVerifyPage.js +60 -52
  12. package/dist/auth/pages/MfaVerifyPage.js.map +1 -1
  13. package/dist/auth/pages/PasswordResetPage.js +277 -262
  14. package/dist/auth/pages/PasswordResetPage.js.map +1 -1
  15. package/dist/auth/pages/ReactivatePage.js +54 -46
  16. package/dist/auth/pages/ReactivatePage.js.map +1 -1
  17. package/dist/auth/pages/RegisterPage.js +223 -213
  18. package/dist/auth/pages/RegisterPage.js.map +1 -1
  19. package/dist/auth/pages/SecurityPage.js +298 -267
  20. package/dist/auth/pages/SecurityPage.js.map +1 -1
  21. package/dist/auth/pages/SessionsPage.js +169 -160
  22. package/dist/auth/pages/SessionsPage.js.map +1 -1
  23. package/dist/auth/pages/SsoCallbackPage.js +53 -50
  24. package/dist/auth/pages/SsoCallbackPage.js.map +1 -1
  25. package/dist/auth/pages/SsoConfigPage.js +466 -444
  26. package/dist/auth/pages/SsoConfigPage.js.map +1 -1
  27. package/dist/auth/pages/SsoLoginPage.js +67 -59
  28. package/dist/auth/pages/SsoLoginPage.js.map +1 -1
  29. package/dist/auth/pages/UserDetailsPage.js +154 -144
  30. package/dist/auth/pages/UserDetailsPage.js.map +1 -1
  31. package/dist/auth/pages/UserProfilePage.js +211 -170
  32. package/dist/auth/pages/UserProfilePage.js.map +1 -1
  33. package/dist/auth/pages/UsersPage.js +572 -576
  34. package/dist/auth/pages/UsersPage.js.map +1 -1
  35. package/dist/microfe-auth.css +2 -2
  36. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordResetPage.js","names":[],"sources":["../../../src/auth/pages/PasswordResetPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { useSearchParams, useNavigate } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { usePasswordOperations } from \"../hooks/usePasswordOperations\";\nimport { useCaptchaV3 } from \"../hooks/useCaptchaV3\";\nimport { AuthLayout } from \"../components/AuthLayout\";\nimport {\n EmailIcon,\n LockIcon,\n EyeIcon,\n EyeOffIcon,\n CheckIcon,\n XIcon,\n SpinnerIcon,\n} from \"../components/AuthIcons\";\n\nconst REDIRECT_DELAY = 5; // seconds\n\n/**\n * Password reset page with professional design\n * Handles both requesting reset and completing reset with token\n */\nexport function PasswordResetPage() {\n const navigate = useNavigate();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const [searchParams] = useSearchParams();\n const token = searchParams.get(\"token\");\n // Preserve returnTo so after reset→login the user ends up on the right product domain\n const returnTo = searchParams.get(\"returnTo\");\n const { requestPasswordReset, resetPassword, isLoading } =\n usePasswordOperations();\n const { executeRecaptcha: executeCaptchaV3 } = useCaptchaV3();\n const [email, setEmail] = useState(\"\");\n const [newPassword, setNewPassword] = useState(\"\");\n const [confirmPassword, setConfirmPassword] = useState(\"\");\n const [showPassword, setShowPassword] = useState(false);\n const [showConfirmPassword, setShowConfirmPassword] = useState(false);\n const [success, setSuccess] = useState(false);\n const [error, setError] = useState(\"\");\n const [countdown, setCountdown] = useState(REDIRECT_DELAY);\n\n // Auto-redirect countdown after successful password reset (only for token flow)\n useEffect(() => {\n if (!success || !token) return;\n\n const loginPath = returnTo\n ? `/auth/login?returnTo=${encodeURIComponent(returnTo)}`\n : \"/auth/login\";\n const timer = setInterval(() => {\n setCountdown((prev) => {\n if (prev <= 1) {\n clearInterval(timer);\n navigate(loginPath);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(timer);\n }, [success, token, navigate, returnTo]);\n\n // Password strength indicators\n const passwordChecks = (() => {\n const password = newPassword;\n return [\n {\n label: tr(\"auth.passwordReset.pwMin8\", \"At least 12 characters\"),\n met: password.length >= 12,\n },\n {\n label: tr(\"auth.passwordReset.pwUppercase\", \"One uppercase letter\"),\n met: /[A-Z]/.test(password),\n },\n {\n label: tr(\"auth.passwordReset.pwLowercase\", \"One lowercase letter\"),\n met: /[a-z]/.test(password),\n },\n {\n label: tr(\"auth.passwordReset.pwNumber\", \"One number\"),\n met: /\\d/.test(password),\n },\n {\n label: tr(\"auth.passwordReset.pwSpecial\", \"One special character\"),\n met: /[!@#$%^&*(),.?\":{}|<>]/.test(password),\n },\n ];\n })();\n\n const passwordStrength = (() => {\n const metCount = passwordChecks.filter((c) => c.met).length;\n if (metCount <= 2)\n return {\n level: tr(\"auth.passwordReset.passwordStrengthWeak\", \"weak\"),\n color: \"bg-status-error-bg-subtle0\",\n width: \"w-1/4\",\n };\n if (metCount <= 3)\n return {\n level: tr(\"auth.passwordReset.passwordStrengthFair\", \"fair\"),\n color: \"bg-status-warning-text\",\n width: \"w-2/4\",\n };\n if (metCount <= 4)\n return {\n level: tr(\"auth.passwordReset.passwordStrengthGood\", \"good\"),\n color: \"bg-status-warning-bg-subtle0\",\n width: \"w-3/4\",\n };\n return {\n level: tr(\"auth.passwordReset.passwordStrengthStrong\", \"strong\"),\n color: \"bg-status-success-bg-subtle0\",\n width: \"w-full\",\n };\n })();\n\n const handleRequestReset = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n try {\n // Get reCAPTCHA v3 token (no-op when captcha is disabled)\n const recaptchaToken = await executeCaptchaV3(\"password_reset\");\n await requestPasswordReset(email, recaptchaToken);\n setSuccess(true);\n } catch (err) {\n setError(\n tr(\n \"auth.passwordReset.sendFailed\",\n \"Failed to send reset email. Please try again.\",\n ),\n );\n console.error(\"Failed to request password reset:\", err);\n }\n };\n\n const handleResetPassword = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n\n if (!token) return;\n\n if (newPassword !== confirmPassword) {\n setError(\n tr(\"auth.passwordReset.passwordsNoMatch\", \"Passwords do not match\"),\n );\n return;\n }\n\n try {\n await resetPassword(token, newPassword);\n setSuccess(true);\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"\";\n if (msg === \"TOKEN_EXPIRED\") {\n setError(\n tr(\n \"auth.passwordReset.errorTokenExpired\",\n \"This password reset link has expired. Please request a new one.\",\n ),\n );\n } else if (msg === \"INVALID_TOKEN\") {\n setError(\n tr(\n \"auth.passwordReset.errorInvalidToken\",\n \"This password reset link is invalid or has already been used.\",\n ),\n );\n } else {\n setError(\n tr(\n \"auth.passwordReset.errorGeneric\",\n \"Failed to reset password. Please try again.\",\n ),\n );\n }\n }\n };\n\n if (success) {\n return (\n <AuthLayout\n title={\n token\n ? tr(\"auth.passwordReset.passwordUpdated\", \"Password updated\")\n : tr(\"auth.passwordReset.checkEmail\", \"Check your email\")\n }\n subtitle={\n token\n ? tr(\n \"auth.passwordReset.successSubtitle\",\n \"Your password has been successfully reset\",\n )\n : tr(\n \"auth.passwordReset.sentInstructions\",\n \"We sent you instructions to reset your password\",\n )\n }\n >\n {/* Success Icon */}\n <div className=\"flex justify-center mb-6\">\n <div className=\"size-16 rounded-full bg-[var(--color-status-success-bg-subtle)] flex items-center justify-center\">\n <svg\n className=\"size-8 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n </div>\n\n <p className=\"text-center text-[var(--color-text-secondary)] mb-8\">\n {token\n ? tr(\n \"auth.passwordReset.canNowSignIn\",\n \"You can now use your new password to sign in to your account.\",\n )\n : tr(\n \"auth.passwordReset.emailSentTo\",\n \"We sent an email to {{email}}. Click the link in the email to reset your password.\",\n ).replace(\"{{email}}\", email)}\n </p>\n\n {token ? (\n <div className=\"space-y-4\">\n <p className=\"text-center text-sm text-[var(--color-text-tertiary)]\">\n {tr(\n \"auth.passwordReset.redirectingIn\",\n \"Redirecting to sign in in\",\n )}{\" \"}\n <span className=\"font-semibold text-[var(--color-text-primary)]\">\n {countdown}\n </span>{\" \"}\n {tr(\"auth.passwordReset.seconds\", \"seconds...\")}\n </p>\n <button\n type=\"button\"\n onClick={() =>\n navigate(\n returnTo\n ? `/auth/login?returnTo=${encodeURIComponent(returnTo)}`\n : \"/auth/login\",\n )\n }\n className=\"auth-primary-button w-full px-4 py-3 font-semibold\"\n >\n {tr(\"auth.passwordReset.signInNow\", \"Sign in now\")}\n </button>\n </div>\n ) : (\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => setSuccess(false)}\n className=\"w-full py-3 px-4 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] font-medium hover:bg-[var(--color-bg-sunken)] transition-all\"\n >\n {tr(\n \"auth.passwordReset.didntReceive\",\n \"Didn't receive the email? Try again\",\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"w-full py-3 px-4 rounded-xl text-[var(--color-text-secondary)] font-medium hover:text-[var(--color-text-primary)] transition-colors\"\n >\n {tr(\"auth.passwordReset.backToSignIn\", \"Back to sign in\")}\n </button>\n </div>\n )}\n </AuthLayout>\n );\n }\n\n return (\n <AuthLayout\n title={\n token\n ? tr(\"auth.passwordReset.createNewPassword\", \"Create new password\")\n : tr(\"auth.passwordReset.resetTitle\", \"Reset your password\")\n }\n subtitle={\n token\n ? tr(\n \"auth.passwordReset.enterNewPassword\",\n \"Enter a new password for your account\",\n )\n : tr(\n \"auth.passwordReset.enterEmail\",\n \"Enter your email and we'll send you a reset link\",\n )\n }\n >\n {token ? (\n <form onSubmit={handleResetPassword} className=\"space-y-5\">\n {/* Error Alert */}\n {error && (\n <div className=\"flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <svg\n className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n </div>\n )}\n\n {/* New Password Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"newPassword\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.passwordReset.newPasswordLabel\", \"New Password\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <LockIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"newPassword\"\n type={showPassword ? \"text\" : \"password\"}\n required\n aria-required=\"true\"\n aria-label={tr(\n \"auth.passwordReset.newPasswordLabel\",\n \"New Password\",\n )}\n autoComplete=\"new-password\"\n value={newPassword}\n onChange={(e) => setNewPassword(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-12 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n placeholder={tr(\n \"auth.passwordReset.newPasswordPlaceholder\",\n \"Enter new password\",\n )}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n aria-label={showPassword ? \"Hide password\" : \"Show password\"}\n className=\"absolute inset-y-0 right-0 pr-3.5 flex items-center text-[var(--color-text-tertiary)] hover:text-[var(--color-text-secondary)] transition-colors\"\n >\n {showPassword ? (\n <EyeOffIcon className=\"size-5\" />\n ) : (\n <EyeIcon className=\"size-5\" />\n )}\n </button>\n </div>\n\n {/* Password Strength Indicator */}\n {newPassword && (\n <div className=\"space-y-3 pt-2\">\n <div className=\"space-y-1\">\n <div className=\"h-1.5 bg-[var(--color-bg-sunken)] rounded-full overflow-hidden\">\n <div\n className={`h-full ${passwordStrength.color} ${passwordStrength.width} transition-all duration-300`}\n />\n </div>\n <p className=\"text-xs text-[var(--color-text-tertiary)] capitalize\">\n {tr(\n \"auth.passwordReset.passwordStrength\",\n \"Password strength:\",\n )}{\" \"}\n <span className=\"font-medium\">\n {passwordStrength.level}\n </span>\n </p>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n {passwordChecks.map((check) => (\n <div key={check.label} className=\"flex items-center gap-2\">\n {check.met ? (\n <CheckIcon className=\"size-4 text-status-success-text\" />\n ) : (\n <XIcon className=\"size-4 text-[var(--color-text-tertiary)]\" />\n )}\n <span\n className={`text-xs ${\n check.met\n ? \"text-[var(--color-status-success-text)]\"\n : \"text-[var(--color-text-tertiary)]\"\n }`}\n >\n {check.label}\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Confirm Password Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"confirmPassword\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\n \"auth.passwordReset.confirmPasswordLabel\",\n \"Confirm Password\",\n )}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <LockIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"confirmPassword\"\n type={showConfirmPassword ? \"text\" : \"password\"}\n required\n aria-required=\"true\"\n aria-label={tr(\n \"auth.passwordReset.confirmPasswordLabel\",\n \"Confirm Password\",\n )}\n autoComplete=\"new-password\"\n aria-invalid={\n confirmPassword.length > 0 && newPassword !== confirmPassword\n }\n value={confirmPassword}\n onChange={(e) => setConfirmPassword(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-12 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n placeholder={tr(\n \"auth.passwordReset.confirmPasswordPlaceholder\",\n \"Confirm new password\",\n )}\n />\n <button\n type=\"button\"\n onClick={() => setShowConfirmPassword(!showConfirmPassword)}\n aria-label={\n showConfirmPassword ? \"Hide password\" : \"Show password\"\n }\n className=\"absolute inset-y-0 right-0 pr-3.5 flex items-center text-[var(--color-text-tertiary)] hover:text-[var(--color-text-secondary)] transition-colors\"\n >\n {showConfirmPassword ? (\n <EyeOffIcon className=\"size-5\" />\n ) : (\n <EyeIcon className=\"size-5\" />\n )}\n </button>\n </div>\n {confirmPassword && newPassword !== confirmPassword && (\n <p className=\"text-xs text-[var(--color-status-error-text)]\">\n {tr(\n \"auth.passwordReset.passwordsMismatch\",\n \"Passwords do not match\",\n )}\n </p>\n )}\n </div>\n\n {/* Submit Button */}\n <button\n type=\"submit\"\n disabled={\n isLoading ||\n (confirmPassword.length > 0 && newPassword !== confirmPassword)\n }\n className=\"auth-primary-button flex w-full items-center justify-center gap-2 px-4 py-3 font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>\n {tr(\"auth.passwordReset.resetting\", \"Resetting password...\")}\n </span>\n </>\n ) : (\n tr(\"auth.passwordReset.resetButton\", \"Reset password\")\n )}\n </button>\n </form>\n ) : (\n <form onSubmit={handleRequestReset} className=\"space-y-5\">\n {/* Error Alert */}\n {error && (\n <div className=\"flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <svg\n className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n </div>\n )}\n\n {/* Email Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"email\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.passwordReset.emailLabel\", \"Email address\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <EmailIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"email\"\n type=\"email\"\n required\n aria-required=\"true\"\n aria-label={tr(\n \"auth.passwordReset.emailLabel\",\n \"Email address\",\n )}\n autoComplete=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n placeholder={tr(\n \"auth.passwordReset.emailPlaceholder\",\n \"you@example.com\",\n )}\n />\n </div>\n </div>\n\n {/* Submit Button */}\n <button\n type=\"submit\"\n disabled={isLoading}\n className=\"auth-primary-button flex w-full items-center justify-center gap-2 px-4 py-3 font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.passwordReset.sending\", \"Sending...\")}</span>\n </>\n ) : (\n tr(\"auth.passwordReset.sendResetLink\", \"Send reset link\")\n )}\n </button>\n </form>\n )}\n\n {/* Back to Sign In */}\n <p className=\"mt-8 text-center text-sm text-[var(--color-text-secondary)]\">\n {tr(\"auth.passwordReset.rememberPassword\", \"Remember your password?\")}{\" \"}\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"font-semibold text-text-link hover:text-text-linkHover transition-colors\"\n >\n {tr(\"auth.passwordReset.signIn\", \"Sign in\")}\n </button>\n </p>\n </AuthLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PasswordResetPage.js","names":[],"sources":["../../../src/auth/pages/PasswordResetPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { useSearchParams, useNavigate } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { usePasswordOperations } from \"../hooks/usePasswordOperations\";\nimport { useCaptchaV3 } from \"../hooks/useCaptchaV3\";\nimport { AuthLayout } from \"../components/AuthLayout\";\nimport { Button } from \"@burdenoff/fe-libs/button\";\nimport { PagePurpose } from \"@burdenoff/fe-libs/ui\";\nimport {\n EmailIcon,\n LockIcon,\n EyeIcon,\n EyeOffIcon,\n CheckIcon,\n XIcon,\n SpinnerIcon,\n} from \"../components/AuthIcons\";\n\nconst REDIRECT_DELAY = 5; // seconds\n\n/**\n * Password reset page with professional design\n * Handles both requesting reset and completing reset with token\n */\nexport function PasswordResetPage() {\n const navigate = useNavigate();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const [searchParams] = useSearchParams();\n const token = searchParams.get(\"token\");\n // Preserve returnTo so after reset→login the user ends up on the right product domain\n const returnTo = searchParams.get(\"returnTo\");\n const { requestPasswordReset, resetPassword, isLoading } =\n usePasswordOperations();\n const { executeRecaptcha: executeCaptchaV3 } = useCaptchaV3();\n const [email, setEmail] = useState(\"\");\n const [newPassword, setNewPassword] = useState(\"\");\n const [confirmPassword, setConfirmPassword] = useState(\"\");\n const [showPassword, setShowPassword] = useState(false);\n const [showConfirmPassword, setShowConfirmPassword] = useState(false);\n const [success, setSuccess] = useState(false);\n const [error, setError] = useState(\"\");\n const [countdown, setCountdown] = useState(REDIRECT_DELAY);\n\n // Auto-redirect countdown after successful password reset (only for token flow)\n useEffect(() => {\n if (!success || !token) return;\n\n const loginPath = returnTo\n ? `/auth/login?returnTo=${encodeURIComponent(returnTo)}`\n : \"/auth/login\";\n const timer = setInterval(() => {\n setCountdown((prev) => {\n if (prev <= 1) {\n clearInterval(timer);\n navigate(loginPath);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(timer);\n }, [success, token, navigate, returnTo]);\n\n // Password strength indicators\n const passwordChecks = (() => {\n const password = newPassword;\n return [\n {\n label: tr(\"auth.passwordReset.pwMin8\", \"At least 12 characters\"),\n met: password.length >= 12,\n },\n {\n label: tr(\"auth.passwordReset.pwUppercase\", \"One uppercase letter\"),\n met: /[A-Z]/.test(password),\n },\n {\n label: tr(\"auth.passwordReset.pwLowercase\", \"One lowercase letter\"),\n met: /[a-z]/.test(password),\n },\n {\n label: tr(\"auth.passwordReset.pwNumber\", \"One number\"),\n met: /\\d/.test(password),\n },\n {\n label: tr(\"auth.passwordReset.pwSpecial\", \"One special character\"),\n met: /[!@#$%^&*(),.?\":{}|<>]/.test(password),\n },\n ];\n })();\n\n const passwordStrength = (() => {\n const metCount = passwordChecks.filter((c) => c.met).length;\n if (metCount <= 2)\n return {\n level: tr(\"auth.passwordReset.passwordStrengthWeak\", \"weak\"),\n color: \"bg-status-error-bg-subtle0\",\n width: \"w-1/4\",\n };\n if (metCount <= 3)\n return {\n level: tr(\"auth.passwordReset.passwordStrengthFair\", \"fair\"),\n color: \"bg-status-warning-text\",\n width: \"w-2/4\",\n };\n if (metCount <= 4)\n return {\n level: tr(\"auth.passwordReset.passwordStrengthGood\", \"good\"),\n color: \"bg-status-warning-bg-subtle0\",\n width: \"w-3/4\",\n };\n return {\n level: tr(\"auth.passwordReset.passwordStrengthStrong\", \"strong\"),\n color: \"bg-status-success-bg-subtle0\",\n width: \"w-full\",\n };\n })();\n\n const handleRequestReset = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n try {\n // Get reCAPTCHA v3 token (no-op when captcha is disabled)\n const recaptchaToken = await executeCaptchaV3(\"password_reset\");\n await requestPasswordReset(email, recaptchaToken);\n setSuccess(true);\n } catch (err) {\n setError(\n tr(\n \"auth.passwordReset.sendFailed\",\n \"Failed to send reset email. Please try again.\",\n ),\n );\n console.error(\"Failed to request password reset:\", err);\n }\n };\n\n const handleResetPassword = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n\n if (!token) return;\n\n if (newPassword !== confirmPassword) {\n setError(\n tr(\"auth.passwordReset.passwordsNoMatch\", \"Passwords do not match\"),\n );\n return;\n }\n\n try {\n await resetPassword(token, newPassword);\n setSuccess(true);\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"\";\n if (msg === \"TOKEN_EXPIRED\") {\n setError(\n tr(\n \"auth.passwordReset.errorTokenExpired\",\n \"This password reset link has expired. Please request a new one.\",\n ),\n );\n } else if (msg === \"INVALID_TOKEN\") {\n setError(\n tr(\n \"auth.passwordReset.errorInvalidToken\",\n \"This password reset link is invalid or has already been used.\",\n ),\n );\n } else {\n setError(\n tr(\n \"auth.passwordReset.errorGeneric\",\n \"Failed to reset password. Please try again.\",\n ),\n );\n }\n }\n };\n\n if (success) {\n return (\n <AuthLayout\n title={\n token\n ? tr(\"auth.passwordReset.passwordUpdated\", \"Password updated\")\n : tr(\"auth.passwordReset.checkEmail\", \"Check your email\")\n }\n subtitle={\n token\n ? tr(\n \"auth.passwordReset.successSubtitle\",\n \"Your password has been successfully reset\",\n )\n : tr(\n \"auth.passwordReset.sentInstructions\",\n \"We sent you instructions to reset your password\",\n )\n }\n >\n {/* Success Icon */}\n <div className=\"flex justify-center mb-6\">\n <div className=\"size-16 rounded-full bg-[var(--color-status-success-bg-subtle)] flex items-center justify-center\">\n <svg\n className=\"size-8 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n </div>\n\n <p className=\"text-center text-[var(--color-text-secondary)] mb-8\">\n {token\n ? tr(\n \"auth.passwordReset.canNowSignIn\",\n \"You can now use your new password to sign in to your account.\",\n )\n : tr(\n \"auth.passwordReset.emailSentTo\",\n \"We sent an email to {{email}}. Click the link in the email to reset your password.\",\n ).replace(\"{{email}}\", email)}\n </p>\n\n {token ? (\n <div className=\"space-y-4\">\n <p className=\"text-center text-sm text-[var(--color-text-tertiary)]\">\n {tr(\n \"auth.passwordReset.redirectingIn\",\n \"Redirecting to sign in in\",\n )}{\" \"}\n <span className=\"font-semibold text-[var(--color-text-primary)]\">\n {countdown}\n </span>{\" \"}\n {tr(\"auth.passwordReset.seconds\", \"seconds...\")}\n </p>\n <Button\n type=\"button\"\n onClick={() =>\n navigate(\n returnTo\n ? `/auth/login?returnTo=${encodeURIComponent(returnTo)}`\n : \"/auth/login\",\n )\n }\n variant=\"default\"\n size=\"lg\"\n className=\"w-full font-semibold\"\n >\n {tr(\"auth.passwordReset.signInNow\", \"Sign in now\")}\n </Button>\n </div>\n ) : (\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => setSuccess(false)}\n className=\"w-full py-3 px-4 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] font-medium hover:bg-[var(--color-bg-sunken)] transition-all\"\n >\n {tr(\n \"auth.passwordReset.didntReceive\",\n \"Didn't receive the email? Try again\",\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"w-full py-3 px-4 rounded-xl text-[var(--color-text-secondary)] font-medium hover:text-[var(--color-text-primary)] transition-colors\"\n >\n {tr(\"auth.passwordReset.backToSignIn\", \"Back to sign in\")}\n </button>\n </div>\n )}\n </AuthLayout>\n );\n }\n\n return (\n <AuthLayout\n title={\n token\n ? tr(\"auth.passwordReset.createNewPassword\", \"Create new password\")\n : tr(\"auth.passwordReset.resetTitle\", \"Reset your password\")\n }\n subtitle={\n token\n ? tr(\n \"auth.passwordReset.enterNewPassword\",\n \"Enter a new password for your account\",\n )\n : tr(\n \"auth.passwordReset.enterEmail\",\n \"Enter your email and we'll send you a reset link\",\n )\n }\n >\n <PagePurpose className=\"mb-5\">\n {token\n ? tr(\n \"auth.passwordReset.purposeReset\",\n \"Choose a new password for your account. Make it strong and unique — you'll use it to sign in next time.\",\n )\n : tr(\n \"auth.passwordReset.purposeRequest\",\n \"Forgot your password? Enter your email and we'll send a secure link to reset it. The link expires shortly for your safety.\",\n )}\n </PagePurpose>\n {token ? (\n <form onSubmit={handleResetPassword} className=\"space-y-5\">\n {/* Error Alert */}\n {error && (\n <div className=\"flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <svg\n className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n </div>\n )}\n\n {/* New Password Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"newPassword\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.passwordReset.newPasswordLabel\", \"New Password\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <LockIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"newPassword\"\n type={showPassword ? \"text\" : \"password\"}\n required\n aria-required=\"true\"\n aria-label={tr(\n \"auth.passwordReset.newPasswordLabel\",\n \"New Password\",\n )}\n autoComplete=\"new-password\"\n value={newPassword}\n onChange={(e) => setNewPassword(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-12 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n placeholder={tr(\n \"auth.passwordReset.newPasswordPlaceholder\",\n \"Enter new password\",\n )}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n aria-label={showPassword ? \"Hide password\" : \"Show password\"}\n className=\"absolute inset-y-0 right-0 pr-3.5 flex items-center text-[var(--color-text-tertiary)] hover:text-[var(--color-text-secondary)] transition-colors\"\n >\n {showPassword ? (\n <EyeOffIcon className=\"size-5\" />\n ) : (\n <EyeIcon className=\"size-5\" />\n )}\n </button>\n </div>\n\n {/* Password Strength Indicator */}\n {newPassword && (\n <div className=\"space-y-3 pt-2\">\n <div className=\"space-y-1\">\n <div className=\"h-1.5 bg-[var(--color-bg-sunken)] rounded-full overflow-hidden\">\n <div\n className={`h-full ${passwordStrength.color} ${passwordStrength.width} transition-all duration-300`}\n />\n </div>\n <p className=\"text-xs text-[var(--color-text-tertiary)] capitalize\">\n {tr(\n \"auth.passwordReset.passwordStrength\",\n \"Password strength:\",\n )}{\" \"}\n <span className=\"font-medium\">\n {passwordStrength.level}\n </span>\n </p>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n {passwordChecks.map((check) => (\n <div key={check.label} className=\"flex items-center gap-2\">\n {check.met ? (\n <CheckIcon className=\"size-4 text-status-success-text\" />\n ) : (\n <XIcon className=\"size-4 text-[var(--color-text-tertiary)]\" />\n )}\n <span\n className={`text-xs ${\n check.met\n ? \"text-[var(--color-status-success-text)]\"\n : \"text-[var(--color-text-tertiary)]\"\n }`}\n >\n {check.label}\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Confirm Password Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"confirmPassword\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\n \"auth.passwordReset.confirmPasswordLabel\",\n \"Confirm Password\",\n )}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <LockIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"confirmPassword\"\n type={showConfirmPassword ? \"text\" : \"password\"}\n required\n aria-required=\"true\"\n aria-label={tr(\n \"auth.passwordReset.confirmPasswordLabel\",\n \"Confirm Password\",\n )}\n autoComplete=\"new-password\"\n aria-invalid={\n confirmPassword.length > 0 && newPassword !== confirmPassword\n }\n value={confirmPassword}\n onChange={(e) => setConfirmPassword(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-12 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n placeholder={tr(\n \"auth.passwordReset.confirmPasswordPlaceholder\",\n \"Confirm new password\",\n )}\n />\n <button\n type=\"button\"\n onClick={() => setShowConfirmPassword(!showConfirmPassword)}\n aria-label={\n showConfirmPassword ? \"Hide password\" : \"Show password\"\n }\n className=\"absolute inset-y-0 right-0 pr-3.5 flex items-center text-[var(--color-text-tertiary)] hover:text-[var(--color-text-secondary)] transition-colors\"\n >\n {showConfirmPassword ? (\n <EyeOffIcon className=\"size-5\" />\n ) : (\n <EyeIcon className=\"size-5\" />\n )}\n </button>\n </div>\n {confirmPassword && newPassword !== confirmPassword && (\n <p className=\"text-xs text-[var(--color-status-error-text)]\">\n {tr(\n \"auth.passwordReset.passwordsMismatch\",\n \"Passwords do not match\",\n )}\n </p>\n )}\n </div>\n\n {/* Submit Button */}\n <Button\n type=\"submit\"\n disabled={\n isLoading ||\n (confirmPassword.length > 0 && newPassword !== confirmPassword)\n }\n variant=\"default\"\n size=\"lg\"\n className=\"w-full font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>\n {tr(\"auth.passwordReset.resetting\", \"Resetting password...\")}\n </span>\n </>\n ) : (\n tr(\"auth.passwordReset.resetButton\", \"Reset password\")\n )}\n </Button>\n </form>\n ) : (\n <form onSubmit={handleRequestReset} className=\"space-y-5\">\n {/* Error Alert */}\n {error && (\n <div className=\"flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <svg\n className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n </div>\n )}\n\n {/* Email Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"email\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.passwordReset.emailLabel\", \"Email address\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <EmailIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"email\"\n type=\"email\"\n required\n aria-required=\"true\"\n aria-label={tr(\n \"auth.passwordReset.emailLabel\",\n \"Email address\",\n )}\n autoComplete=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all\"\n placeholder={tr(\n \"auth.passwordReset.emailPlaceholder\",\n \"you@example.com\",\n )}\n />\n </div>\n </div>\n\n {/* Submit Button */}\n <Button\n type=\"submit\"\n disabled={isLoading}\n variant=\"default\"\n size=\"lg\"\n className=\"w-full font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.passwordReset.sending\", \"Sending...\")}</span>\n </>\n ) : (\n tr(\"auth.passwordReset.sendResetLink\", \"Send reset link\")\n )}\n </Button>\n </form>\n )}\n\n {/* Back to Sign In */}\n <p className=\"mt-8 text-center text-sm text-[var(--color-text-secondary)]\">\n {tr(\"auth.passwordReset.rememberPassword\", \"Remember your password?\")}{\" \"}\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"font-semibold text-text-link hover:text-text-linkHover transition-colors\"\n >\n {tr(\"auth.passwordReset.signIn\", \"Sign in\")}\n </button>\n </p>\n </AuthLayout>\n );\n}\n"],"mappings":"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"}
@@ -5,17 +5,19 @@ import { useEffect as o, useState as s } from "react";
5
5
  import { useLocation as c, useNavigate as l } from "react-router-dom";
6
6
  import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell";
7
7
  import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
8
+ import { Button as m } from "@burdenoff/fe-libs/button";
9
+ import { PagePurpose as h } from "@burdenoff/fe-libs/ui";
8
10
  //#region src/auth/pages/ReactivatePage.tsx
9
- function m() {
10
- let { t: m } = u(), h = (e, t) => {
11
- let n = m(e);
11
+ function g() {
12
+ let { t: g } = u(), _ = (e, t) => {
13
+ let n = g(e);
12
14
  return n === e ? t : n;
13
- }, g = l(), _ = c(), { reactivateAccount: v, isReactivating: y } = a(), b = _.state?.email || "", [x, S] = s(b), [C, w] = s(""), [T, E] = s(null), [D, O] = s(!1);
15
+ }, v = l(), y = c(), { reactivateAccount: b, isReactivating: x } = a(), S = y.state?.email || "", [C, w] = s(S), [T, E] = s(""), [D, O] = s(null), [k, A] = s(!1);
14
16
  return o(() => {
15
- b && S(b);
16
- }, [b]), D ? /* @__PURE__ */ f(e, {
17
- title: h("auth.reactivate.successTitle", "Account Reactivated!"),
18
- subtitle: h("auth.reactivate.successSubtitle", "Welcome back"),
17
+ S && w(S);
18
+ }, [S]), k ? /* @__PURE__ */ f(e, {
19
+ title: _("auth.reactivate.successTitle", "Account Reactivated!"),
20
+ subtitle: _("auth.reactivate.successSubtitle", "Welcome back"),
19
21
  children: /* @__PURE__ */ p("div", {
20
22
  className: "text-center py-8",
21
23
  children: [
@@ -36,11 +38,11 @@ function m() {
36
38
  }),
37
39
  /* @__PURE__ */ f("h2", {
38
40
  className: "text-xl font-semibold text-[var(--color-text-primary)] mb-2",
39
- children: h("auth.reactivate.accountActive", "Your account is now active")
41
+ children: _("auth.reactivate.accountActive", "Your account is now active")
40
42
  }),
41
43
  /* @__PURE__ */ f("p", {
42
44
  className: "text-[var(--color-text-secondary)] mb-6",
43
- children: h("auth.reactivate.redirecting", "You can now access all features. Redirecting to dashboard...")
45
+ children: _("auth.reactivate.redirecting", "You can now access all features. Redirecting to dashboard...")
44
46
  }),
45
47
  /* @__PURE__ */ f("div", {
46
48
  className: "flex justify-center",
@@ -49,33 +51,37 @@ function m() {
49
51
  ]
50
52
  })
51
53
  }) : /* @__PURE__ */ p(e, {
52
- title: h("auth.reactivate.title", "Reactivate Account"),
53
- subtitle: h("auth.reactivate.subtitle", "Restore access to your deactivated account"),
54
+ title: _("auth.reactivate.title", "Reactivate Account"),
55
+ subtitle: _("auth.reactivate.subtitle", "Restore access to your deactivated account"),
54
56
  children: [
57
+ /* @__PURE__ */ f(h, {
58
+ className: "mb-5",
59
+ children: _("auth.reactivate.purpose", "Reactivate an account you previously deactivated. Confirm your email and password to restore full access — deleted accounts can't be recovered here.")
60
+ }),
55
61
  /* @__PURE__ */ p("form", {
56
62
  onSubmit: async (e) => {
57
- if (e.preventDefault(), E(null), !x || !C) {
58
- E(h("auth.reactivate.enterBoth", "Please enter both email and password"));
63
+ if (e.preventDefault(), O(null), !C || !T) {
64
+ O(_("auth.reactivate.enterBoth", "Please enter both email and password"));
59
65
  return;
60
66
  }
61
67
  try {
62
- let e = await v(x, C);
63
- e.success ? (O(!0), setTimeout(() => {
64
- g("/dashboard", { replace: !0 });
65
- }, 2e3)) : E(e.error || "Failed to reactivate account");
68
+ let e = await b(C, T);
69
+ e.success ? (A(!0), setTimeout(() => {
70
+ v("/dashboard", { replace: !0 });
71
+ }, 2e3)) : O(e.error || "Failed to reactivate account");
66
72
  } catch (e) {
67
- console.error("Reactivation error:", e), E(e instanceof Error ? e.message : "An unexpected error occurred");
73
+ console.error("Reactivation error:", e), O(e instanceof Error ? e.message : "An unexpected error occurred");
68
74
  }
69
75
  },
70
76
  className: "space-y-5",
71
77
  children: [
72
- T && /* @__PURE__ */ p("div", {
78
+ D && /* @__PURE__ */ p("div", {
73
79
  className: "flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]",
74
80
  children: [/* @__PURE__ */ f(t, { className: "size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5" }), /* @__PURE__ */ f("div", {
75
81
  className: "flex-1",
76
82
  children: /* @__PURE__ */ f("p", {
77
83
  className: "text-sm text-[var(--color-status-error-text)]",
78
- children: T
84
+ children: D
79
85
  })
80
86
  })]
81
87
  }),
@@ -96,10 +102,10 @@ function m() {
96
102
  })
97
103
  }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("p", {
98
104
  className: "text-sm text-[var(--color-status-warning-text)] font-medium",
99
- children: h("auth.reactivate.deactivated", "Account Deactivated?")
105
+ children: _("auth.reactivate.deactivated", "Account Deactivated?")
100
106
  }), /* @__PURE__ */ f("p", {
101
107
  className: "text-xs text-[var(--color-status-warning-text)] mt-1",
102
- children: h("auth.reactivate.instructions", "If you previously deactivated your account, you can restore it here. Enter your email and password to reactivate.")
108
+ children: _("auth.reactivate.instructions", "If you previously deactivated your account, you can restore it here. Enter your email and password to reactivate.")
103
109
  })] })]
104
110
  })
105
111
  }),
@@ -108,7 +114,7 @@ function m() {
108
114
  children: [/* @__PURE__ */ f("label", {
109
115
  htmlFor: "email",
110
116
  className: "block text-sm font-medium text-[var(--color-text-primary)]",
111
- children: h("auth.reactivate.emailLabel", "Email Address")
117
+ children: _("auth.reactivate.emailLabel", "Email Address")
112
118
  }), /* @__PURE__ */ p("div", {
113
119
  className: "relative",
114
120
  children: [/* @__PURE__ */ f("div", {
@@ -118,9 +124,9 @@ function m() {
118
124
  id: "email",
119
125
  type: "email",
120
126
  required: !0,
121
- "aria-label": h("auth.reactivate.emailLabel", "Email Address"),
122
- value: x,
123
- onChange: (e) => S(e.target.value),
127
+ "aria-label": _("auth.reactivate.emailLabel", "Email Address"),
128
+ value: C,
129
+ onChange: (e) => w(e.target.value),
124
130
  className: "block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-status-success-bg/20 focus:border-status-success-border transition-all",
125
131
  placeholder: "you@example.com"
126
132
  })]
@@ -131,7 +137,7 @@ function m() {
131
137
  children: [/* @__PURE__ */ f("label", {
132
138
  htmlFor: "password",
133
139
  className: "block text-sm font-medium text-[var(--color-text-primary)]",
134
- children: h("auth.reactivate.passwordLabel", "Password")
140
+ children: _("auth.reactivate.passwordLabel", "Password")
135
141
  }), /* @__PURE__ */ p("div", {
136
142
  className: "relative",
137
143
  children: [/* @__PURE__ */ f("div", {
@@ -141,19 +147,21 @@ function m() {
141
147
  id: "password",
142
148
  type: "password",
143
149
  required: !0,
144
- "aria-label": h("auth.reactivate.passwordLabel", "Password"),
145
- value: C,
146
- onChange: (e) => w(e.target.value),
150
+ "aria-label": _("auth.reactivate.passwordLabel", "Password"),
151
+ value: T,
152
+ onChange: (e) => E(e.target.value),
147
153
  className: "block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-status-success-bg/20 focus:border-status-success-border transition-all",
148
- placeholder: h("auth.reactivate.passwordPlaceholder", "Enter your password")
154
+ placeholder: _("auth.reactivate.passwordPlaceholder", "Enter your password")
149
155
  })]
150
156
  })]
151
157
  }),
152
- /* @__PURE__ */ f("button", {
158
+ /* @__PURE__ */ f(m, {
153
159
  type: "submit",
154
- disabled: y || !x || !C,
155
- className: "auth-primary-button w-full py-3 px-4 flex items-center justify-center gap-2",
156
- children: y ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(i, { className: "size-5 animate-spin" }), /* @__PURE__ */ f("span", { children: "Reactivating…" })] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("svg", {
160
+ disabled: x || !C || !T,
161
+ variant: "default",
162
+ size: "lg",
163
+ className: "w-full font-semibold",
164
+ children: x ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(i, { className: "size-5 animate-spin" }), /* @__PURE__ */ f("span", { children: "Reactivating…" })] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("svg", {
157
165
  className: "size-5",
158
166
  fill: "none",
159
167
  viewBox: "0 0 24 24",
@@ -164,7 +172,7 @@ function m() {
164
172
  strokeWidth: 2,
165
173
  d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
166
174
  })
167
- }), /* @__PURE__ */ f("span", { children: h("auth.reactivate.reactivateBtn", "Reactivate Account") })] })
175
+ }), /* @__PURE__ */ f("span", { children: _("auth.reactivate.reactivateBtn", "Reactivate Account") })] })
168
176
  })
169
177
  ]
170
178
  }),
@@ -174,14 +182,14 @@ function m() {
174
182
  className: "text-center",
175
183
  children: /* @__PURE__ */ p("button", {
176
184
  type: "button",
177
- onClick: () => g("/auth/login"),
185
+ onClick: () => v("/auth/login"),
178
186
  className: "text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors",
179
187
  children: [
180
- h("auth.reactivate.accountIsActive", "Remember your account is active?"),
188
+ _("auth.reactivate.accountIsActive", "Remember your account is active?"),
181
189
  " ",
182
190
  /* @__PURE__ */ f("span", {
183
191
  className: "font-semibold text-text-link hover:text-text-linkHover",
184
- children: h("auth.reactivate.signInInstead", "Sign in instead")
192
+ children: _("auth.reactivate.signInInstead", "Sign in instead")
185
193
  })
186
194
  ]
187
195
  })
@@ -189,14 +197,14 @@ function m() {
189
197
  className: "text-center",
190
198
  children: /* @__PURE__ */ p("button", {
191
199
  type: "button",
192
- onClick: () => g("/auth/reset-password"),
200
+ onClick: () => v("/auth/reset-password"),
193
201
  className: "text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors",
194
202
  children: [
195
- h("auth.reactivate.forgotPassword", "Forgot your password?"),
203
+ _("auth.reactivate.forgotPassword", "Forgot your password?"),
196
204
  " ",
197
205
  /* @__PURE__ */ f("span", {
198
206
  className: "font-semibold text-accent-purple hover:text-accent-purple",
199
- children: h("auth.reactivate.resetIt", "Reset it")
207
+ children: _("auth.reactivate.resetIt", "Reset it")
200
208
  })
201
209
  ]
202
210
  })
@@ -206,16 +214,16 @@ function m() {
206
214
  className: "mt-6 p-4 rounded-xl bg-[var(--color-bg-muted)] border border-[var(--color-border-default)]",
207
215
  children: [/* @__PURE__ */ f("h4", {
208
216
  className: "text-sm font-medium text-[var(--color-text-primary)] mb-2",
209
- children: h("auth.reactivate.cantReactivate", "Can't reactivate your account?")
217
+ children: _("auth.reactivate.cantReactivate", "Can't reactivate your account?")
210
218
  }), /* @__PURE__ */ f("p", {
211
219
  className: "text-xs text-[var(--color-text-secondary)]",
212
- children: h("auth.reactivate.deletedHelp", "If your account was deleted (not just deactivated), it cannot be restored. Contact support if you believe this is an error.")
220
+ children: _("auth.reactivate.deletedHelp", "If your account was deleted (not just deactivated), it cannot be restored. Contact support if you believe this is an error.")
213
221
  })]
214
222
  })
215
223
  ]
216
224
  });
217
225
  }
218
226
  //#endregion
219
- export { m as ReactivatePage };
227
+ export { g as ReactivatePage };
220
228
 
221
229
  //# sourceMappingURL=ReactivatePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactivatePage.js","names":[],"sources":["../../../src/auth/pages/ReactivatePage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useNavigate, useLocation } from \"react-router-dom\";\nimport { useAccountOperations } from \"../hooks/useAccountOperations\";\nimport { AuthLayout } from \"../components/AuthLayout\";\nimport {\n EmailIcon,\n LockIcon,\n SpinnerIcon,\n AlertIcon,\n} from \"../components/AuthIcons\";\n\n/**\n * Account Reactivation Page\n * Allows users to reactivate their deactivated accounts\n */\nexport function ReactivatePage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const navigate = useNavigate();\n const location = useLocation();\n const { reactivateAccount, isReactivating } = useAccountOperations();\n\n // Get email from navigation state (passed from login page)\n const emailFromState = (location.state as { email?: string })?.email || \"\";\n\n const [email, setEmail] = useState(emailFromState);\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n\n // Update email if passed from login page\n useEffect(() => {\n if (emailFromState) {\n setEmail(emailFromState);\n }\n }, [emailFromState]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n if (!email || !password) {\n setError(\n tr(\"auth.reactivate.enterBoth\", \"Please enter both email and password\"),\n );\n return;\n }\n\n try {\n const result = await reactivateAccount(email, password);\n\n if (result.success) {\n setSuccess(true);\n // Redirect to dashboard after short delay\n setTimeout(() => {\n navigate(\"/dashboard\", { replace: true });\n }, 2000);\n } else {\n setError(result.error || \"Failed to reactivate account\");\n }\n } catch (err) {\n console.error(\"Reactivation error:\", err);\n setError(\n err instanceof Error ? err.message : \"An unexpected error occurred\",\n );\n }\n };\n\n if (success) {\n return (\n <AuthLayout\n title={tr(\"auth.reactivate.successTitle\", \"Account Reactivated!\")}\n subtitle={tr(\"auth.reactivate.successSubtitle\", \"Welcome back\")}\n >\n <div className=\"text-center py-8\">\n <div className=\"size-20 mx-auto mb-6 rounded-full bg-[var(--color-status-success-bg-subtle)] flex items-center justify-center\">\n <svg\n className=\"size-10 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)] mb-2\">\n {tr(\"auth.reactivate.accountActive\", \"Your account is now active\")}\n </h2>\n <p className=\"text-[var(--color-text-secondary)] mb-6\">\n {tr(\n \"auth.reactivate.redirecting\",\n \"You can now access all features. Redirecting to dashboard...\",\n )}\n </p>\n\n <div className=\"flex justify-center\">\n <SpinnerIcon className=\"size-6 text-status-success-text animate-spin\" />\n </div>\n </div>\n </AuthLayout>\n );\n }\n\n return (\n <AuthLayout\n title={tr(\"auth.reactivate.title\", \"Reactivate Account\")}\n subtitle={tr(\n \"auth.reactivate.subtitle\",\n \"Restore access to your deactivated account\",\n )}\n >\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n {/* Error Alert */}\n {error && (\n <div className=\"flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <AlertIcon className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\" />\n <div className=\"flex-1\">\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n </div>\n </div>\n )}\n\n {/* Info Banner */}\n <div className=\"p-4 rounded-xl bg-[var(--color-status-warning-bg-subtle)] border border-[var(--color-status-warning-border)]\">\n <div className=\"flex items-start gap-3\">\n <svg\n className=\"size-5 text-[var(--color-status-warning-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <div>\n <p className=\"text-sm text-[var(--color-status-warning-text)] font-medium\">\n {tr(\"auth.reactivate.deactivated\", \"Account Deactivated?\")}\n </p>\n <p className=\"text-xs text-[var(--color-status-warning-text)] mt-1\">\n {tr(\n \"auth.reactivate.instructions\",\n \"If you previously deactivated your account, you can restore it here. Enter your email and password to reactivate.\",\n )}\n </p>\n </div>\n </div>\n </div>\n\n {/* Email Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"email\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.reactivate.emailLabel\", \"Email Address\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <EmailIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"email\"\n type=\"email\"\n required\n aria-label={tr(\"auth.reactivate.emailLabel\", \"Email Address\")}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-status-success-bg/20 focus:border-status-success-border transition-all\"\n placeholder=\"you@example.com\"\n />\n </div>\n </div>\n\n {/* Password Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"password\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.reactivate.passwordLabel\", \"Password\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <LockIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"password\"\n type=\"password\"\n required\n aria-label={tr(\"auth.reactivate.passwordLabel\", \"Password\")}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-status-success-bg/20 focus:border-status-success-border transition-all\"\n placeholder={tr(\n \"auth.reactivate.passwordPlaceholder\",\n \"Enter your password\",\n )}\n />\n </div>\n </div>\n\n {/* Submit Button */}\n <button\n type=\"submit\"\n disabled={isReactivating || !email || !password}\n className=\"auth-primary-button w-full py-3 px-4 flex items-center justify-center gap-2\"\n >\n {isReactivating ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>Reactivating…</span>\n </>\n ) : (\n <>\n <svg\n className=\"size-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n <span>\n {tr(\"auth.reactivate.reactivateBtn\", \"Reactivate Account\")}\n </span>\n </>\n )}\n </button>\n </form>\n\n {/* Links */}\n <div className=\"mt-8 pt-6 border-t border-[var(--color-border-default)] space-y-4\">\n <div className=\"text-center\">\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n {tr(\n \"auth.reactivate.accountIsActive\",\n \"Remember your account is active?\",\n )}{\" \"}\n <span className=\"font-semibold text-text-link hover:text-text-linkHover\">\n {tr(\"auth.reactivate.signInInstead\", \"Sign in instead\")}\n </span>\n </button>\n </div>\n\n <div className=\"text-center\">\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/reset-password\")}\n className=\"text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n {tr(\"auth.reactivate.forgotPassword\", \"Forgot your password?\")}{\" \"}\n <span className=\"font-semibold text-accent-purple hover:text-accent-purple\">\n {tr(\"auth.reactivate.resetIt\", \"Reset it\")}\n </span>\n </button>\n </div>\n </div>\n\n {/* Help Text */}\n <div className=\"mt-6 p-4 rounded-xl bg-[var(--color-bg-muted)] border border-[var(--color-border-default)]\">\n <h4 className=\"text-sm font-medium text-[var(--color-text-primary)] mb-2\">\n {tr(\n \"auth.reactivate.cantReactivate\",\n \"Can't reactivate your account?\",\n )}\n </h4>\n <p className=\"text-xs text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.reactivate.deletedHelp\",\n \"If your account was deleted (not just deactivated), it cannot be restored. Contact support if you believe this is an error.\",\n )}\n </p>\n </div>\n </AuthLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactivatePage.js","names":[],"sources":["../../../src/auth/pages/ReactivatePage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useNavigate, useLocation } from \"react-router-dom\";\nimport { useAccountOperations } from \"../hooks/useAccountOperations\";\nimport { AuthLayout } from \"../components/AuthLayout\";\nimport { Button } from \"@burdenoff/fe-libs/button\";\nimport { PagePurpose } from \"@burdenoff/fe-libs/ui\";\nimport {\n EmailIcon,\n LockIcon,\n SpinnerIcon,\n AlertIcon,\n} from \"../components/AuthIcons\";\n\n/**\n * Account Reactivation Page\n * Allows users to reactivate their deactivated accounts\n */\nexport function ReactivatePage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const navigate = useNavigate();\n const location = useLocation();\n const { reactivateAccount, isReactivating } = useAccountOperations();\n\n // Get email from navigation state (passed from login page)\n const emailFromState = (location.state as { email?: string })?.email || \"\";\n\n const [email, setEmail] = useState(emailFromState);\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n\n // Update email if passed from login page\n useEffect(() => {\n if (emailFromState) {\n setEmail(emailFromState);\n }\n }, [emailFromState]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n if (!email || !password) {\n setError(\n tr(\"auth.reactivate.enterBoth\", \"Please enter both email and password\"),\n );\n return;\n }\n\n try {\n const result = await reactivateAccount(email, password);\n\n if (result.success) {\n setSuccess(true);\n // Redirect to dashboard after short delay\n setTimeout(() => {\n navigate(\"/dashboard\", { replace: true });\n }, 2000);\n } else {\n setError(result.error || \"Failed to reactivate account\");\n }\n } catch (err) {\n console.error(\"Reactivation error:\", err);\n setError(\n err instanceof Error ? err.message : \"An unexpected error occurred\",\n );\n }\n };\n\n if (success) {\n return (\n <AuthLayout\n title={tr(\"auth.reactivate.successTitle\", \"Account Reactivated!\")}\n subtitle={tr(\"auth.reactivate.successSubtitle\", \"Welcome back\")}\n >\n <div className=\"text-center py-8\">\n <div className=\"size-20 mx-auto mb-6 rounded-full bg-[var(--color-status-success-bg-subtle)] flex items-center justify-center\">\n <svg\n className=\"size-10 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)] mb-2\">\n {tr(\"auth.reactivate.accountActive\", \"Your account is now active\")}\n </h2>\n <p className=\"text-[var(--color-text-secondary)] mb-6\">\n {tr(\n \"auth.reactivate.redirecting\",\n \"You can now access all features. Redirecting to dashboard...\",\n )}\n </p>\n\n <div className=\"flex justify-center\">\n <SpinnerIcon className=\"size-6 text-status-success-text animate-spin\" />\n </div>\n </div>\n </AuthLayout>\n );\n }\n\n return (\n <AuthLayout\n title={tr(\"auth.reactivate.title\", \"Reactivate Account\")}\n subtitle={tr(\n \"auth.reactivate.subtitle\",\n \"Restore access to your deactivated account\",\n )}\n >\n <PagePurpose className=\"mb-5\">\n {tr(\n \"auth.reactivate.purpose\",\n \"Reactivate an account you previously deactivated. Confirm your email and password to restore full access — deleted accounts can't be recovered here.\",\n )}\n </PagePurpose>\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n {/* Error Alert */}\n {error && (\n <div className=\"flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <AlertIcon className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\" />\n <div className=\"flex-1\">\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n </div>\n </div>\n )}\n\n {/* Info Banner */}\n <div className=\"p-4 rounded-xl bg-[var(--color-status-warning-bg-subtle)] border border-[var(--color-status-warning-border)]\">\n <div className=\"flex items-start gap-3\">\n <svg\n className=\"size-5 text-[var(--color-status-warning-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <div>\n <p className=\"text-sm text-[var(--color-status-warning-text)] font-medium\">\n {tr(\"auth.reactivate.deactivated\", \"Account Deactivated?\")}\n </p>\n <p className=\"text-xs text-[var(--color-status-warning-text)] mt-1\">\n {tr(\n \"auth.reactivate.instructions\",\n \"If you previously deactivated your account, you can restore it here. Enter your email and password to reactivate.\",\n )}\n </p>\n </div>\n </div>\n </div>\n\n {/* Email Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"email\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.reactivate.emailLabel\", \"Email Address\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <EmailIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"email\"\n type=\"email\"\n required\n aria-label={tr(\"auth.reactivate.emailLabel\", \"Email Address\")}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-status-success-bg/20 focus:border-status-success-border transition-all\"\n placeholder=\"you@example.com\"\n />\n </div>\n </div>\n\n {/* Password Input */}\n <div className=\"space-y-2\">\n <label\n htmlFor=\"password\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)]\"\n >\n {tr(\"auth.reactivate.passwordLabel\", \"Password\")}\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none\">\n <LockIcon className=\"size-5 text-[var(--color-text-tertiary)]\" />\n </div>\n <input\n id=\"password\"\n type=\"password\"\n required\n aria-label={tr(\"auth.reactivate.passwordLabel\", \"Password\")}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n className=\"block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-status-success-bg/20 focus:border-status-success-border transition-all\"\n placeholder={tr(\n \"auth.reactivate.passwordPlaceholder\",\n \"Enter your password\",\n )}\n />\n </div>\n </div>\n\n {/* Submit Button */}\n <Button\n type=\"submit\"\n disabled={isReactivating || !email || !password}\n variant=\"default\"\n size=\"lg\"\n className=\"w-full font-semibold\"\n >\n {isReactivating ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>Reactivating…</span>\n </>\n ) : (\n <>\n <svg\n className=\"size-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n <span>\n {tr(\"auth.reactivate.reactivateBtn\", \"Reactivate Account\")}\n </span>\n </>\n )}\n </Button>\n </form>\n\n {/* Links */}\n <div className=\"mt-8 pt-6 border-t border-[var(--color-border-default)] space-y-4\">\n <div className=\"text-center\">\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n {tr(\n \"auth.reactivate.accountIsActive\",\n \"Remember your account is active?\",\n )}{\" \"}\n <span className=\"font-semibold text-text-link hover:text-text-linkHover\">\n {tr(\"auth.reactivate.signInInstead\", \"Sign in instead\")}\n </span>\n </button>\n </div>\n\n <div className=\"text-center\">\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/reset-password\")}\n className=\"text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n {tr(\"auth.reactivate.forgotPassword\", \"Forgot your password?\")}{\" \"}\n <span className=\"font-semibold text-accent-purple hover:text-accent-purple\">\n {tr(\"auth.reactivate.resetIt\", \"Reset it\")}\n </span>\n </button>\n </div>\n </div>\n\n {/* Help Text */}\n <div className=\"mt-6 p-4 rounded-xl bg-[var(--color-bg-muted)] border border-[var(--color-border-default)]\">\n <h4 className=\"text-sm font-medium text-[var(--color-text-primary)] mb-2\">\n {tr(\n \"auth.reactivate.cantReactivate\",\n \"Can't reactivate your account?\",\n )}\n </h4>\n <p className=\"text-xs text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.reactivate.deletedHelp\",\n \"If your account was deleted (not just deactivated), it cannot be restored. Contact support if you believe this is an error.\",\n )}\n </p>\n </div>\n </AuthLayout>\n );\n}\n"],"mappings":"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"}