@tinyrack/tinyauth-server 0.7.0 → 0.8.0

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 (104) hide show
  1. package/dist/services/account-selection.service.d.ts.map +1 -1
  2. package/dist/services/account-selection.service.js +5 -2
  3. package/dist/services/account-selection.service.js.map +1 -1
  4. package/dist/services/oauth-authorize.service.d.ts.map +1 -1
  5. package/dist/services/oauth-authorize.service.js +3 -1
  6. package/dist/services/oauth-authorize.service.js.map +1 -1
  7. package/package.json +1 -1
  8. package/public/assets/2fa-DZSOQLyd.js +2 -0
  9. package/public/assets/{2fa-Cteolf9l.js.map → 2fa-DZSOQLyd.js.map} +1 -1
  10. package/public/assets/2fa-DvD9N_wj.js +2 -0
  11. package/public/assets/{2fa-BMEIiDXv.js.map → 2fa-DvD9N_wj.js.map} +1 -1
  12. package/public/assets/{2fa-BhCgCfEc.js → 2fa-P8YqnDXC.js} +2 -2
  13. package/public/assets/{2fa-BhCgCfEc.js.map → 2fa-P8YqnDXC.js.map} +1 -1
  14. package/public/assets/{2fa-E0x3Samn.js → 2fa-fLX-LED8.js} +2 -2
  15. package/public/assets/{2fa-E0x3Samn.js.map → 2fa-fLX-LED8.js.map} +1 -1
  16. package/public/assets/{admin-CXJ0z2QN.js → admin-BLPp8bT8.js} +2 -2
  17. package/public/assets/{admin-CXJ0z2QN.js.map → admin-BLPp8bT8.js.map} +1 -1
  18. package/public/assets/{consent-C-h_pWHQ.js → consent-CjXe4bU5.js} +2 -2
  19. package/public/assets/{consent-C-h_pWHQ.js.map → consent-CjXe4bU5.js.map} +1 -1
  20. package/public/assets/consent-Cq6tCfwA.js +2 -0
  21. package/public/assets/{consent-B17hGrta.js.map → consent-Cq6tCfwA.js.map} +1 -1
  22. package/public/assets/{email-DjE7mqnX.js → email-CpOX6Ig_.js} +2 -2
  23. package/public/assets/email-CpOX6Ig_.js.map +1 -0
  24. package/public/assets/email-DvD9N_wj.js +2 -0
  25. package/public/assets/email-DvD9N_wj.js.map +1 -0
  26. package/public/assets/{error-BKXsXhdR.js → error-DMzYyopT.js} +2 -2
  27. package/public/assets/{error-BKXsXhdR.js.map → error-DMzYyopT.js.map} +1 -1
  28. package/public/assets/forgot-DvD9N_wj.js +2 -0
  29. package/public/assets/{forgot-BMEIiDXv.js.map → forgot-DvD9N_wj.js.map} +1 -1
  30. package/public/assets/{forgot-C9zSfaX9.js → forgot-RbSzzjWF.js} +2 -2
  31. package/public/assets/{forgot-C9zSfaX9.js.map → forgot-RbSzzjWF.js.map} +1 -1
  32. package/public/assets/{index-BmfaaNx6.js → index-CgkA6nnx.js} +3 -3
  33. package/public/assets/index-CgkA6nnx.js.map +1 -0
  34. package/public/assets/{login-DG1Yfmb8.js → login-BQI7QY9W.js} +2 -2
  35. package/public/assets/login-BQI7QY9W.js.map +1 -0
  36. package/public/assets/login-DvD9N_wj.js +2 -0
  37. package/public/assets/login-DvD9N_wj.js.map +1 -0
  38. package/public/assets/{passkey-BDrX3jVg.js → passkey-C0BKdldQ.js} +2 -2
  39. package/public/assets/passkey-C0BKdldQ.js.map +1 -0
  40. package/public/assets/{passkey-C-h8Fvqn.js → passkey-D9qQ8xoR.js} +2 -2
  41. package/public/assets/passkey-D9qQ8xoR.js.map +1 -0
  42. package/public/assets/password-CqjbZggE.js +2 -0
  43. package/public/assets/password-CqjbZggE.js.map +1 -0
  44. package/public/assets/password-DvD9N_wj.js +2 -0
  45. package/public/assets/password-DvD9N_wj.js.map +1 -0
  46. package/public/assets/{profile-8buOY6GT.js → profile-B5qQlPwW.js} +2 -2
  47. package/public/assets/{profile-8buOY6GT.js.map → profile-B5qQlPwW.js.map} +1 -1
  48. package/public/assets/profile-fwH7_EJ0.js +2 -0
  49. package/public/assets/{profile-DcpL_XUt.js.map → profile-fwH7_EJ0.js.map} +1 -1
  50. package/public/assets/{recovery-Csf6dtvj.js → recovery-DqEhUHzv.js} +2 -2
  51. package/public/assets/{recovery-Csf6dtvj.js.map → recovery-DqEhUHzv.js.map} +1 -1
  52. package/public/assets/{register-X6dycne4.js → register-CntgI-rd.js} +2 -2
  53. package/public/assets/register-CntgI-rd.js.map +1 -0
  54. package/public/assets/register-DvD9N_wj.js +2 -0
  55. package/public/assets/register-DvD9N_wj.js.map +1 -0
  56. package/public/assets/{reset-1nsqPlxL.js → reset-BK1XYJiv.js} +2 -2
  57. package/public/assets/{reset-1nsqPlxL.js.map → reset-BK1XYJiv.js.map} +1 -1
  58. package/public/assets/reset-DvD9N_wj.js +2 -0
  59. package/public/assets/{reset-BMEIiDXv.js.map → reset-DvD9N_wj.js.map} +1 -1
  60. package/public/assets/{select-CDdb3jyc.js → select-DeUoTgDw.js} +2 -2
  61. package/public/assets/{select-CDdb3jyc.js.map → select-DeUoTgDw.js.map} +1 -1
  62. package/public/assets/select-DvD9N_wj.js +2 -0
  63. package/public/assets/{select-BMEIiDXv.js.map → select-DvD9N_wj.js.map} +1 -1
  64. package/public/assets/{terms-CUhvMN9k.js → terms-CPEuXMaO.js} +2 -2
  65. package/public/assets/{terms-CUhvMN9k.js.map → terms-CPEuXMaO.js.map} +1 -1
  66. package/public/assets/terms-fwH7_EJ0.js +2 -0
  67. package/public/assets/{terms-DcpL_XUt.js.map → terms-fwH7_EJ0.js.map} +1 -1
  68. package/public/assets/{totp-DB9WqW4V.js → totp-B1ebEiOW.js} +2 -2
  69. package/public/assets/totp-B1ebEiOW.js.map +1 -0
  70. package/public/assets/{totp-UDT2P91H.js → totp-DWWZe-tJ.js} +2 -2
  71. package/public/assets/totp-DWWZe-tJ.js.map +1 -0
  72. package/public/assets/{use-totp-setup-9fktn_he.js → use-totp-setup-Z96pOMXt.js} +2 -2
  73. package/public/assets/{use-totp-setup-9fktn_he.js.map → use-totp-setup-Z96pOMXt.js.map} +1 -1
  74. package/public/assets/{useMutation-Iu4AJCB4.js → useMutation-Biy2-pH_.js} +2 -2
  75. package/public/assets/{useMutation-Iu4AJCB4.js.map → useMutation-Biy2-pH_.js.map} +1 -1
  76. package/public/assets/{users-Bi7gjreq.js → users-YtDGJlDl.js} +2 -2
  77. package/public/assets/{users-Bi7gjreq.js.map → users-YtDGJlDl.js.map} +1 -1
  78. package/public/index.html +1 -1
  79. package/public/assets/2fa-BMEIiDXv.js +0 -2
  80. package/public/assets/2fa-Cteolf9l.js +0 -2
  81. package/public/assets/consent-B17hGrta.js +0 -2
  82. package/public/assets/email-BMEIiDXv.js +0 -2
  83. package/public/assets/email-BMEIiDXv.js.map +0 -1
  84. package/public/assets/email-DjE7mqnX.js.map +0 -1
  85. package/public/assets/forgot-BMEIiDXv.js +0 -2
  86. package/public/assets/index-BmfaaNx6.js.map +0 -1
  87. package/public/assets/login-BMEIiDXv.js +0 -2
  88. package/public/assets/login-BMEIiDXv.js.map +0 -1
  89. package/public/assets/login-DG1Yfmb8.js.map +0 -1
  90. package/public/assets/passkey-BDrX3jVg.js.map +0 -1
  91. package/public/assets/passkey-C-h8Fvqn.js.map +0 -1
  92. package/public/assets/password-86C-hCze.js +0 -2
  93. package/public/assets/password-86C-hCze.js.map +0 -1
  94. package/public/assets/password-BMEIiDXv.js +0 -2
  95. package/public/assets/password-BMEIiDXv.js.map +0 -1
  96. package/public/assets/profile-DcpL_XUt.js +0 -2
  97. package/public/assets/register-BMEIiDXv.js +0 -2
  98. package/public/assets/register-BMEIiDXv.js.map +0 -1
  99. package/public/assets/register-X6dycne4.js.map +0 -1
  100. package/public/assets/reset-BMEIiDXv.js +0 -2
  101. package/public/assets/select-BMEIiDXv.js +0 -2
  102. package/public/assets/terms-DcpL_XUt.js +0 -2
  103. package/public/assets/totp-DB9WqW4V.js.map +0 -1
  104. package/public/assets/totp-UDT2P91H.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{o as e,r as t,s as n,u as r}from"./IconBase.es-d5KP98Ac.js";import{Q as i,a,i as o,n as s,ut as c}from"./use-theme-cVUDAjtt.js";import{t as l}from"./useMutation-Iu4AJCB4.js";import{t as u}from"./mutationOptions-Dfvzj6n2.js";import{t as d}from"./CheckCircle.es-MnJIACCe.js";import{t as f}from"./page-layout-C475gs09.js";import{t as p}from"./EnvelopeSimple.es-BZ7u3LYh.js";import{t as m}from"./Key.es-l5aSxw0I.js";import{c as h,o as g}from"./zod-BItJDQBQ.js";import{A as _,F as v,M as y,S as b,j as x,p as S}from"./index-BmfaaNx6.js";import{t as C}from"./page-header-BYMFSGfT.js";import{t as w}from"./alert-CSXqgDVi.js";import{t as T}from"./promise-OpBtq8tG.js";import{r as E,t as D}from"./standard-schema-o4V-s4uY.js";import{t as O}from"./icon-input-8iU7PNzd.js";import{t as k}from"./submit-button-Xx6DwLyh.js";var A=r(n()),j=e();function M({text:e,className:t=``}){return(0,j.jsxs)(`div`,{className:`my-4 flex items-center ${t}`,children:[(0,j.jsx)(`div`,{className:`h-px flex-1 bg-base-200`}),e&&(0,j.jsx)(`span`,{className:`px-3 text-base-content/60 text-sm`,children:e}),(0,j.jsx)(`div`,{className:`h-px flex-1 bg-base-200`})]})}var N=u({mutationFn:async e=>a(await o.api.auth.email.verify.$post({json:e}))}),P=u({mutationFn:async e=>a(await o.api.auth.email.resend.$post({json:e,header:{}}))});function F(){let{t:e}=t(),n=v(),r=c(),a=S.useSearch(),{token:o,email:u}=a,[F,I]=(0,A.useState)(!1),[L,R]=(0,A.useState)(!1),{data:z}=i(s),B=(0,A.useMemo)(()=>g({token:h().min(1,e(`validation.token.required`))}),[e]),V=l({...N,onSuccess:async e=>{let t=e.user;if(r.setQueryData(b.queryKey,{user:t}),await T(),t.second_factor_required){let e=[];return z.auth.password.totp.enabled&&e.push(`totp`),z.auth.passkey.enabled&&e.push(`passkey`),e.length===1?e[0]===`totp`?n({to:`/setup/totp`,search:x(a)}):n({to:`/setup/passkey`,search:x(a)}):n({to:`/setup/2fa`,search:x(a)})}y(a)?window.location.href=_(a):I(!0)},onSettled:()=>{r.invalidateQueries({queryKey:b.queryKey})}}),H=l({...P,onSuccess:()=>{R(!0),setTimeout(()=>R(!1),5e3)}}),{register:U,setError:W,handleSubmit:G,formState:{errors:K}}=E({defaultValues:{token:o||``},resolver:D(B)}),q=async t=>{try{await V.mutateAsync(t)}catch{W(`token`,{type:`manual`,message:e(`verifyEmail.error.invalidToken`)})}},J=async()=>{if(u)try{await H.mutateAsync({email:u})}catch{}};return F?(0,j.jsxs)(f,{cardPadding:!0,maxWidth:`100`,children:[(0,j.jsx)(w,{className:`mb-4`,icon:d,type:`success`,children:e(`verifyEmail.success.title`)}),(0,j.jsx)(C,{subtitle:e(`verifyEmail.success.description`),title:e(`verifyEmail.success.subtitle`)}),(0,j.jsx)(`button`,{className:`btn btn-block h-10 font-semibold text-[14px]`,"data-testid":`email-verify-go-profile`,onClick:()=>n({to:`/profile`}),type:`button`,children:e(`verifyEmail.success.goToProfile`)})]}):(0,j.jsxs)(f,{cardPadding:!0,maxWidth:`100`,children:[(0,j.jsx)(C,{subtitle:e(`verifyEmail.subtitle`),title:e(`verifyEmail.title`)}),u&&(0,j.jsx)(w,{className:`mb-4`,icon:p,type:`info`,children:(0,j.jsxs)(`div`,{className:`text-left`,children:[(0,j.jsx)(`p`,{className:`font-semibold`,children:e(`register.success.subtitle`)}),(0,j.jsx)(`p`,{className:`text-xs`,children:e(`register.success.description`,{email:u})})]})}),(0,j.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:G(q),children:[(0,j.jsx)(O,{error:K.token,icon:m,placeholder:e(`verifyEmail.token.placeholder`),...U(`token`),type:`text`}),(0,j.jsx)(k,{className:`mt-2`,isPending:V.isPending,pendingText:e(`verifyEmail.submitting`),children:e(`verifyEmail.submit`)})]}),u&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(M,{}),L&&(0,j.jsx)(w,{className:`mb-2`,icon:d,type:`success`,children:e(`verifyEmail.resendSuccess`)}),(0,j.jsx)(`button`,{className:`btn btn-ghost btn-sm w-full`,"data-testid":`email-verify-resend`,disabled:H.isPending||L,onClick:J,type:`button`,children:H.isPending?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`span`,{className:`loading loading-spinner loading-xs`}),e(`verifyEmail.resending`)]}):e(`verifyEmail.resend`)})]})]})}export{F as component};
2
- //# sourceMappingURL=email-DjE7mqnX.js.map
1
+ import{o as e,r as t,s as n,u as r}from"./IconBase.es-d5KP98Ac.js";import{Q as i,a,i as o,n as s,ut as c}from"./use-theme-cVUDAjtt.js";import{t as l}from"./useMutation-Biy2-pH_.js";import{t as u}from"./mutationOptions-Dfvzj6n2.js";import{t as d}from"./CheckCircle.es-MnJIACCe.js";import{t as f}from"./page-layout-C475gs09.js";import{t as p}from"./EnvelopeSimple.es-BZ7u3LYh.js";import{t as m}from"./Key.es-l5aSxw0I.js";import{c as h,o as g}from"./zod-BItJDQBQ.js";import{A as _,I as v,M as y,N as b,S as x,p as S}from"./index-CgkA6nnx.js";import{t as C}from"./page-header-BYMFSGfT.js";import{t as w}from"./alert-CSXqgDVi.js";import{t as T}from"./promise-OpBtq8tG.js";import{r as E,t as D}from"./standard-schema-o4V-s4uY.js";import{t as O}from"./icon-input-8iU7PNzd.js";import{t as k}from"./submit-button-Xx6DwLyh.js";var A=r(n()),j=e();function M({text:e,className:t=``}){return(0,j.jsxs)(`div`,{className:`my-4 flex items-center ${t}`,children:[(0,j.jsx)(`div`,{className:`h-px flex-1 bg-base-200`}),e&&(0,j.jsx)(`span`,{className:`px-3 text-base-content/60 text-sm`,children:e}),(0,j.jsx)(`div`,{className:`h-px flex-1 bg-base-200`})]})}var N=u({mutationFn:async e=>a(await o.api.auth.email.verify.$post({json:e}))}),P=u({mutationFn:async e=>a(await o.api.auth.email.resend.$post({json:e,header:{}}))});function F(){let{t:e}=t(),n=v(),r=c(),a=S.useSearch(),{token:o,email:u}=a,[F,I]=(0,A.useState)(!1),[L,R]=(0,A.useState)(!1),{data:z}=i(s),B=(0,A.useMemo)(()=>g({token:h().min(1,e(`validation.token.required`))}),[e]),V=l({...N,onSuccess:async e=>{let t=e.user;if(r.setQueryData(x.queryKey,{user:t}),await T(),t.second_factor_required){let e=[];return z.auth.password.totp.enabled&&e.push(`totp`),z.auth.passkey.enabled&&e.push(`passkey`),e.length===1?e[0]===`totp`?n({to:`/setup/totp`,search:y(a)}):n({to:`/setup/passkey`,search:y(a)}):n({to:`/setup/2fa`,search:y(a)})}b(a)?window.location.href=_(a):I(!0)},onSettled:()=>{r.invalidateQueries({queryKey:x.queryKey})}}),H=l({...P,onSuccess:()=>{R(!0),setTimeout(()=>R(!1),5e3)}}),{register:U,setError:W,handleSubmit:G,formState:{errors:K}}=E({defaultValues:{token:o||``},resolver:D(B)}),q=async t=>{try{await V.mutateAsync(t)}catch{W(`token`,{type:`manual`,message:e(`verifyEmail.error.invalidToken`)})}},J=async()=>{if(u)try{await H.mutateAsync({email:u})}catch{}};return F?(0,j.jsxs)(f,{cardPadding:!0,maxWidth:`100`,children:[(0,j.jsx)(w,{className:`mb-4`,icon:d,type:`success`,children:e(`verifyEmail.success.title`)}),(0,j.jsx)(C,{subtitle:e(`verifyEmail.success.description`),title:e(`verifyEmail.success.subtitle`)}),(0,j.jsx)(`button`,{className:`btn btn-block h-10 font-semibold text-[14px]`,"data-testid":`email-verify-go-profile`,onClick:()=>n({to:`/profile`}),type:`button`,children:e(`verifyEmail.success.goToProfile`)})]}):(0,j.jsxs)(f,{cardPadding:!0,maxWidth:`100`,children:[(0,j.jsx)(C,{subtitle:e(`verifyEmail.subtitle`),title:e(`verifyEmail.title`)}),u&&(0,j.jsx)(w,{className:`mb-4`,icon:p,type:`info`,children:(0,j.jsxs)(`div`,{className:`text-left`,children:[(0,j.jsx)(`p`,{className:`font-semibold`,children:e(`register.success.subtitle`)}),(0,j.jsx)(`p`,{className:`text-xs`,children:e(`register.success.description`,{email:u})})]})}),(0,j.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:G(q),children:[(0,j.jsx)(O,{error:K.token,icon:m,placeholder:e(`verifyEmail.token.placeholder`),...U(`token`),type:`text`}),(0,j.jsx)(k,{className:`mt-2`,isPending:V.isPending,pendingText:e(`verifyEmail.submitting`),children:e(`verifyEmail.submit`)})]}),u&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(M,{}),L&&(0,j.jsx)(w,{className:`mb-2`,icon:d,type:`success`,children:e(`verifyEmail.resendSuccess`)}),(0,j.jsx)(`button`,{className:`btn btn-ghost btn-sm w-full`,"data-testid":`email-verify-resend`,disabled:H.isPending||L,onClick:J,type:`button`,children:H.isPending?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`span`,{className:`loading loading-spinner loading-xs`}),e(`verifyEmail.resending`)]}):e(`verifyEmail.resend`)})]})]})}export{F as component};
2
+ //# sourceMappingURL=email-CpOX6Ig_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-CpOX6Ig_.js","names":["standardSchemaResolver","CheckCircleIcon","EnvelopeSimpleIcon","KeyIcon","useMutation","useQueryClient","useSuspenseQuery","useNavigate","useMemo","useState","useForm","useTranslation","z","IconInput","PageHeader","SubmitButton","Alert","Divider","PageLayout","buildAuthenticatedAuthorizeUrl","extractOAuthParams","isOAuthFlow","tick","appConfigQueryOptions","getSessionQueryOptions","resendVerificationMutationOptions","verifyEmailMutationOptions","Route","VerifyEmailFormValues","token","VerifyEmail","t","navigate","queryClient","search","useSearch","queryToken","email","verified","setVerified","resendSuccess","setResendSuccess","data","appConfig","verifyEmailSchema","object","string","min","verifyEmailMutation","onSuccess","user","setQueryData","queryKey","second_factor_required","available_2fa_methods","SecondFactorMethod","auth","password","totp","enabled","push","passkey","length","method","to","window","location","href","onSettled","invalidateQueries","resendVerificationMutation","setTimeout","register","setError","handleSubmit","formState","errors","defaultValues","resolver","onSubmit","values","mutateAsync","_error","type","message","handleResend","isPending","component"],"sources":["../../../frontend/src/components/ui/divider.tsx","../../../frontend/src/queries/verify-email.ts","../../../frontend/src/routes/verify/email/index.tsx?tsr-split=component"],"sourcesContent":["type DividerProps = {\n text?: string;\n className?: string;\n};\n\nexport function Divider({ text, className = '' }: DividerProps) {\n return (\n <div className={`my-4 flex items-center ${className}`}>\n <div className=\"h-px flex-1 bg-base-200\" />\n {text && (\n <span className=\"px-3 text-base-content/60 text-sm\">{text}</span>\n )}\n <div className=\"h-px flex-1 bg-base-200\" />\n </div>\n );\n}\n","import { mutationOptions } from '@tanstack/react-query';\nimport type { InferRequestType, InferResponseType } from 'hono/client';\nimport { client, jsonOk } from '#frontend/libs/api.ts';\n\nexport type VerifyEmailParams = InferRequestType<\n (typeof client.api.auth.email.verify)['$post']\n>['json'];\n\nexport type VerifyEmailResponse = InferResponseType<\n (typeof client.api.auth.email.verify)['$post'],\n 200\n>;\n\nexport const verifyEmailMutationOptions = mutationOptions({\n mutationFn: async (values: VerifyEmailParams) => {\n const res = await client.api.auth.email.verify.$post({\n json: values,\n });\n return jsonOk(res);\n },\n});\n\nexport type ResendVerificationParams = InferRequestType<\n (typeof client.api.auth.email.resend)['$post']\n>['json'];\n\nexport type ResendVerificationResponse = InferResponseType<\n (typeof client.api.auth.email.resend)['$post'],\n 200\n>;\n\nexport const resendVerificationMutationOptions = mutationOptions({\n mutationFn: async (values: ResendVerificationParams) => {\n const res = await client.api.auth.email.resend.$post({\n json: values,\n header: {},\n });\n return jsonOk(res);\n },\n});\n","import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n EnvelopeSimpleIcon,\n KeyIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { Divider } from '#frontend/components/ui/divider.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthenticatedAuthorizeUrl,\n extractOAuthParams,\n isOAuthFlow,\n OAuthSearchSchema,\n type SecondFactorMethod,\n} from '#frontend/libs/oauth-search.ts';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport {\n resendVerificationMutationOptions,\n verifyEmailMutationOptions,\n} from '#frontend/queries/verify-email.ts';\n\nconst SearchSchema = z.object({\n ...OAuthSearchSchema.shape,\n token: z.string().default(''),\n email: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/verify/email/')({\n component: VerifyEmail,\n errorComponent: RouteErrorFallback,\n validateSearch: SearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype VerifyEmailFormValues = {\n token: string;\n};\n\nfunction VerifyEmail() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n const { token: queryToken, email } = search;\n const [verified, setVerified] = useState(false);\n const [resendSuccess, setResendSuccess] = useState(false);\n const { data: appConfig } = useSuspenseQuery(appConfigQueryOptions);\n\n const verifyEmailSchema = useMemo(\n () =>\n z.object({\n token: z.string().min(1, t('validation.token.required')),\n }),\n [t],\n );\n\n const verifyEmailMutation = useMutation({\n ...verifyEmailMutationOptions,\n onSuccess: async (data) => {\n const user = data.user;\n\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: user,\n });\n await tick();\n\n if (user.second_factor_required) {\n const available_2fa_methods: SecondFactorMethod[] = [];\n if (appConfig.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (appConfig.auth.passkey.enabled) {\n available_2fa_methods.push('passkey');\n }\n\n if (available_2fa_methods.length === 1) {\n const method = available_2fa_methods[0];\n if (method === 'totp') {\n return navigate({\n to: '/setup/totp',\n search: extractOAuthParams(search),\n });\n } else {\n return navigate({\n to: '/setup/passkey',\n search: extractOAuthParams(search),\n });\n }\n } else {\n return navigate({\n to: '/setup/2fa',\n search: extractOAuthParams(search),\n });\n }\n }\n\n if (isOAuthFlow(search)) {\n window.location.href = buildAuthenticatedAuthorizeUrl(search);\n } else {\n setVerified(true);\n }\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const resendVerificationMutation = useMutation({\n ...resendVerificationMutationOptions,\n onSuccess: () => {\n setResendSuccess(true);\n setTimeout(() => setResendSuccess(false), 5000);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<VerifyEmailFormValues>({\n defaultValues: {\n token: queryToken || '',\n },\n resolver: standardSchemaResolver(verifyEmailSchema),\n });\n\n const onSubmit = async (values: VerifyEmailFormValues) => {\n try {\n await verifyEmailMutation.mutateAsync(values);\n } catch (_error) {\n setError('token', {\n type: 'manual',\n message: t('verifyEmail.error.invalidToken'),\n });\n }\n };\n\n const handleResend = async () => {\n if (!email) {\n return;\n }\n try {\n await resendVerificationMutation.mutateAsync({ email });\n } catch (_error) {}\n };\n\n if (verified) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('verifyEmail.success.description')}\n title={t('verifyEmail.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"email-verify-go-profile\"\n onClick={() => navigate({ to: '/profile' })}\n type=\"button\"\n >\n {t('verifyEmail.success.goToProfile')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('verifyEmail.subtitle')}\n title={t('verifyEmail.title')}\n />\n\n {email && (\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n <div className=\"text-left\">\n <p className=\"font-semibold\">{t('register.success.subtitle')}</p>\n <p className=\"text-xs\">\n {t('register.success.description', { email })}\n </p>\n </div>\n </Alert>\n )}\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('verifyEmail.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={verifyEmailMutation.isPending}\n pendingText={t('verifyEmail.submitting')}\n >\n {t('verifyEmail.submit')}\n </SubmitButton>\n </form>\n\n {email && (\n <>\n <Divider />\n\n {resendSuccess && (\n <Alert className=\"mb-2\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.resendSuccess')}\n </Alert>\n )}\n\n <button\n className=\"btn btn-ghost btn-sm w-full\"\n data-testid=\"email-verify-resend\"\n disabled={resendVerificationMutation.isPending || resendSuccess}\n onClick={handleResend}\n type=\"button\"\n >\n {resendVerificationMutation.isPending ? (\n <>\n <span className=\"loading loading-spinner loading-xs\" />\n {t('verifyEmail.resending')}\n </>\n ) : (\n t('verifyEmail.resend')\n )}\n </button>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"o0BAKA,SAAA,EAAA,CAAA,OAAA,YAAA,IAAA,2QAUA,CCFA,IAAa,EAA6B,EAAgB,CACxD,WAAY,KAAO,IAIV,EAAO,MAHI,EAAO,IAAI,KAAK,MAAM,OAAO,MAAM,CACnD,KAAM,CACR,CAAC,CACgB,CAErB,CAAC,EAWY,EAAoC,EAAgB,CAC/D,WAAY,KAAO,IAKV,EAAO,MAJI,EAAO,IAAI,KAAK,MAAM,OAAO,MAAM,CACnD,KAAM,EACN,OAAQ,CAAC,CACX,CAAC,CACgB,CAErB,CAAC,EC2BD,SAAS8B,GAAc,CACrB,GAAM,CAAEC,KAAMpB,EAAe,EACvBqB,EAAWzB,EAAY,EACvB0B,EAAc5B,EAAe,EAC7B6B,EAASP,EAAMQ,UAAU,EACzB,CAAEN,MAAOO,EAAYC,SAAUH,EAC/B,CAACI,EAAUC,IAAAA,EAAAA,EAAAA,UAAwB,EAAK,EACxC,CAACC,EAAeC,IAAAA,EAAAA,EAAAA,UAA6B,EAAK,EAClD,CAAEC,KAAMC,GAAcrC,EAAiBiB,CAAqB,EAE5DqB,GAAAA,EAAAA,EAAAA,aAEFhC,EAAS,CACPiB,MAAOjB,EAAS,EAAEmC,IAAI,EAAGhB,EAAE,2BAA2B,CAAC,CACzD,CAAC,EACH,CAACA,CAAC,CACJ,EAEMiB,EAAsB5C,EAAY,CACtC,GAAGsB,EACHuB,UAAW,KAAOP,IAAS,CACzB,IAAMQ,EAAOR,EAAKQ,KAOlB,GALAjB,EAAYkB,aAAa3B,EAAuB4B,SAAU,CAClDF,MACR,CAAC,EACD,MAAM5B,EAAK,EAEP4B,EAAKG,uBAAwB,CAC/B,IAAMC,EAA8C,CAAA,EAsBlD,OArBEX,EAAUa,KAAKC,SAASC,KAAKC,SAC/BL,EAAsBM,KAAK,MAAM,EAE/BjB,EAAUa,KAAKK,QAAQF,SACzBL,EAAsBM,KAAK,SAAS,EAGlCN,EAAsBQ,SAAW,EACpBR,EAAsB,KACtB,OACNtB,EAAS,CACdgC,GAAI,cACJ9B,OAAQd,EAAmBc,CAAM,CACnC,CAAC,EAEMF,EAAS,CACdgC,GAAI,iBACJ9B,OAAQd,EAAmBc,CAAM,CACnC,CAAC,EAGIF,EAAS,CACdgC,GAAI,aACJ9B,OAAQd,EAAmBc,CAAM,CACnC,CAAC,CAEL,CAEIb,EAAYa,CAAM,EACpB+B,OAAOC,SAASC,KAAOhD,EAA+Be,CAAM,EAE5DK,EAAY,EAAI,CAEpB,EACA6B,cAAiB,CACfnC,EAAYoC,kBAAkB,CAC5BjB,SAAU5B,EAAuB4B,QACnC,CAAC,CACH,CACF,CAAC,EAEKkB,EAA6BlE,EAAY,CAC7C,GAAGqB,EACHwB,cAAiB,CACfR,EAAiB,EAAI,EACrB8B,eAAiB9B,EAAiB,EAAK,EAAG,GAAI,CAChD,CACF,CAAC,EAEK,CACJ+B,WACAC,WACAC,eACAC,UAAW,CAAEC,WACXlE,EAA+B,CACjCmE,cAAe,CACbhD,MAAOO,GAAc,EACvB,EACA0C,SAAU9E,EAAuB4C,CAAiB,CACpD,CAAC,EAEKmC,EAAW,KAAOC,IAAkC,CACxD,GAAI,CACF,MAAMhC,EAAoBiC,YAAYD,CAAM,CAC9C,MAAiB,CACfP,EAAS,QAAS,CAChBU,KAAM,SACNC,QAASrD,EAAE,gCAAgC,CAC7C,CAAC,CACH,CACF,EAEMsD,EAAe,SAAY,CAC1BhD,KAGL,GAAI,CACF,MAAMiC,EAA2BW,YAAY,CAAE5C,OAAM,CAAC,CACxD,MAAiB,CAAC,CACpB,EA0BA,OAxBIC,GAEA,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMrC,EAAiB,KAAK,mBACjD8B,EAAE,2BAA2B,CACzB,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,iCAAiC,EAC7C,MAAOA,EAAE,8BAA8B,CAAE,CAAA,GAG3C,EAAA,EAAA,KAAC,SAAD,CACE,UAAU,+CACV,cAAY,0BACZ,YAAeC,EAAS,CAAEgC,GAAI,UAAW,CAAC,EAC1C,KAAK,kBAEJjC,EAAE,iCAAiC,CAC9B,CAAA,CACE,KAKd,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,sBAAsB,EAClC,MAAOA,EAAE,mBAAmB,CAAE,CAAA,EAG/BM,IACC,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMnC,EAAoB,KAAK,iBACrD,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yBAAiB6B,EAAE,2BAA2B,CAAK,CAAA,GAChE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,mBACVA,EAAE,+BAAgC,CAAEM,OAAM,CAAC,CAC3C,CAAA,CACA,GACA,CAAA,GAGT,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,sBAAsB,SAAUqC,EAAaK,CAAQ,WAArE,EACE,EAAA,EAAA,KAAC,EAAD,CACE,MAAOH,EAAO/C,MACd,KAAM1B,EACN,YAAa4B,EAAE,+BAA+B,EAC9C,GAAIyC,EAAS,OAAO,EACpB,KAAK,MAAM,CAAA,GAGb,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,OACV,UAAWxB,EAAoBsC,UAC/B,YAAavD,EAAE,wBAAwB,WAEtCA,EAAE,oBAAoB,CACX,CAAA,CACV,IAELM,IACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,CAAA,EAEPG,IACC,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMvC,EAAiB,KAAK,mBACjD8B,EAAE,2BAA2B,CACzB,CAAA,GAGT,EAAA,EAAA,KAAC,SAAD,CACE,UAAU,8BACV,cAAY,sBACZ,SAAUuC,EAA2BgB,WAAa9C,EAClD,QAAS6C,EACT,KAAK,kBAEJf,EAA2BgB,WAC1B,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oCAAoC,CAAA,EACnDvD,EAAE,uBAAuB,CAC5B,CAAA,CAAA,EAEAA,EAAE,oBAAoB,CAElB,CAAA,CACV,CAAA,CAAA,CAEQ,GAEhB"}
@@ -0,0 +1,2 @@
1
+ import{P as e}from"./index-CgkA6nnx.js";var t=e;export{t as errorComponent};
2
+ //# sourceMappingURL=email-DvD9N_wj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-DvD9N_wj.js","names":["RouteErrorFallback","VerifyEmailFormValues","token","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/verify/email/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n EnvelopeSimpleIcon,\n KeyIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { Divider } from '#frontend/components/ui/divider.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthenticatedAuthorizeUrl,\n extractOAuthParams,\n isOAuthFlow,\n OAuthSearchSchema,\n type SecondFactorMethod,\n} from '#frontend/libs/oauth-search.ts';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport {\n resendVerificationMutationOptions,\n verifyEmailMutationOptions,\n} from '#frontend/queries/verify-email.ts';\n\nconst SearchSchema = z.object({\n ...OAuthSearchSchema.shape,\n token: z.string().default(''),\n email: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/verify/email/')({\n component: VerifyEmail,\n errorComponent: RouteErrorFallback,\n validateSearch: SearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype VerifyEmailFormValues = {\n token: string;\n};\n\nfunction VerifyEmail() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n const { token: queryToken, email } = search;\n const [verified, setVerified] = useState(false);\n const [resendSuccess, setResendSuccess] = useState(false);\n const { data: appConfig } = useSuspenseQuery(appConfigQueryOptions);\n\n const verifyEmailSchema = useMemo(\n () =>\n z.object({\n token: z.string().min(1, t('validation.token.required')),\n }),\n [t],\n );\n\n const verifyEmailMutation = useMutation({\n ...verifyEmailMutationOptions,\n onSuccess: async (data) => {\n const user = data.user;\n\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: user,\n });\n await tick();\n\n if (user.second_factor_required) {\n const available_2fa_methods: SecondFactorMethod[] = [];\n if (appConfig.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (appConfig.auth.passkey.enabled) {\n available_2fa_methods.push('passkey');\n }\n\n if (available_2fa_methods.length === 1) {\n const method = available_2fa_methods[0];\n if (method === 'totp') {\n return navigate({\n to: '/setup/totp',\n search: extractOAuthParams(search),\n });\n } else {\n return navigate({\n to: '/setup/passkey',\n search: extractOAuthParams(search),\n });\n }\n } else {\n return navigate({\n to: '/setup/2fa',\n search: extractOAuthParams(search),\n });\n }\n }\n\n if (isOAuthFlow(search)) {\n window.location.href = buildAuthenticatedAuthorizeUrl(search);\n } else {\n setVerified(true);\n }\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const resendVerificationMutation = useMutation({\n ...resendVerificationMutationOptions,\n onSuccess: () => {\n setResendSuccess(true);\n setTimeout(() => setResendSuccess(false), 5000);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<VerifyEmailFormValues>({\n defaultValues: {\n token: queryToken || '',\n },\n resolver: standardSchemaResolver(verifyEmailSchema),\n });\n\n const onSubmit = async (values: VerifyEmailFormValues) => {\n try {\n await verifyEmailMutation.mutateAsync(values);\n } catch (_error) {\n setError('token', {\n type: 'manual',\n message: t('verifyEmail.error.invalidToken'),\n });\n }\n };\n\n const handleResend = async () => {\n if (!email) {\n return;\n }\n try {\n await resendVerificationMutation.mutateAsync({ email });\n } catch (_error) {}\n };\n\n if (verified) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('verifyEmail.success.description')}\n title={t('verifyEmail.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"email-verify-go-profile\"\n onClick={() => navigate({ to: '/profile' })}\n type=\"button\"\n >\n {t('verifyEmail.success.goToProfile')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('verifyEmail.subtitle')}\n title={t('verifyEmail.title')}\n />\n\n {email && (\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n <div className=\"text-left\">\n <p className=\"font-semibold\">{t('register.success.subtitle')}</p>\n <p className=\"text-xs\">\n {t('register.success.description', { email })}\n </p>\n </div>\n </Alert>\n )}\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('verifyEmail.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={verifyEmailMutation.isPending}\n pendingText={t('verifyEmail.submitting')}\n >\n {t('verifyEmail.submit')}\n </SubmitButton>\n </form>\n\n {email && (\n <>\n <Divider />\n\n {resendSuccess && (\n <Alert className=\"mb-2\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.resendSuccess')}\n </Alert>\n )}\n\n <button\n className=\"btn btn-ghost btn-sm w-full\"\n data-testid=\"email-verify-resend\"\n disabled={resendVerificationMutation.isPending || resendSuccess}\n onClick={handleResend}\n type=\"button\"\n >\n {resendVerificationMutation.isPending ? (\n <>\n <span className=\"loading loading-spinner loading-xs\" />\n {t('verifyEmail.resending')}\n </>\n ) : (\n t('verifyEmail.resend')\n )}\n </button>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"wCAgEE,IAAAG,EA3COH"}
@@ -1,2 +1,2 @@
1
- import{o as e,r as t,s as n,t as r,u as i}from"./IconBase.es-d5KP98Ac.js";import{f as a}from"./use-theme-cVUDAjtt.js";import{t as o}from"./page-layout-C475gs09.js";import{I as s,P as c}from"./index-BmfaaNx6.js";import{t as l}from"./page-header-BYMFSGfT.js";import{t as u}from"./alert-CSXqgDVi.js";var d=i(n(),1),f=new Map([[`bold`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M222.14,105.85l-80-80a20,20,0,0,0-28.28,0l-80,80A19.86,19.86,0,0,0,28,120v96a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V164h24v52a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V120A19.86,19.86,0,0,0,222.14,105.85ZM204,204H164V152a12,12,0,0,0-12-12H104a12,12,0,0,0-12,12v52H52V121.65l76-76,76,76Z`}))],[`duotone`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M216,120v96H152V152H104v64H40V120a8,8,0,0,1,2.34-5.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,216,120Z`,opacity:`0.2`}),d.createElement(`path`,{d:`M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z`}))],[`fill`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z`}))],[`light`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M217.9,110.1l-80-80a14,14,0,0,0-19.8,0l-80,80A13.92,13.92,0,0,0,34,120v96a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V158h36v58a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V120A13.92,13.92,0,0,0,217.9,110.1ZM210,210H158V152a6,6,0,0,0-6-6H104a6,6,0,0,0-6,6v58H46V120a2,2,0,0,1,.58-1.42l80-80a2,2,0,0,1,2.84,0l80,80A2,2,0,0,1,210,120Z`}))],[`regular`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z`}))],[`thin`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M216.49,111.51l-80-80a12,12,0,0,0-17,0l-80,80A12,12,0,0,0,36,120v96a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V156h40v60a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V120A12,12,0,0,0,216.49,111.51ZM212,212H156V152a4,4,0,0,0-4-4H104a4,4,0,0,0-4,4v60H44V120a4,4,0,0,1,1.17-2.83l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,212,120Z`}))]]),p=d.forwardRef((e,t)=>d.createElement(r,{ref:t,...e,weights:f}));p.displayName=`HouseIcon`;var m=e();function h(){let{t:e}=t(),n=s({from:`/error/`}),r=n.code||`UNKNOWN_ERROR`,i=n.message||e(`error.defaultMessage`);return(0,m.jsxs)(o,{cardPadding:!0,maxWidth:`100`,children:[(0,m.jsx)(u,{className:`mb-4`,icon:c,type:`error`,children:e(`error.title`)}),(0,m.jsx)(l,{subtitle:i,title:e(`error.subtitle`)}),(0,m.jsxs)(`div`,{className:`mb-6 rounded-lg bg-base-200 p-4 text-center`,children:[(0,m.jsx)(`p`,{className:`mb-1 text-base-content/50 text-xs`,children:e(`error.codeLabel`)}),(0,m.jsx)(`code`,{className:`font-mono text-error text-sm`,"data-testid":`error-code`,children:r})]}),(0,m.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,m.jsx)(a,{className:`btn btn-block h-10 font-semibold text-[14px]`,to:`/login`,children:e(`error.goToLogin`)}),(0,m.jsxs)(`button`,{className:`btn btn-ghost btn-block h-10 font-semibold text-[14px]`,onClick:()=>window.history.back(),type:`button`,children:[(0,m.jsx)(p,{className:`size-4`,weight:`fill`}),e(`error.goBack`)]})]}),(0,m.jsxs)(`div`,{className:`mt-6 text-center text-base-content/70 text-xs`,children:[e(`error.footer.needHelp`),` `,(0,m.jsx)(`a`,{className:`link link-info font-medium`,href:`mailto:support@example.com`,children:e(`error.footer.contactSupport`)})]})]})}export{h as component};
2
- //# sourceMappingURL=error-BKXsXhdR.js.map
1
+ import{o as e,r as t,s as n,t as r,u as i}from"./IconBase.es-d5KP98Ac.js";import{f as a}from"./use-theme-cVUDAjtt.js";import{t as o}from"./page-layout-C475gs09.js";import{F as s,L as c}from"./index-CgkA6nnx.js";import{t as l}from"./page-header-BYMFSGfT.js";import{t as u}from"./alert-CSXqgDVi.js";var d=i(n(),1),f=new Map([[`bold`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M222.14,105.85l-80-80a20,20,0,0,0-28.28,0l-80,80A19.86,19.86,0,0,0,28,120v96a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V164h24v52a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V120A19.86,19.86,0,0,0,222.14,105.85ZM204,204H164V152a12,12,0,0,0-12-12H104a12,12,0,0,0-12,12v52H52V121.65l76-76,76,76Z`}))],[`duotone`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M216,120v96H152V152H104v64H40V120a8,8,0,0,1,2.34-5.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,216,120Z`,opacity:`0.2`}),d.createElement(`path`,{d:`M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z`}))],[`fill`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z`}))],[`light`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M217.9,110.1l-80-80a14,14,0,0,0-19.8,0l-80,80A13.92,13.92,0,0,0,34,120v96a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V158h36v58a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V120A13.92,13.92,0,0,0,217.9,110.1ZM210,210H158V152a6,6,0,0,0-6-6H104a6,6,0,0,0-6,6v58H46V120a2,2,0,0,1,.58-1.42l80-80a2,2,0,0,1,2.84,0l80,80A2,2,0,0,1,210,120Z`}))],[`regular`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z`}))],[`thin`,d.createElement(d.Fragment,null,d.createElement(`path`,{d:`M216.49,111.51l-80-80a12,12,0,0,0-17,0l-80,80A12,12,0,0,0,36,120v96a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V156h40v60a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V120A12,12,0,0,0,216.49,111.51ZM212,212H156V152a4,4,0,0,0-4-4H104a4,4,0,0,0-4,4v60H44V120a4,4,0,0,1,1.17-2.83l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,212,120Z`}))]]),p=d.forwardRef((e,t)=>d.createElement(r,{ref:t,...e,weights:f}));p.displayName=`HouseIcon`;var m=e();function h(){let{t:e}=t(),n=c({from:`/error/`}),r=n.code||`UNKNOWN_ERROR`,i=n.message||e(`error.defaultMessage`);return(0,m.jsxs)(o,{cardPadding:!0,maxWidth:`100`,children:[(0,m.jsx)(u,{className:`mb-4`,icon:s,type:`error`,children:e(`error.title`)}),(0,m.jsx)(l,{subtitle:i,title:e(`error.subtitle`)}),(0,m.jsxs)(`div`,{className:`mb-6 rounded-lg bg-base-200 p-4 text-center`,children:[(0,m.jsx)(`p`,{className:`mb-1 text-base-content/50 text-xs`,children:e(`error.codeLabel`)}),(0,m.jsx)(`code`,{className:`font-mono text-error text-sm`,"data-testid":`error-code`,children:r})]}),(0,m.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,m.jsx)(a,{className:`btn btn-block h-10 font-semibold text-[14px]`,to:`/login`,children:e(`error.goToLogin`)}),(0,m.jsxs)(`button`,{className:`btn btn-ghost btn-block h-10 font-semibold text-[14px]`,onClick:()=>window.history.back(),type:`button`,children:[(0,m.jsx)(p,{className:`size-4`,weight:`fill`}),e(`error.goBack`)]})]}),(0,m.jsxs)(`div`,{className:`mt-6 text-center text-base-content/70 text-xs`,children:[e(`error.footer.needHelp`),` `,(0,m.jsx)(`a`,{className:`link link-info font-medium`,href:`mailto:support@example.com`,children:e(`error.footer.contactSupport`)})]})]})}export{h as component};
2
+ //# sourceMappingURL=error-DMzYyopT.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-BKXsXhdR.js","names":["e","t","a","HouseIcon","WarningCircleIcon","Link","useSearch","useTranslation","PageHeader","Alert","PageLayout","ErrorPage","t","search","from","errorCode","code","errorMessage","message","window","history","back","component"],"sources":["../../../../node_modules/.pnpm/@phosphor-icons+react@2.1.10_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@phosphor-icons/react/dist/defs/House.es.js","../../../../node_modules/.pnpm/@phosphor-icons+react@2.1.10_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@phosphor-icons/react/dist/csr/House.es.js","../../../frontend/src/routes/error/index.tsx?tsr-split=component"],"sourcesContent":["import * as a from \"react\";\nconst e = /* @__PURE__ */ new Map([\n [\n \"bold\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M222.14,105.85l-80-80a20,20,0,0,0-28.28,0l-80,80A19.86,19.86,0,0,0,28,120v96a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V164h24v52a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V120A19.86,19.86,0,0,0,222.14,105.85ZM204,204H164V152a12,12,0,0,0-12-12H104a12,12,0,0,0-12,12v52H52V121.65l76-76,76,76Z\" }))\n ],\n [\n \"duotone\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\n \"path\",\n {\n d: \"M216,120v96H152V152H104v64H40V120a8,8,0,0,1,2.34-5.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,216,120Z\",\n opacity: \"0.2\"\n }\n ), /* @__PURE__ */ a.createElement(\"path\", { d: \"M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z\" }))\n ],\n [\n \"fill\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z\" }))\n ],\n [\n \"light\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M217.9,110.1l-80-80a14,14,0,0,0-19.8,0l-80,80A13.92,13.92,0,0,0,34,120v96a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V158h36v58a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V120A13.92,13.92,0,0,0,217.9,110.1ZM210,210H158V152a6,6,0,0,0-6-6H104a6,6,0,0,0-6,6v58H46V120a2,2,0,0,1,.58-1.42l80-80a2,2,0,0,1,2.84,0l80,80A2,2,0,0,1,210,120Z\" }))\n ],\n [\n \"regular\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z\" }))\n ],\n [\n \"thin\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M216.49,111.51l-80-80a12,12,0,0,0-17,0l-80,80A12,12,0,0,0,36,120v96a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V156h40v60a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V120A12,12,0,0,0,216.49,111.51ZM212,212H156V152a4,4,0,0,0-4-4H104a4,4,0,0,0-4,4v60H44V120a4,4,0,0,1,1.17-2.83l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,212,120Z\" }))\n ]\n]);\nexport {\n e as default\n};\n","import * as o from \"react\";\nimport t from \"../lib/IconBase.es.js\";\nimport a from \"../defs/House.es.js\";\nconst e = o.forwardRef((r, s) => /* @__PURE__ */ o.createElement(t, { ref: s, ...r, weights: a }));\ne.displayName = \"HouseIcon\";\nconst n = e;\nexport {\n n as House,\n e as HouseIcon\n};\n","import { HouseIcon, WarningCircleIcon } from '@phosphor-icons/react';\nimport { createFileRoute, Link, useSearch } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\n\nconst errorSearchSchema = z.object({\n code: z.string().optional(),\n message: z.string().optional(),\n});\n\nexport const Route = createFileRoute('/error/')({\n component: ErrorPage,\n validateSearch: errorSearchSchema,\n});\n\nfunction ErrorPage() {\n const { t } = useTranslation();\n const search = useSearch({ from: '/error/' });\n\n const errorCode = search.code || 'UNKNOWN_ERROR';\n const errorMessage = search.message || t('error.defaultMessage');\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={WarningCircleIcon} type=\"error\">\n {t('error.title')}\n </Alert>\n\n <PageHeader subtitle={errorMessage} title={t('error.subtitle')} />\n\n {/* Error Code */}\n <div className=\"mb-6 rounded-lg bg-base-200 p-4 text-center\">\n <p className=\"mb-1 text-base-content/50 text-xs\">\n {t('error.codeLabel')}\n </p>\n <code className=\"font-mono text-error text-sm\" data-testid=\"error-code\">\n {errorCode}\n </code>\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-3\">\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('error.goToLogin')}\n </Link>\n <button\n className=\"btn btn-ghost btn-block h-10 font-semibold text-[14px]\"\n onClick={() => window.history.back()}\n type=\"button\"\n >\n <HouseIcon className=\"size-4\" weight=\"fill\" />\n {t('error.goBack')}\n </button>\n </div>\n\n {/* Footer */}\n <div className=\"mt-6 text-center text-base-content/70 text-xs\">\n {t('error.footer.needHelp')}{' '}\n <a\n className=\"link link-info font-medium\"\n href=\"mailto:support@example.com\"\n >\n {t('error.footer.contactSupport')}\n </a>\n </div>\n </PageLayout>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"wTACMA,EAAoB,IAAI,IAAI,CAChC,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,6RAA8R,CAAC,CAAC,CACjY,EACA,CACE,UACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAClE,OACA,CACE,EAAG,yGACH,QAAS,KACX,CACF,EAAmB,EAAE,cAAc,OAAQ,CAAE,EAAG,kQAAmQ,CAAC,CAAC,CACvT,EACA,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,mMAAoM,CAAC,CAAC,CACvS,EACA,CACE,QACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,mTAAoT,CAAC,CAAC,CACvZ,EACA,CACE,UACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,kQAAmQ,CAAC,CAAC,CACtW,EACA,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,0SAA2S,CAAC,CAAC,CAC9Y,CACF,CAAC,EC7BK,EAAA,EAAM,YAAY,EAAG,IAAsB,EAAE,cAAcC,EAAG,CAAE,IAAK,EAAG,GAAG,EAAG,QAASC,CAAE,CAAC,CAAC,EACjG,EAAE,YAAc,sBCchB,SAASS,GAAY,CACnB,GAAM,CAAEC,KAAML,EAAe,EACvBM,EAASP,EAAU,CAAEQ,KAAM,SAAU,CAAC,EAEtCC,EAAYF,EAAOG,MAAQ,gBAC3BC,EAAeJ,EAAOK,SAAWN,EAAE,sBAAsB,EAE/D,OACE,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMR,EAAmB,KAAK,iBACnDQ,EAAE,aAAa,CACX,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CAAY,SAAUK,EAAc,MAAOL,EAAE,gBAAgB,CAAE,CAAA,GAG/D,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uDAAf,EACE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,6CACVA,EAAE,iBAAiB,CACnB,CAAA,GACH,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+BAA+B,cAAY,sBACxDG,CACG,CAAA,CACH,KAGL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,+BAAf,EACE,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,+CACV,GAAG,kBAEFH,EAAE,iBAAiB,CAChB,CAAA,GACN,EAAA,EAAA,MAAC,SAAD,CACE,UAAU,yDACV,YAAeO,OAAOC,QAAQC,KAAK,EACnC,KAAK,kBAHP,EAKE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,SAAS,OAAO,MAAM,CAAA,EAC1CT,EAAE,cAAc,CACX,GACL,KAGL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yDAAf,CACGA,EAAE,uBAAuB,EAAG,KAC7B,EAAA,EAAA,KAAC,IAAD,CACE,UAAU,6BACV,KAAK,sCAEJA,EAAE,6BAA6B,CAC/B,CAAA,CACA,GACK,GAEhB"}
1
+ {"version":3,"file":"error-DMzYyopT.js","names":["e","t","a","HouseIcon","WarningCircleIcon","Link","useSearch","useTranslation","PageHeader","Alert","PageLayout","ErrorPage","t","search","from","errorCode","code","errorMessage","message","window","history","back","component"],"sources":["../../../../node_modules/.pnpm/@phosphor-icons+react@2.1.10_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@phosphor-icons/react/dist/defs/House.es.js","../../../../node_modules/.pnpm/@phosphor-icons+react@2.1.10_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@phosphor-icons/react/dist/csr/House.es.js","../../../frontend/src/routes/error/index.tsx?tsr-split=component"],"sourcesContent":["import * as a from \"react\";\nconst e = /* @__PURE__ */ new Map([\n [\n \"bold\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M222.14,105.85l-80-80a20,20,0,0,0-28.28,0l-80,80A19.86,19.86,0,0,0,28,120v96a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V164h24v52a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V120A19.86,19.86,0,0,0,222.14,105.85ZM204,204H164V152a12,12,0,0,0-12-12H104a12,12,0,0,0-12,12v52H52V121.65l76-76,76,76Z\" }))\n ],\n [\n \"duotone\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\n \"path\",\n {\n d: \"M216,120v96H152V152H104v64H40V120a8,8,0,0,1,2.34-5.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,216,120Z\",\n opacity: \"0.2\"\n }\n ), /* @__PURE__ */ a.createElement(\"path\", { d: \"M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z\" }))\n ],\n [\n \"fill\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z\" }))\n ],\n [\n \"light\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M217.9,110.1l-80-80a14,14,0,0,0-19.8,0l-80,80A13.92,13.92,0,0,0,34,120v96a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V158h36v58a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V120A13.92,13.92,0,0,0,217.9,110.1ZM210,210H158V152a6,6,0,0,0-6-6H104a6,6,0,0,0-6,6v58H46V120a2,2,0,0,1,.58-1.42l80-80a2,2,0,0,1,2.84,0l80,80A2,2,0,0,1,210,120Z\" }))\n ],\n [\n \"regular\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z\" }))\n ],\n [\n \"thin\",\n /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(\"path\", { d: \"M216.49,111.51l-80-80a12,12,0,0,0-17,0l-80,80A12,12,0,0,0,36,120v96a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V156h40v60a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V120A12,12,0,0,0,216.49,111.51ZM212,212H156V152a4,4,0,0,0-4-4H104a4,4,0,0,0-4,4v60H44V120a4,4,0,0,1,1.17-2.83l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,212,120Z\" }))\n ]\n]);\nexport {\n e as default\n};\n","import * as o from \"react\";\nimport t from \"../lib/IconBase.es.js\";\nimport a from \"../defs/House.es.js\";\nconst e = o.forwardRef((r, s) => /* @__PURE__ */ o.createElement(t, { ref: s, ...r, weights: a }));\ne.displayName = \"HouseIcon\";\nconst n = e;\nexport {\n n as House,\n e as HouseIcon\n};\n","import { HouseIcon, WarningCircleIcon } from '@phosphor-icons/react';\nimport { createFileRoute, Link, useSearch } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\n\nconst errorSearchSchema = z.object({\n code: z.string().optional(),\n message: z.string().optional(),\n});\n\nexport const Route = createFileRoute('/error/')({\n component: ErrorPage,\n validateSearch: errorSearchSchema,\n});\n\nfunction ErrorPage() {\n const { t } = useTranslation();\n const search = useSearch({ from: '/error/' });\n\n const errorCode = search.code || 'UNKNOWN_ERROR';\n const errorMessage = search.message || t('error.defaultMessage');\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={WarningCircleIcon} type=\"error\">\n {t('error.title')}\n </Alert>\n\n <PageHeader subtitle={errorMessage} title={t('error.subtitle')} />\n\n {/* Error Code */}\n <div className=\"mb-6 rounded-lg bg-base-200 p-4 text-center\">\n <p className=\"mb-1 text-base-content/50 text-xs\">\n {t('error.codeLabel')}\n </p>\n <code className=\"font-mono text-error text-sm\" data-testid=\"error-code\">\n {errorCode}\n </code>\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-3\">\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('error.goToLogin')}\n </Link>\n <button\n className=\"btn btn-ghost btn-block h-10 font-semibold text-[14px]\"\n onClick={() => window.history.back()}\n type=\"button\"\n >\n <HouseIcon className=\"size-4\" weight=\"fill\" />\n {t('error.goBack')}\n </button>\n </div>\n\n {/* Footer */}\n <div className=\"mt-6 text-center text-base-content/70 text-xs\">\n {t('error.footer.needHelp')}{' '}\n <a\n className=\"link link-info font-medium\"\n href=\"mailto:support@example.com\"\n >\n {t('error.footer.contactSupport')}\n </a>\n </div>\n </PageLayout>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"wTACMA,EAAoB,IAAI,IAAI,CAChC,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,6RAA8R,CAAC,CAAC,CACjY,EACA,CACE,UACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAClE,OACA,CACE,EAAG,yGACH,QAAS,KACX,CACF,EAAmB,EAAE,cAAc,OAAQ,CAAE,EAAG,kQAAmQ,CAAC,CAAC,CACvT,EACA,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,mMAAoM,CAAC,CAAC,CACvS,EACA,CACE,QACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,mTAAoT,CAAC,CAAC,CACvZ,EACA,CACE,UACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,kQAAmQ,CAAC,CAAC,CACtW,EACA,CACE,OACgB,EAAE,cAAA,EAAgB,SAAU,KAAsB,EAAE,cAAc,OAAQ,CAAE,EAAG,0SAA2S,CAAC,CAAC,CAC9Y,CACF,CAAC,EC7BK,EAAA,EAAM,YAAY,EAAG,IAAsB,EAAE,cAAcC,EAAG,CAAE,IAAK,EAAG,GAAG,EAAG,QAASC,CAAE,CAAC,CAAC,EACjG,EAAE,YAAc,sBCchB,SAASS,GAAY,CACnB,GAAM,CAAEC,KAAML,EAAe,EACvBM,EAASP,EAAU,CAAEQ,KAAM,SAAU,CAAC,EAEtCC,EAAYF,EAAOG,MAAQ,gBAC3BC,EAAeJ,EAAOK,SAAWN,EAAE,sBAAsB,EAE/D,OACE,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMR,EAAmB,KAAK,iBACnDQ,EAAE,aAAa,CACX,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CAAY,SAAUK,EAAc,MAAOL,EAAE,gBAAgB,CAAE,CAAA,GAG/D,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uDAAf,EACE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,6CACVA,EAAE,iBAAiB,CACnB,CAAA,GACH,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+BAA+B,cAAY,sBACxDG,CACG,CAAA,CACH,KAGL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,+BAAf,EACE,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,+CACV,GAAG,kBAEFH,EAAE,iBAAiB,CAChB,CAAA,GACN,EAAA,EAAA,MAAC,SAAD,CACE,UAAU,yDACV,YAAeO,OAAOC,QAAQC,KAAK,EACnC,KAAK,kBAHP,EAKE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,SAAS,OAAO,MAAM,CAAA,EAC1CT,EAAE,cAAc,CACX,GACL,KAGL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yDAAf,CACGA,EAAE,uBAAuB,EAAG,KAC7B,EAAA,EAAA,KAAC,IAAD,CACE,UAAU,6BACV,KAAK,sCAEJA,EAAE,6BAA6B,CAC/B,CAAA,CACA,GACK,GAEhB"}
@@ -0,0 +1,2 @@
1
+ import{P as e}from"./index-CgkA6nnx.js";var t=e;export{t as errorComponent};
2
+ //# sourceMappingURL=forgot-DvD9N_wj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"forgot-BMEIiDXv.js","names":["RouteErrorFallback","ForgotPasswordFormValues","email","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/password/forgot/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { CheckCircleIcon, EnvelopeSimpleIcon } from '@phosphor-icons/react';\nimport { useMutation } from '@tanstack/react-query';\nimport { createFileRoute, Link, redirect } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FooterLink } from '#frontend/components/auth/footer-link.tsx';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { forgotPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nexport const Route = createFileRoute('/password/forgot/')({\n component: ForgotPassword,\n errorComponent: RouteErrorFallback,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config?.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype ForgotPasswordFormValues = {\n email: string;\n};\n\nfunction ForgotPassword() {\n const { t } = useTranslation();\n const [emailSent, setEmailSent] = useState(false);\n const [submittedEmail, setSubmittedEmail] = useState('');\n\n const forgotPasswordSchema = useMemo(\n () =>\n z.object({\n email: z.email({ error: t('validation.email.invalid') }),\n }),\n [t],\n );\n\n const forgotPasswordMutation = useMutation({\n ...forgotPasswordMutationOptions,\n onSuccess: () => {\n setEmailSent(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ForgotPasswordFormValues>({\n defaultValues: {\n email: '',\n },\n resolver: standardSchemaResolver(forgotPasswordSchema),\n });\n\n const onSubmit = async (values: ForgotPasswordFormValues) => {\n try {\n setSubmittedEmail(values.email);\n await forgotPasswordMutation.mutateAsync(values);\n } catch (error) {\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'USER_NOT_EDITABLE'\n ) {\n setError('email', {\n type: 'manual',\n message: t('forgotPassword.error.notEditable'),\n });\n } else {\n setEmailSent(true);\n }\n }\n };\n\n if (emailSent) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('forgotPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('forgotPassword.success.description', {\n email: submittedEmail,\n })}\n title={t('forgotPassword.success.subtitle')}\n />\n\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n {t('forgotPassword.success.checkSpam')}\n </Alert>\n\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('forgotPassword.backToLogin')}\n </Link>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('forgotPassword.subtitle')}\n title={t('forgotPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n autoComplete=\"email\"\n error={errors.email}\n icon={EnvelopeSimpleIcon}\n placeholder={t('forgotPassword.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={forgotPasswordMutation.isPending}\n pendingText={t('forgotPassword.submitting')}\n >\n {t('forgotPassword.submit')}\n </SubmitButton>\n </form>\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n text={t('forgotPassword.footer.rememberedPassword')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"wCAqCE,IAAAG,EAxBOH"}
1
+ {"version":3,"file":"forgot-DvD9N_wj.js","names":["RouteErrorFallback","ForgotPasswordFormValues","email","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/password/forgot/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { CheckCircleIcon, EnvelopeSimpleIcon } from '@phosphor-icons/react';\nimport { useMutation } from '@tanstack/react-query';\nimport { createFileRoute, Link, redirect } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FooterLink } from '#frontend/components/auth/footer-link.tsx';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { forgotPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nexport const Route = createFileRoute('/password/forgot/')({\n component: ForgotPassword,\n errorComponent: RouteErrorFallback,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config?.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype ForgotPasswordFormValues = {\n email: string;\n};\n\nfunction ForgotPassword() {\n const { t } = useTranslation();\n const [emailSent, setEmailSent] = useState(false);\n const [submittedEmail, setSubmittedEmail] = useState('');\n\n const forgotPasswordSchema = useMemo(\n () =>\n z.object({\n email: z.email({ error: t('validation.email.invalid') }),\n }),\n [t],\n );\n\n const forgotPasswordMutation = useMutation({\n ...forgotPasswordMutationOptions,\n onSuccess: () => {\n setEmailSent(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ForgotPasswordFormValues>({\n defaultValues: {\n email: '',\n },\n resolver: standardSchemaResolver(forgotPasswordSchema),\n });\n\n const onSubmit = async (values: ForgotPasswordFormValues) => {\n try {\n setSubmittedEmail(values.email);\n await forgotPasswordMutation.mutateAsync(values);\n } catch (error) {\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'USER_NOT_EDITABLE'\n ) {\n setError('email', {\n type: 'manual',\n message: t('forgotPassword.error.notEditable'),\n });\n } else {\n setEmailSent(true);\n }\n }\n };\n\n if (emailSent) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('forgotPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('forgotPassword.success.description', {\n email: submittedEmail,\n })}\n title={t('forgotPassword.success.subtitle')}\n />\n\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n {t('forgotPassword.success.checkSpam')}\n </Alert>\n\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('forgotPassword.backToLogin')}\n </Link>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('forgotPassword.subtitle')}\n title={t('forgotPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n autoComplete=\"email\"\n error={errors.email}\n icon={EnvelopeSimpleIcon}\n placeholder={t('forgotPassword.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={forgotPasswordMutation.isPending}\n pendingText={t('forgotPassword.submitting')}\n >\n {t('forgotPassword.submit')}\n </SubmitButton>\n </form>\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n text={t('forgotPassword.footer.rememberedPassword')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"wCAqCE,IAAAG,EAxBOH"}
@@ -1,2 +1,2 @@
1
- import{o as e,r as t,s as n,u as r}from"./IconBase.es-d5KP98Ac.js";import{f as i}from"./use-theme-cVUDAjtt.js";import{t as a}from"./useMutation-Iu4AJCB4.js";import{t as o}from"./CheckCircle.es-MnJIACCe.js";import{t as s}from"./page-layout-C475gs09.js";import{t as c}from"./EnvelopeSimple.es-BZ7u3LYh.js";import{i as l,o as u}from"./zod-BItJDQBQ.js";import{t as d}from"./page-header-BYMFSGfT.js";import{t as f}from"./alert-CSXqgDVi.js";import{r as p,t as m}from"./standard-schema-o4V-s4uY.js";import{t as h}from"./footer-link-Ib1Hd-fr.js";import{t as g}from"./icon-input-8iU7PNzd.js";import{t as _}from"./submit-button-Xx6DwLyh.js";import{t as v}from"./password-reset-XZJTgJi3.js";var y=r(n()),b=e();function x(){let{t:e}=t(),[n,r]=(0,y.useState)(!1),[x,S]=(0,y.useState)(``),C=(0,y.useMemo)(()=>u({email:l({error:e(`validation.email.invalid`)})}),[e]),w=a({...v,onSuccess:()=>{r(!0)}}),{register:T,setError:E,handleSubmit:D,formState:{errors:O}}=p({defaultValues:{email:``},resolver:m(C)});return n?(0,b.jsxs)(s,{cardPadding:!0,maxWidth:`100`,children:[(0,b.jsx)(f,{className:`mb-4`,icon:o,type:`success`,children:e(`forgotPassword.success.title`)}),(0,b.jsx)(d,{subtitle:e(`forgotPassword.success.description`,{email:x}),title:e(`forgotPassword.success.subtitle`)}),(0,b.jsx)(f,{className:`mb-4`,icon:c,type:`info`,children:e(`forgotPassword.success.checkSpam`)}),(0,b.jsx)(i,{className:`btn btn-block h-10 font-semibold text-[14px]`,to:`/login`,children:e(`forgotPassword.backToLogin`)})]}):(0,b.jsxs)(s,{cardPadding:!0,maxWidth:`100`,children:[(0,b.jsx)(d,{subtitle:e(`forgotPassword.subtitle`),title:e(`forgotPassword.title`)}),(0,b.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:D(async t=>{try{S(t.email),await w.mutateAsync(t)}catch(t){t&&typeof t==`object`&&`code`in t&&t.code===`USER_NOT_EDITABLE`?E(`email`,{type:`manual`,message:e(`forgotPassword.error.notEditable`)}):r(!0)}}),children:[(0,b.jsx)(g,{autoComplete:`email`,error:O.email,icon:c,placeholder:e(`forgotPassword.email.placeholder`),...T(`email`),type:`email`}),(0,b.jsx)(_,{className:`mt-2`,isPending:w.isPending,pendingText:e(`forgotPassword.submitting`),children:e(`forgotPassword.submit`)})]}),(0,b.jsx)(h,{as:i,linkText:e(`register.link.login`),text:e(`forgotPassword.footer.rememberedPassword`),to:`/login`})]})}export{x as component};
2
- //# sourceMappingURL=forgot-C9zSfaX9.js.map
1
+ import{o as e,r as t,s as n,u as r}from"./IconBase.es-d5KP98Ac.js";import{f as i}from"./use-theme-cVUDAjtt.js";import{t as a}from"./useMutation-Biy2-pH_.js";import{t as o}from"./CheckCircle.es-MnJIACCe.js";import{t as s}from"./page-layout-C475gs09.js";import{t as c}from"./EnvelopeSimple.es-BZ7u3LYh.js";import{i as l,o as u}from"./zod-BItJDQBQ.js";import{t as d}from"./page-header-BYMFSGfT.js";import{t as f}from"./alert-CSXqgDVi.js";import{r as p,t as m}from"./standard-schema-o4V-s4uY.js";import{t as h}from"./footer-link-Ib1Hd-fr.js";import{t as g}from"./icon-input-8iU7PNzd.js";import{t as _}from"./submit-button-Xx6DwLyh.js";import{t as v}from"./password-reset-XZJTgJi3.js";var y=r(n()),b=e();function x(){let{t:e}=t(),[n,r]=(0,y.useState)(!1),[x,S]=(0,y.useState)(``),C=(0,y.useMemo)(()=>u({email:l({error:e(`validation.email.invalid`)})}),[e]),w=a({...v,onSuccess:()=>{r(!0)}}),{register:T,setError:E,handleSubmit:D,formState:{errors:O}}=p({defaultValues:{email:``},resolver:m(C)});return n?(0,b.jsxs)(s,{cardPadding:!0,maxWidth:`100`,children:[(0,b.jsx)(f,{className:`mb-4`,icon:o,type:`success`,children:e(`forgotPassword.success.title`)}),(0,b.jsx)(d,{subtitle:e(`forgotPassword.success.description`,{email:x}),title:e(`forgotPassword.success.subtitle`)}),(0,b.jsx)(f,{className:`mb-4`,icon:c,type:`info`,children:e(`forgotPassword.success.checkSpam`)}),(0,b.jsx)(i,{className:`btn btn-block h-10 font-semibold text-[14px]`,to:`/login`,children:e(`forgotPassword.backToLogin`)})]}):(0,b.jsxs)(s,{cardPadding:!0,maxWidth:`100`,children:[(0,b.jsx)(d,{subtitle:e(`forgotPassword.subtitle`),title:e(`forgotPassword.title`)}),(0,b.jsxs)(`form`,{className:`flex flex-col gap-4`,onSubmit:D(async t=>{try{S(t.email),await w.mutateAsync(t)}catch(t){t&&typeof t==`object`&&`code`in t&&t.code===`USER_NOT_EDITABLE`?E(`email`,{type:`manual`,message:e(`forgotPassword.error.notEditable`)}):r(!0)}}),children:[(0,b.jsx)(g,{autoComplete:`email`,error:O.email,icon:c,placeholder:e(`forgotPassword.email.placeholder`),...T(`email`),type:`email`}),(0,b.jsx)(_,{className:`mt-2`,isPending:w.isPending,pendingText:e(`forgotPassword.submitting`),children:e(`forgotPassword.submit`)})]}),(0,b.jsx)(h,{as:i,linkText:e(`register.link.login`),text:e(`forgotPassword.footer.rememberedPassword`),to:`/login`})]})}export{x as component};
2
+ //# sourceMappingURL=forgot-RbSzzjWF.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"forgot-C9zSfaX9.js","names":["standardSchemaResolver","CheckCircleIcon","EnvelopeSimpleIcon","useMutation","Link","useMemo","useState","useForm","useTranslation","z","FooterLink","IconInput","PageHeader","SubmitButton","Alert","PageLayout","forgotPasswordMutationOptions","ForgotPasswordFormValues","email","ForgotPassword","t","emailSent","setEmailSent","submittedEmail","setSubmittedEmail","forgotPasswordSchema","object","error","forgotPasswordMutation","onSuccess","register","setError","handleSubmit","formState","errors","defaultValues","resolver","onSubmit","values","mutateAsync","code","type","message","isPending","component"],"sources":["../../../frontend/src/routes/password/forgot/index.tsx?tsr-split=component"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { CheckCircleIcon, EnvelopeSimpleIcon } from '@phosphor-icons/react';\nimport { useMutation } from '@tanstack/react-query';\nimport { createFileRoute, Link, redirect } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FooterLink } from '#frontend/components/auth/footer-link.tsx';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { forgotPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nexport const Route = createFileRoute('/password/forgot/')({\n component: ForgotPassword,\n errorComponent: RouteErrorFallback,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config?.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype ForgotPasswordFormValues = {\n email: string;\n};\n\nfunction ForgotPassword() {\n const { t } = useTranslation();\n const [emailSent, setEmailSent] = useState(false);\n const [submittedEmail, setSubmittedEmail] = useState('');\n\n const forgotPasswordSchema = useMemo(\n () =>\n z.object({\n email: z.email({ error: t('validation.email.invalid') }),\n }),\n [t],\n );\n\n const forgotPasswordMutation = useMutation({\n ...forgotPasswordMutationOptions,\n onSuccess: () => {\n setEmailSent(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ForgotPasswordFormValues>({\n defaultValues: {\n email: '',\n },\n resolver: standardSchemaResolver(forgotPasswordSchema),\n });\n\n const onSubmit = async (values: ForgotPasswordFormValues) => {\n try {\n setSubmittedEmail(values.email);\n await forgotPasswordMutation.mutateAsync(values);\n } catch (error) {\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'USER_NOT_EDITABLE'\n ) {\n setError('email', {\n type: 'manual',\n message: t('forgotPassword.error.notEditable'),\n });\n } else {\n setEmailSent(true);\n }\n }\n };\n\n if (emailSent) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('forgotPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('forgotPassword.success.description', {\n email: submittedEmail,\n })}\n title={t('forgotPassword.success.subtitle')}\n />\n\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n {t('forgotPassword.success.checkSpam')}\n </Alert>\n\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('forgotPassword.backToLogin')}\n </Link>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('forgotPassword.subtitle')}\n title={t('forgotPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n autoComplete=\"email\"\n error={errors.email}\n icon={EnvelopeSimpleIcon}\n placeholder={t('forgotPassword.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={forgotPasswordMutation.isPending}\n pendingText={t('forgotPassword.submitting')}\n >\n {t('forgotPassword.submit')}\n </SubmitButton>\n </form>\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n text={t('forgotPassword.footer.rememberedPassword')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"2rBAuCA,SAASmB,GAAiB,CACxB,GAAM,CAAEC,KAAMZ,EAAe,EACvB,CAACa,EAAWC,IAAAA,EAAAA,EAAAA,UAAyB,EAAK,EAC1C,CAACC,EAAgBC,IAAAA,EAAAA,EAAAA,UAA8B,EAAE,EAEjDC,GAAAA,EAAAA,EAAAA,aAEFhB,EAAS,CACPS,MAAOT,EAAQ,CAAEkB,MAAOP,EAAE,0BAA0B,CAAE,CAAC,CACzD,CAAC,EACH,CAACA,CAAC,CACJ,EAEMQ,EAAyBzB,EAAY,CACzC,GAAGa,EACHa,cAAiB,CACfP,EAAa,EAAI,CACnB,CACF,CAAC,EAEK,CACJQ,WACAC,WACAC,eACAC,UAAW,CAAEC,WACX3B,EAAkC,CACpC4B,cAAe,CACbjB,MAAO,EACT,EACAkB,SAAUpC,EAAuByB,CAAoB,CACvD,CAAC,EAmDD,OA5BIJ,GAEA,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMpB,EAAiB,KAAK,mBACjDmB,EAAE,8BAA8B,CAC5B,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,qCAAsC,CAChDF,MAAOK,CACT,CAAC,EACD,MAAOH,EAAE,iCAAiC,CAAE,CAAA,GAG9C,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMlB,EAAoB,KAAK,gBACpDkB,EAAE,kCAAkC,CAChC,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,+CACV,GAAG,kBAEFA,EAAE,4BAA4B,CAC3B,CAAA,CACI,KAKd,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,yBAAyB,EACrC,MAAOA,EAAE,sBAAsB,CAAE,CAAA,GAGnC,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,sBAAsB,SAAUY,EAAaK,KAxDzCC,IAAqC,CAC3D,GAAI,CACFd,EAAkBc,EAAOpB,KAAK,EAC9B,MAAMU,EAAuBW,YAAYD,CAAM,CACjD,OAASX,EAAO,CAEZA,GACA,OAAOA,GAAU,UACjB,SAAUA,GACVA,EAAMa,OAAS,oBAEfT,EAAS,QAAS,CAChBU,KAAM,SACNC,QAAStB,EAAE,kCAAkC,CAC/C,CAAC,EAEDE,EAAa,EAAI,CAErB,CACF,CAqCyE,WAArE,EACE,EAAA,EAAA,KAAC,EAAD,CACE,aAAa,QACb,MAAOY,EAAOhB,MACd,KAAMhB,EACN,YAAakB,EAAE,kCAAkC,EACjD,GAAIU,EAAS,OAAO,EACpB,KAAK,OAAO,CAAA,GAGd,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,OACV,UAAWF,EAAuBe,UAClC,YAAavB,EAAE,2BAA2B,WAEzCA,EAAE,uBAAuB,CACd,CAAA,CACV,KAEN,EAAA,EAAA,KAAC,EAAD,CACE,GAAIhB,EACJ,SAAUgB,EAAE,qBAAqB,EACjC,KAAMA,EAAE,0CAA0C,EAClD,GAAG,QAAQ,CAAA,CAEH,GAEhB"}
1
+ {"version":3,"file":"forgot-RbSzzjWF.js","names":["standardSchemaResolver","CheckCircleIcon","EnvelopeSimpleIcon","useMutation","Link","useMemo","useState","useForm","useTranslation","z","FooterLink","IconInput","PageHeader","SubmitButton","Alert","PageLayout","forgotPasswordMutationOptions","ForgotPasswordFormValues","email","ForgotPassword","t","emailSent","setEmailSent","submittedEmail","setSubmittedEmail","forgotPasswordSchema","object","error","forgotPasswordMutation","onSuccess","register","setError","handleSubmit","formState","errors","defaultValues","resolver","onSubmit","values","mutateAsync","code","type","message","isPending","component"],"sources":["../../../frontend/src/routes/password/forgot/index.tsx?tsr-split=component"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport { CheckCircleIcon, EnvelopeSimpleIcon } from '@phosphor-icons/react';\nimport { useMutation } from '@tanstack/react-query';\nimport { createFileRoute, Link, redirect } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FooterLink } from '#frontend/components/auth/footer-link.tsx';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { forgotPasswordMutationOptions } from '#frontend/queries/password-reset.ts';\n\nexport const Route = createFileRoute('/password/forgot/')({\n component: ForgotPassword,\n errorComponent: RouteErrorFallback,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config?.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype ForgotPasswordFormValues = {\n email: string;\n};\n\nfunction ForgotPassword() {\n const { t } = useTranslation();\n const [emailSent, setEmailSent] = useState(false);\n const [submittedEmail, setSubmittedEmail] = useState('');\n\n const forgotPasswordSchema = useMemo(\n () =>\n z.object({\n email: z.email({ error: t('validation.email.invalid') }),\n }),\n [t],\n );\n\n const forgotPasswordMutation = useMutation({\n ...forgotPasswordMutationOptions,\n onSuccess: () => {\n setEmailSent(true);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<ForgotPasswordFormValues>({\n defaultValues: {\n email: '',\n },\n resolver: standardSchemaResolver(forgotPasswordSchema),\n });\n\n const onSubmit = async (values: ForgotPasswordFormValues) => {\n try {\n setSubmittedEmail(values.email);\n await forgotPasswordMutation.mutateAsync(values);\n } catch (error) {\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'USER_NOT_EDITABLE'\n ) {\n setError('email', {\n type: 'manual',\n message: t('forgotPassword.error.notEditable'),\n });\n } else {\n setEmailSent(true);\n }\n }\n };\n\n if (emailSent) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('forgotPassword.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('forgotPassword.success.description', {\n email: submittedEmail,\n })}\n title={t('forgotPassword.success.subtitle')}\n />\n\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n {t('forgotPassword.success.checkSpam')}\n </Alert>\n\n <Link\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n to=\"/login\"\n >\n {t('forgotPassword.backToLogin')}\n </Link>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('forgotPassword.subtitle')}\n title={t('forgotPassword.title')}\n />\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n autoComplete=\"email\"\n error={errors.email}\n icon={EnvelopeSimpleIcon}\n placeholder={t('forgotPassword.email.placeholder')}\n {...register('email')}\n type=\"email\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={forgotPasswordMutation.isPending}\n pendingText={t('forgotPassword.submitting')}\n >\n {t('forgotPassword.submit')}\n </SubmitButton>\n </form>\n\n <FooterLink\n as={Link}\n linkText={t('register.link.login')}\n text={t('forgotPassword.footer.rememberedPassword')}\n to=\"/login\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"2rBAuCA,SAASmB,GAAiB,CACxB,GAAM,CAAEC,KAAMZ,EAAe,EACvB,CAACa,EAAWC,IAAAA,EAAAA,EAAAA,UAAyB,EAAK,EAC1C,CAACC,EAAgBC,IAAAA,EAAAA,EAAAA,UAA8B,EAAE,EAEjDC,GAAAA,EAAAA,EAAAA,aAEFhB,EAAS,CACPS,MAAOT,EAAQ,CAAEkB,MAAOP,EAAE,0BAA0B,CAAE,CAAC,CACzD,CAAC,EACH,CAACA,CAAC,CACJ,EAEMQ,EAAyBzB,EAAY,CACzC,GAAGa,EACHa,cAAiB,CACfP,EAAa,EAAI,CACnB,CACF,CAAC,EAEK,CACJQ,WACAC,WACAC,eACAC,UAAW,CAAEC,WACX3B,EAAkC,CACpC4B,cAAe,CACbjB,MAAO,EACT,EACAkB,SAAUpC,EAAuByB,CAAoB,CACvD,CAAC,EAmDD,OA5BIJ,GAEA,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMpB,EAAiB,KAAK,mBACjDmB,EAAE,8BAA8B,CAC5B,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,qCAAsC,CAChDF,MAAOK,CACT,CAAC,EACD,MAAOH,EAAE,iCAAiC,CAAE,CAAA,GAG9C,EAAA,EAAA,KAAC,EAAD,CAAO,UAAU,OAAO,KAAMlB,EAAoB,KAAK,gBACpDkB,EAAE,kCAAkC,CAChC,CAAA,GAEP,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,+CACV,GAAG,kBAEFA,EAAE,4BAA4B,CAC3B,CAAA,CACI,KAKd,EAAA,EAAA,MAAC,EAAD,CAAY,YAAA,GAAY,SAAS,eAAjC,EACE,EAAA,EAAA,KAAC,EAAD,CACE,SAAUA,EAAE,yBAAyB,EACrC,MAAOA,EAAE,sBAAsB,CAAE,CAAA,GAGnC,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,sBAAsB,SAAUY,EAAaK,KAxDzCC,IAAqC,CAC3D,GAAI,CACFd,EAAkBc,EAAOpB,KAAK,EAC9B,MAAMU,EAAuBW,YAAYD,CAAM,CACjD,OAASX,EAAO,CAEZA,GACA,OAAOA,GAAU,UACjB,SAAUA,GACVA,EAAMa,OAAS,oBAEfT,EAAS,QAAS,CAChBU,KAAM,SACNC,QAAStB,EAAE,kCAAkC,CAC/C,CAAC,EAEDE,EAAa,EAAI,CAErB,CACF,CAqCyE,WAArE,EACE,EAAA,EAAA,KAAC,EAAD,CACE,aAAa,QACb,MAAOY,EAAOhB,MACd,KAAMhB,EACN,YAAakB,EAAE,kCAAkC,EACjD,GAAIU,EAAS,OAAO,EACpB,KAAK,OAAO,CAAA,GAGd,EAAA,EAAA,KAAC,EAAD,CACE,UAAU,OACV,UAAWF,EAAuBe,UAClC,YAAavB,EAAE,2BAA2B,WAEzCA,EAAE,uBAAuB,CACd,CAAA,CACV,KAEN,EAAA,EAAA,KAAC,EAAD,CACE,GAAIhB,EACJ,SAAUgB,EAAE,qBAAqB,EACjC,KAAMA,EAAE,0CAA0C,EAClD,GAAG,QAAQ,CAAA,CAEH,GAEhB"}