@lalternative/auth 0.4.2 → 0.4.4

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.
package/dist/index.js CHANGED
@@ -13,52 +13,233 @@ function useLogout(authClient) {
13
13
  return signOut;
14
14
  }
15
15
 
16
+ // src/components/auth-field.tsx
17
+ import { useId, useState } from "react";
18
+ import { jsx, jsxs } from "react/jsx-runtime";
19
+ function AuthField({
20
+ label,
21
+ hint,
22
+ description,
23
+ invalid = false,
24
+ ...props
25
+ }) {
26
+ const id = useId();
27
+ const descriptionId = description ? `${id}-description` : void 0;
28
+ const [revealed, setRevealed] = useState(false);
29
+ const isPassword = props.type === "password";
30
+ const type = isPassword && revealed ? "text" : props.type;
31
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
32
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-3", children: [
33
+ /* @__PURE__ */ jsx(
34
+ "label",
35
+ {
36
+ htmlFor: id,
37
+ className: "text-sm font-medium leading-none text-foreground",
38
+ children: label
39
+ }
40
+ ),
41
+ hint
42
+ ] }),
43
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
44
+ /* @__PURE__ */ jsx(
45
+ "input",
46
+ {
47
+ ...props,
48
+ id,
49
+ type,
50
+ "aria-invalid": invalid || void 0,
51
+ "aria-describedby": descriptionId,
52
+ className: [
53
+ "h-[52px] w-full rounded-xl border bg-background px-4 text-base",
54
+ "sm:h-11 sm:text-sm",
55
+ isPassword ? "pr-12" : "",
56
+ "text-foreground placeholder:text-muted-foreground/70",
57
+ "transition-[border-color,box-shadow] duration-150 ease-out",
58
+ "focus-visible:outline-none focus-visible:ring-0",
59
+ invalid ? "border-destructive focus-visible:border-destructive focus-visible:shadow-[0_0_0_3px_hsl(var(--destructive)/0.18)]" : "border-input focus-visible:border-ring focus-visible:shadow-[0_0_0_3px_hsl(var(--ring)/0.14)]",
60
+ "disabled:cursor-not-allowed disabled:opacity-60"
61
+ ].filter(Boolean).join(" ")
62
+ }
63
+ ),
64
+ isPassword && /* @__PURE__ */ jsx(
65
+ "button",
66
+ {
67
+ type: "button",
68
+ onClick: () => setRevealed((v) => !v),
69
+ disabled: props.disabled,
70
+ "aria-pressed": revealed,
71
+ "aria-label": revealed ? "Masquer le mot de passe" : "Afficher le mot de passe",
72
+ className: "absolute inset-y-0 right-0 flex w-12 items-center justify-center rounded-r-xl text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-60",
73
+ children: /* @__PURE__ */ jsx(EyeIcon, { open: revealed })
74
+ }
75
+ )
76
+ ] }),
77
+ description && /* @__PURE__ */ jsx("p", { id: descriptionId, className: "text-xs text-muted-foreground", children: description })
78
+ ] });
79
+ }
80
+ function EyeIcon({ open }) {
81
+ return /* @__PURE__ */ jsxs(
82
+ "svg",
83
+ {
84
+ width: "18",
85
+ height: "18",
86
+ viewBox: "0 0 24 24",
87
+ fill: "none",
88
+ stroke: "currentColor",
89
+ strokeWidth: "1.75",
90
+ strokeLinecap: "round",
91
+ strokeLinejoin: "round",
92
+ "aria-hidden": "true",
93
+ children: [
94
+ /* @__PURE__ */ jsx("path", { d: "M2.06 12.35a1 1 0 0 1 0-.7 10.75 10.75 0 0 1 19.88 0 1 1 0 0 1 0 .7 10.75 10.75 0 0 1-19.88 0Z" }),
95
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
96
+ !open && /* @__PURE__ */ jsx("path", { d: "m3 3 18 18" })
97
+ ]
98
+ }
99
+ );
100
+ }
101
+
102
+ // src/components/auth-submit.tsx
103
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
104
+ function AuthSubmit({
105
+ pending = false,
106
+ disabled = false,
107
+ pendingLabel,
108
+ children
109
+ }) {
110
+ return /* @__PURE__ */ jsxs2(
111
+ "button",
112
+ {
113
+ type: "submit",
114
+ disabled: disabled || pending,
115
+ "aria-busy": pending || void 0,
116
+ className: [
117
+ "relative flex h-[52px] w-full items-center justify-center rounded-xl sm:h-11",
118
+ "bg-primary text-base font-medium text-primary-foreground sm:text-sm",
119
+ "shadow-sm transition-[background-color,transform,box-shadow] duration-150 ease-out",
120
+ "hover:bg-primary/90 active:translate-y-px",
121
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
122
+ "disabled:pointer-events-none disabled:opacity-55"
123
+ ].join(" "),
124
+ children: [
125
+ pending && /* @__PURE__ */ jsx2(
126
+ "span",
127
+ {
128
+ "aria-hidden": "true",
129
+ className: "absolute left-4 size-4 animate-spin rounded-full border-2 border-current border-t-transparent opacity-70 motion-reduce:animate-none"
130
+ }
131
+ ),
132
+ pending ? pendingLabel : children
133
+ ]
134
+ }
135
+ );
136
+ }
137
+
16
138
  // src/components/login-form.tsx
17
- import { useState } from "react";
139
+ import { useState as useState2 } from "react";
18
140
 
19
141
  // src/components/social-buttons.tsx
20
- import { jsx, jsxs } from "react/jsx-runtime";
142
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
21
143
  var LABELS = {
22
- google: "Continue with Google",
23
- github: "Continue with GitHub"
144
+ google: "Continuer avec Google",
145
+ github: "Continuer avec GitHub"
24
146
  };
25
147
  function SocialButtons({
26
148
  providers,
27
149
  onSelect,
28
- disabled = false
150
+ disabled = false,
151
+ separator = "ou",
152
+ labels
29
153
  }) {
30
154
  if (providers.length === 0) return null;
31
- return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
32
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
33
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx("div", { className: "w-full border-t border-input" }) }),
34
- /* @__PURE__ */ jsx("div", { className: "relative flex justify-center", children: /* @__PURE__ */ jsx("span", { className: "bg-background px-2 text-xs uppercase tracking-wider text-muted-foreground", children: "or" }) })
155
+ const copy = { ...LABELS, ...labels };
156
+ return /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
157
+ /* @__PURE__ */ jsxs3("div", { "aria-hidden": "true", className: "flex items-center gap-3", children: [
158
+ /* @__PURE__ */ jsx3("span", { className: "h-px flex-1 bg-border" }),
159
+ /* @__PURE__ */ jsx3("span", { className: "text-[11px] uppercase tracking-[0.14em] text-muted-foreground", children: separator }),
160
+ /* @__PURE__ */ jsx3("span", { className: "h-px flex-1 bg-border" })
35
161
  ] }),
36
- /* @__PURE__ */ jsx("div", { className: "space-y-2", children: providers.map((provider) => /* @__PURE__ */ jsx(
162
+ /* @__PURE__ */ jsx3("div", { className: "space-y-2.5", children: providers.map((provider) => /* @__PURE__ */ jsxs3(
37
163
  "button",
38
164
  {
39
165
  type: "button",
40
166
  onClick: () => onSelect(provider),
41
167
  disabled,
42
- className: "inline-flex h-11 w-full items-center justify-center rounded-md border border-input bg-background px-4 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
43
- children: LABELS[provider] ?? provider
168
+ className: [
169
+ "flex h-[52px] w-full items-center justify-center gap-2.5 rounded-xl sm:h-11",
170
+ "border border-input bg-background text-base font-medium text-foreground sm:text-sm",
171
+ "transition-[background-color,border-color,transform] duration-150 ease-out",
172
+ "hover:border-foreground/20 hover:bg-accent active:translate-y-px",
173
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
174
+ "disabled:pointer-events-none disabled:opacity-55"
175
+ ].join(" "),
176
+ children: [
177
+ /* @__PURE__ */ jsx3(ProviderMark, { provider }),
178
+ copy[provider] ?? provider
179
+ ]
44
180
  },
45
181
  provider
46
182
  )) })
47
183
  ] });
48
184
  }
49
-
50
- // src/components/login-form.tsx
51
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
52
- function oauthErrorMessage(code) {
53
- switch (code) {
54
- case "account_not_linked":
55
- return "This email is already registered with a password. Sign in with your password instead.";
56
- case "access_denied":
57
- return "Sign-in was cancelled.";
58
- default:
59
- return "Sign-in failed. Please try again.";
185
+ function ProviderMark({ provider }) {
186
+ if (provider === "google") {
187
+ return /* @__PURE__ */ jsxs3("svg", { width: "17", height: "17", viewBox: "0 0 18 18", "aria-hidden": "true", children: [
188
+ /* @__PURE__ */ jsx3(
189
+ "path",
190
+ {
191
+ fill: "#4285F4",
192
+ d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"
193
+ }
194
+ ),
195
+ /* @__PURE__ */ jsx3(
196
+ "path",
197
+ {
198
+ fill: "#34A853",
199
+ d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.02-3.7H.96v2.33A9 9 0 0 0 9 18Z"
200
+ }
201
+ ),
202
+ /* @__PURE__ */ jsx3(
203
+ "path",
204
+ {
205
+ fill: "#FBBC05",
206
+ d: "M3.98 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.02-2.33Z"
207
+ }
208
+ ),
209
+ /* @__PURE__ */ jsx3(
210
+ "path",
211
+ {
212
+ fill: "#EA4335",
213
+ d: "M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.46.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.02 2.33C4.68 5.16 6.66 3.58 9 3.58Z"
214
+ }
215
+ )
216
+ ] });
60
217
  }
218
+ return /* @__PURE__ */ jsx3("svg", { width: "17", height: "17", viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx3("path", { d: "M8 0a8 8 0 0 0-2.53 15.59c.4.07.55-.17.55-.38l-.01-1.49c-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.4 7.4 0 0 1 4 0c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48l-.01 2.2c0 .21.15.46.55.38A8 8 0 0 0 8 0Z" }) });
61
219
  }
220
+
221
+ // src/components/login-form.tsx
222
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
223
+ var DEFAULTS = {
224
+ title: "Connexion",
225
+ subtitle: "Content de te revoir. Entre tes identifiants pour continuer.",
226
+ emailPlaceholder: "Adresse e-mail",
227
+ passwordPlaceholder: "Mot de passe",
228
+ forgotPassword: "Mot de passe oubli\xE9 ?",
229
+ submit: "Se connecter",
230
+ submitPending: "Connexion\u2026",
231
+ noAccount: "Pas encore de compte ?",
232
+ register: "Cr\xE9er un compte",
233
+ emailRequired: "Renseigne ton adresse e-mail",
234
+ passwordRequired: "Renseigne ton mot de passe",
235
+ invalidCredentials: "Adresse e-mail ou mot de passe incorrect",
236
+ // accountLinking is disabled in createPlatformAuth, so a social sign-in on an
237
+ // address already registered with a password is refused with this code.
238
+ // Without a message the button reads as broken rather than as a rejection.
239
+ accountNotLinked: "Cette adresse est d\xE9j\xE0 associ\xE9e \xE0 un mot de passe. Connecte-toi avec ton mot de passe.",
240
+ socialCancelled: "Connexion annul\xE9e.",
241
+ socialFailed: "La connexion a \xE9chou\xE9. R\xE9essaie."
242
+ };
62
243
  function LoginForm({
63
244
  onSuccess,
64
245
  registerUrl = "/register",
@@ -66,20 +247,22 @@ function LoginForm({
66
247
  socialCallbackUrl = "/",
67
248
  socialProviders = [],
68
249
  coreTokenUrl = "/api/auth/core-token",
250
+ labels,
69
251
  authClient
70
252
  }) {
71
- const [email, setEmail] = useState("");
72
- const [password, setPassword] = useState("");
73
- const [error, setError] = useState();
74
- const [isPending, setIsPending] = useState(false);
253
+ const t = { ...DEFAULTS, ...labels };
254
+ const [email, setEmail] = useState2("");
255
+ const [password, setPassword] = useState2("");
256
+ const [error, setError] = useState2();
257
+ const [isPending, setIsPending] = useState2(false);
75
258
  const handleSubmit = async (e) => {
76
259
  e.preventDefault();
77
260
  if (!email.trim()) {
78
- setError("Please enter your email address");
261
+ setError(t.emailRequired);
79
262
  return;
80
263
  }
81
264
  if (!password) {
82
- setError("Please enter your password");
265
+ setError(t.passwordRequired);
83
266
  return;
84
267
  }
85
268
  setError(void 0);
@@ -90,7 +273,7 @@ function LoginForm({
90
273
  password
91
274
  });
92
275
  if (res?.error) {
93
- setError(res.error.message ?? "Invalid email or password");
276
+ setError(res.error.message ?? t.invalidCredentials);
94
277
  return;
95
278
  }
96
279
  if (coreTokenUrl) {
@@ -98,7 +281,7 @@ function LoginForm({
98
281
  }
99
282
  onSuccess?.();
100
283
  } catch (err) {
101
- setError(err instanceof Error ? err.message : "Invalid email or password");
284
+ setError(err instanceof Error ? err.message : t.invalidCredentials);
102
285
  } finally {
103
286
  setIsPending(false);
104
287
  }
@@ -111,65 +294,74 @@ function LoginForm({
111
294
  callbackURL: socialCallbackUrl
112
295
  });
113
296
  } catch (err) {
297
+ const code = err instanceof Error ? err.message : "";
114
298
  setError(
115
- err instanceof Error ? oauthErrorMessage(err.message) : oauthErrorMessage("")
299
+ code === "account_not_linked" ? t.accountNotLinked : code === "access_denied" ? t.socialCancelled : t.socialFailed
116
300
  );
117
301
  }
118
302
  };
119
- return /* @__PURE__ */ jsxs2("div", { className: "space-y-8", children: [
120
- /* @__PURE__ */ jsxs2("div", { children: [
121
- /* @__PURE__ */ jsx2("h1", { className: "text-2xl font-bold tracking-tight", children: "Sign in" }),
122
- /* @__PURE__ */ jsx2("p", { className: "mt-1 text-sm text-muted-foreground", children: "Welcome back. Enter your credentials to continue." })
303
+ return /* @__PURE__ */ jsxs4("div", { className: "space-y-7", children: [
304
+ /* @__PURE__ */ jsxs4("header", { className: "space-y-1.5", children: [
305
+ /* @__PURE__ */ jsx4("h1", { className: "text-[26px] font-semibold leading-tight tracking-[-0.02em] text-foreground sm:text-2xl", children: t.title }),
306
+ /* @__PURE__ */ jsx4("p", { className: "text-sm leading-relaxed text-muted-foreground", children: t.subtitle })
123
307
  ] }),
124
- error && /* @__PURE__ */ jsx2("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
125
- /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
126
- /* @__PURE__ */ jsx2(
127
- "input",
308
+ error && /* @__PURE__ */ jsx4(
309
+ "div",
310
+ {
311
+ role: "alert",
312
+ className: "rounded-xl border border-destructive/25 bg-destructive/10 px-3.5 py-3 text-sm leading-snug text-destructive",
313
+ children: error
314
+ }
315
+ ),
316
+ /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className: "space-y-5", noValidate: true, children: [
317
+ /* @__PURE__ */ jsx4(
318
+ AuthField,
128
319
  {
320
+ label: t.emailPlaceholder,
129
321
  type: "email",
322
+ inputMode: "email",
130
323
  value: email,
131
324
  onChange: (e) => setEmail(e.target.value),
132
- placeholder: "Email address",
133
325
  required: true,
134
326
  disabled: isPending,
135
327
  autoComplete: "email",
136
- className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
328
+ autoCapitalize: "none",
329
+ spellCheck: false,
330
+ invalid: !!error
137
331
  }
138
332
  ),
139
- /* @__PURE__ */ jsxs2("div", { className: "space-y-1", children: [
140
- /* @__PURE__ */ jsx2(
141
- "input",
142
- {
143
- type: "password",
144
- value: password,
145
- onChange: (e) => setPassword(e.target.value),
146
- placeholder: "Password",
147
- required: true,
148
- disabled: isPending,
149
- autoComplete: "current-password",
150
- className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
151
- }
152
- ),
153
- /* @__PURE__ */ jsx2("div", { className: "text-right", children: /* @__PURE__ */ jsx2(
154
- "a",
155
- {
156
- href: forgotPasswordUrl,
157
- className: "text-xs text-muted-foreground underline underline-offset-4 hover:text-foreground",
158
- children: "Forgot your password?"
159
- }
160
- ) })
161
- ] }),
162
- /* @__PURE__ */ jsx2(
163
- "button",
333
+ /* @__PURE__ */ jsx4(
334
+ AuthField,
164
335
  {
165
- type: "submit",
166
- disabled: isPending || !email.trim() || !password,
167
- className: "inline-flex h-11 w-full items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-50",
168
- children: isPending ? "Signing in..." : "Sign in"
336
+ label: t.passwordPlaceholder,
337
+ type: "password",
338
+ value: password,
339
+ onChange: (e) => setPassword(e.target.value),
340
+ required: true,
341
+ disabled: isPending,
342
+ autoComplete: "current-password",
343
+ invalid: !!error,
344
+ hint: /* @__PURE__ */ jsx4(
345
+ "a",
346
+ {
347
+ href: forgotPasswordUrl,
348
+ className: "rounded text-xs text-muted-foreground underline-offset-4 transition-colors hover:text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
349
+ children: t.forgotPassword
350
+ }
351
+ )
352
+ }
353
+ ),
354
+ /* @__PURE__ */ jsx4(
355
+ AuthSubmit,
356
+ {
357
+ pending: isPending,
358
+ disabled: !email.trim() || !password,
359
+ pendingLabel: t.submitPending,
360
+ children: t.submit
169
361
  }
170
362
  )
171
363
  ] }),
172
- /* @__PURE__ */ jsx2(
364
+ /* @__PURE__ */ jsx4(
173
365
  SocialButtons,
174
366
  {
175
367
  providers: socialProviders,
@@ -177,15 +369,15 @@ function LoginForm({
177
369
  disabled: isPending
178
370
  }
179
371
  ),
180
- /* @__PURE__ */ jsxs2("p", { className: "text-center text-sm text-muted-foreground", children: [
181
- "Don't have an account?",
372
+ /* @__PURE__ */ jsxs4("p", { className: "text-center text-sm text-muted-foreground", children: [
373
+ t.noAccount,
182
374
  " ",
183
- /* @__PURE__ */ jsx2(
375
+ /* @__PURE__ */ jsx4(
184
376
  "a",
185
377
  {
186
378
  href: registerUrl,
187
- className: "font-medium text-foreground underline underline-offset-4 hover:text-foreground/80",
188
- children: "Sign up"
379
+ className: "rounded font-medium text-foreground underline underline-offset-4 decoration-foreground/25 transition-colors hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
380
+ children: t.register
189
381
  }
190
382
  )
191
383
  ] })
@@ -193,34 +385,53 @@ function LoginForm({
193
385
  }
194
386
 
195
387
  // src/components/register-form.tsx
196
- import { useState as useState2 } from "react";
197
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
388
+ import { useState as useState3 } from "react";
389
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
198
390
  var MIN_PASSWORD_LENGTH = 8;
391
+ var DEFAULTS2 = {
392
+ title: "Cr\xE9er un compte",
393
+ subtitle: "Nous t'enverrons un code pour confirmer ton adresse e-mail.",
394
+ namePlaceholder: "Nom complet",
395
+ emailPlaceholder: "Adresse e-mail",
396
+ passwordPlaceholder: "Mot de passe",
397
+ passwordHint: `Au moins ${MIN_PASSWORD_LENGTH} caract\xE8res.`,
398
+ submit: "Cr\xE9er mon compte",
399
+ submitPending: "Cr\xE9ation\u2026",
400
+ haveAccount: "Tu as d\xE9j\xE0 un compte ?",
401
+ login: "Se connecter",
402
+ nameRequired: "Renseigne ton nom",
403
+ emailRequired: "Renseigne ton adresse e-mail",
404
+ passwordTooShort: `Le mot de passe doit faire au moins ${MIN_PASSWORD_LENGTH} caract\xE8res`,
405
+ signUpFailed: "La cr\xE9ation du compte a \xE9chou\xE9"
406
+ };
199
407
  function RegisterForm({
200
408
  onSuccess,
201
409
  loginUrl = "/login",
202
410
  legal,
203
411
  socialCallbackUrl = "/",
204
412
  socialProviders = [],
413
+ labels,
205
414
  authClient
206
415
  }) {
207
- const [name, setName] = useState2("");
208
- const [email, setEmail] = useState2("");
209
- const [password, setPassword] = useState2("");
210
- const [error, setError] = useState2();
211
- const [isPending, setIsPending] = useState2(false);
416
+ const t = { ...DEFAULTS2, ...labels };
417
+ const [name, setName] = useState3("");
418
+ const [email, setEmail] = useState3("");
419
+ const [password, setPassword] = useState3("");
420
+ const [error, setError] = useState3();
421
+ const [isPending, setIsPending] = useState3(false);
422
+ const tooShort = password.length > 0 && password.length < MIN_PASSWORD_LENGTH;
212
423
  const handleSubmit = async (e) => {
213
424
  e.preventDefault();
214
425
  if (!name.trim()) {
215
- setError("Please enter your name");
426
+ setError(t.nameRequired);
216
427
  return;
217
428
  }
218
429
  if (!email.trim()) {
219
- setError("Please enter your email address");
430
+ setError(t.emailRequired);
220
431
  return;
221
432
  }
222
433
  if (password.length < MIN_PASSWORD_LENGTH) {
223
- setError(`Password must be at least ${MIN_PASSWORD_LENGTH} characters`);
434
+ setError(t.passwordTooShort);
224
435
  return;
225
436
  }
226
437
  setError(void 0);
@@ -232,14 +443,12 @@ function RegisterForm({
232
443
  password
233
444
  });
234
445
  if (res?.error) {
235
- setError(res.error.message ?? "Could not create your account");
446
+ setError(res.error.message ?? t.signUpFailed);
236
447
  return;
237
448
  }
238
449
  onSuccess?.(email.trim());
239
450
  } catch (err) {
240
- setError(
241
- err instanceof Error ? err.message : "Could not create your account"
242
- );
451
+ setError(err instanceof Error ? err.message : t.signUpFailed);
243
452
  } finally {
244
453
  setIsPending(false);
245
454
  }
@@ -252,75 +461,68 @@ function RegisterForm({
252
461
  callbackURL: socialCallbackUrl
253
462
  });
254
463
  } catch (err) {
255
- setError(err instanceof Error ? err.message : "Sign-up failed");
464
+ setError(err instanceof Error ? err.message : t.signUpFailed);
256
465
  }
257
466
  };
258
- return /* @__PURE__ */ jsxs3("div", { className: "space-y-8", children: [
259
- /* @__PURE__ */ jsxs3("div", { children: [
260
- /* @__PURE__ */ jsx3("h1", { className: "text-2xl font-bold tracking-tight", children: "Create an account" }),
261
- /* @__PURE__ */ jsx3("p", { className: "mt-1 text-sm text-muted-foreground", children: "We'll send you a code to confirm your email address." })
467
+ return /* @__PURE__ */ jsxs5("div", { className: "space-y-7", children: [
468
+ /* @__PURE__ */ jsxs5("header", { className: "space-y-1.5", children: [
469
+ /* @__PURE__ */ jsx5("h1", { className: "text-[26px] font-semibold leading-tight tracking-[-0.02em] text-foreground sm:text-2xl", children: t.title }),
470
+ /* @__PURE__ */ jsx5("p", { className: "text-sm leading-relaxed text-muted-foreground", children: t.subtitle })
262
471
  ] }),
263
- error && /* @__PURE__ */ jsx3("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
264
- /* @__PURE__ */ jsxs3("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
265
- /* @__PURE__ */ jsx3(
266
- "input",
472
+ error && /* @__PURE__ */ jsx5(
473
+ "div",
474
+ {
475
+ role: "alert",
476
+ className: "rounded-xl border border-destructive/25 bg-destructive/10 px-3.5 py-3 text-sm leading-snug text-destructive",
477
+ children: error
478
+ }
479
+ ),
480
+ /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className: "space-y-5", noValidate: true, children: [
481
+ /* @__PURE__ */ jsx5(
482
+ AuthField,
267
483
  {
484
+ label: t.namePlaceholder,
268
485
  type: "text",
269
486
  value: name,
270
487
  onChange: (e) => setName(e.target.value),
271
- placeholder: "Full name",
272
488
  required: true,
273
489
  disabled: isPending,
274
- autoComplete: "name",
275
- className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
490
+ autoComplete: "name"
276
491
  }
277
492
  ),
278
- /* @__PURE__ */ jsx3(
279
- "input",
493
+ /* @__PURE__ */ jsx5(
494
+ AuthField,
280
495
  {
496
+ label: t.emailPlaceholder,
281
497
  type: "email",
498
+ inputMode: "email",
282
499
  value: email,
283
500
  onChange: (e) => setEmail(e.target.value),
284
- placeholder: "Email address",
285
501
  required: true,
286
502
  disabled: isPending,
287
503
  autoComplete: "email",
288
- className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
504
+ autoCapitalize: "none",
505
+ spellCheck: false
289
506
  }
290
507
  ),
291
- /* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
292
- /* @__PURE__ */ jsx3(
293
- "input",
294
- {
295
- type: "password",
296
- value: password,
297
- onChange: (e) => setPassword(e.target.value),
298
- placeholder: "Password",
299
- required: true,
300
- disabled: isPending,
301
- autoComplete: "new-password",
302
- "aria-describedby": "register-password-hint",
303
- className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
304
- }
305
- ),
306
- /* @__PURE__ */ jsxs3("p", { id: "register-password-hint", className: "text-xs text-muted-foreground", children: [
307
- "At least ",
308
- MIN_PASSWORD_LENGTH,
309
- " characters."
310
- ] })
311
- ] }),
312
- /* @__PURE__ */ jsx3(
313
- "button",
508
+ /* @__PURE__ */ jsx5(
509
+ AuthField,
314
510
  {
315
- type: "submit",
511
+ label: t.passwordPlaceholder,
512
+ type: "password",
513
+ value: password,
514
+ onChange: (e) => setPassword(e.target.value),
515
+ required: true,
316
516
  disabled: isPending,
317
- className: "inline-flex h-11 w-full items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-50",
318
- children: isPending ? "Creating account..." : "Create account"
517
+ autoComplete: "new-password",
518
+ description: t.passwordHint,
519
+ invalid: tooShort
319
520
  }
320
521
  ),
321
- legal && /* @__PURE__ */ jsx3("div", { className: "text-center text-xs text-muted-foreground", children: legal })
522
+ /* @__PURE__ */ jsx5(AuthSubmit, { pending: isPending, pendingLabel: t.submitPending, children: t.submit }),
523
+ legal && /* @__PURE__ */ jsx5("p", { className: "text-center text-xs leading-relaxed text-muted-foreground", children: legal })
322
524
  ] }),
323
- /* @__PURE__ */ jsx3(
525
+ /* @__PURE__ */ jsx5(
324
526
  SocialButtons,
325
527
  {
326
528
  providers: socialProviders,
@@ -328,15 +530,15 @@ function RegisterForm({
328
530
  disabled: isPending
329
531
  }
330
532
  ),
331
- /* @__PURE__ */ jsxs3("p", { className: "text-center text-sm text-muted-foreground", children: [
332
- "Already have an account?",
533
+ /* @__PURE__ */ jsxs5("p", { className: "text-center text-sm text-muted-foreground", children: [
534
+ t.haveAccount,
333
535
  " ",
334
- /* @__PURE__ */ jsx3(
536
+ /* @__PURE__ */ jsx5(
335
537
  "a",
336
538
  {
337
539
  href: loginUrl,
338
- className: "font-medium text-foreground underline underline-offset-4 hover:text-foreground/80",
339
- children: "Sign in"
540
+ className: "rounded font-medium text-foreground underline underline-offset-4 decoration-foreground/25 transition-colors hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
541
+ children: t.login
340
542
  }
341
543
  )
342
544
  ] })
@@ -344,18 +546,18 @@ function RegisterForm({
344
546
  }
345
547
 
346
548
  // src/components/verify-email-form.tsx
347
- import { useState as useState3 } from "react";
348
- import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
549
+ import { useState as useState4 } from "react";
550
+ import { Fragment, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
349
551
  function VerifyEmailForm({
350
552
  email,
351
553
  onSuccess,
352
554
  authClient
353
555
  }) {
354
- const [otp, setOtp] = useState3("");
355
- const [isVerifying, setIsVerifying] = useState3(false);
356
- const [isResending, setIsResending] = useState3(false);
357
- const [resendMessage, setResendMessage] = useState3();
358
- const [error, setError] = useState3();
556
+ const [otp, setOtp] = useState4("");
557
+ const [isVerifying, setIsVerifying] = useState4(false);
558
+ const [isResending, setIsResending] = useState4(false);
559
+ const [resendMessage, setResendMessage] = useState4();
560
+ const [error, setError] = useState4();
359
561
  const handleVerify = async (e) => {
360
562
  e.preventDefault();
361
563
  if (!otp.trim() || otp.length < 6) {
@@ -398,19 +600,19 @@ function VerifyEmailForm({
398
600
  setIsResending(false);
399
601
  }
400
602
  };
401
- return /* @__PURE__ */ jsxs4("div", { className: "space-y-8", children: [
402
- /* @__PURE__ */ jsxs4("div", { children: [
403
- /* @__PURE__ */ jsx4("h1", { className: "text-2xl font-bold tracking-tight", children: "Verify your email" }),
404
- /* @__PURE__ */ jsx4("p", { className: "mt-1 text-sm text-muted-foreground", children: email ? /* @__PURE__ */ jsxs4(Fragment, { children: [
603
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-8", children: [
604
+ /* @__PURE__ */ jsxs6("div", { children: [
605
+ /* @__PURE__ */ jsx6("h1", { className: "text-2xl font-bold tracking-tight", children: "Verify your email" }),
606
+ /* @__PURE__ */ jsx6("p", { className: "mt-1 text-sm text-muted-foreground", children: email ? /* @__PURE__ */ jsxs6(Fragment, { children: [
405
607
  "Enter the 6-digit code sent to",
406
608
  " ",
407
- /* @__PURE__ */ jsx4("span", { className: "font-medium text-foreground", children: email })
609
+ /* @__PURE__ */ jsx6("span", { className: "font-medium text-foreground", children: email })
408
610
  ] }) : "Enter the 6-digit code sent to your email" })
409
611
  ] }),
410
- error && /* @__PURE__ */ jsx4("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
411
- resendMessage && /* @__PURE__ */ jsx4("div", { className: "rounded-lg border border-green-200 bg-green-50 px-3 py-2 text-xs text-green-700", children: resendMessage }),
412
- /* @__PURE__ */ jsxs4("form", { onSubmit: handleVerify, className: "space-y-4", noValidate: true, children: [
413
- /* @__PURE__ */ jsx4(
612
+ error && /* @__PURE__ */ jsx6("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
613
+ resendMessage && /* @__PURE__ */ jsx6("div", { className: "rounded-lg border border-green-200 bg-green-50 px-3 py-2 text-xs text-green-700", children: resendMessage }),
614
+ /* @__PURE__ */ jsxs6("form", { onSubmit: handleVerify, className: "space-y-4", noValidate: true, children: [
615
+ /* @__PURE__ */ jsx6(
414
616
  "input",
415
617
  {
416
618
  type: "text",
@@ -426,7 +628,7 @@ function VerifyEmailForm({
426
628
  className: "flex h-12 w-full rounded-md border border-input bg-background px-3 py-2 text-center text-lg tracking-[0.4em] font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
427
629
  }
428
630
  ),
429
- /* @__PURE__ */ jsx4(
631
+ /* @__PURE__ */ jsx6(
430
632
  "button",
431
633
  {
432
634
  type: "submit",
@@ -435,7 +637,7 @@ function VerifyEmailForm({
435
637
  children: isVerifying ? "Verifying..." : "Verify email"
436
638
  }
437
639
  ),
438
- /* @__PURE__ */ jsx4(
640
+ /* @__PURE__ */ jsx6(
439
641
  "button",
440
642
  {
441
643
  type: "button",
@@ -446,10 +648,10 @@ function VerifyEmailForm({
446
648
  }
447
649
  )
448
650
  ] }),
449
- /* @__PURE__ */ jsxs4("p", { className: "text-center text-sm text-muted-foreground", children: [
651
+ /* @__PURE__ */ jsxs6("p", { className: "text-center text-sm text-muted-foreground", children: [
450
652
  "Already verified?",
451
653
  " ",
452
- /* @__PURE__ */ jsx4(
654
+ /* @__PURE__ */ jsx6(
453
655
  "a",
454
656
  {
455
657
  href: "/login",
@@ -462,16 +664,16 @@ function VerifyEmailForm({
462
664
  }
463
665
 
464
666
  // src/components/forgot-password-form.tsx
465
- import { useState as useState4 } from "react";
466
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
667
+ import { useState as useState5 } from "react";
668
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
467
669
  function ForgotPasswordForm({
468
670
  onSuccess,
469
671
  loginUrl = "/login",
470
672
  authClient
471
673
  }) {
472
- const [email, setEmail] = useState4("");
473
- const [error, setError] = useState4();
474
- const [isPending, setIsPending] = useState4(false);
674
+ const [email, setEmail] = useState5("");
675
+ const [error, setError] = useState5();
676
+ const [isPending, setIsPending] = useState5(false);
475
677
  const handleSubmit = async (e) => {
476
678
  e.preventDefault();
477
679
  if (!email.trim()) {
@@ -496,14 +698,14 @@ function ForgotPasswordForm({
496
698
  setIsPending(false);
497
699
  }
498
700
  };
499
- return /* @__PURE__ */ jsxs5("div", { className: "space-y-8", children: [
500
- /* @__PURE__ */ jsxs5("div", { children: [
501
- /* @__PURE__ */ jsx5("h1", { className: "text-2xl font-bold tracking-tight", children: "Forgot your password?" }),
502
- /* @__PURE__ */ jsx5("p", { className: "mt-1 text-sm text-muted-foreground", children: "Enter your email address and we'll send you a code to reset your password." })
701
+ return /* @__PURE__ */ jsxs7("div", { className: "space-y-8", children: [
702
+ /* @__PURE__ */ jsxs7("div", { children: [
703
+ /* @__PURE__ */ jsx7("h1", { className: "text-2xl font-bold tracking-tight", children: "Forgot your password?" }),
704
+ /* @__PURE__ */ jsx7("p", { className: "mt-1 text-sm text-muted-foreground", children: "Enter your email address and we'll send you a code to reset your password." })
503
705
  ] }),
504
- error && /* @__PURE__ */ jsx5("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
505
- /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
506
- /* @__PURE__ */ jsx5(
706
+ error && /* @__PURE__ */ jsx7("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
707
+ /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
708
+ /* @__PURE__ */ jsx7(
507
709
  "input",
508
710
  {
509
711
  type: "email",
@@ -516,7 +718,7 @@ function ForgotPasswordForm({
516
718
  className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
517
719
  }
518
720
  ),
519
- /* @__PURE__ */ jsx5(
721
+ /* @__PURE__ */ jsx7(
520
722
  "button",
521
723
  {
522
724
  type: "submit",
@@ -526,10 +728,10 @@ function ForgotPasswordForm({
526
728
  }
527
729
  )
528
730
  ] }),
529
- /* @__PURE__ */ jsxs5("p", { className: "text-center text-sm text-muted-foreground", children: [
731
+ /* @__PURE__ */ jsxs7("p", { className: "text-center text-sm text-muted-foreground", children: [
530
732
  "Remember your password?",
531
733
  " ",
532
- /* @__PURE__ */ jsx5(
734
+ /* @__PURE__ */ jsx7(
533
735
  "a",
534
736
  {
535
737
  href: loginUrl,
@@ -542,21 +744,21 @@ function ForgotPasswordForm({
542
744
  }
543
745
 
544
746
  // src/components/reset-password-form.tsx
545
- import { useState as useState5 } from "react";
546
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
747
+ import { useState as useState6 } from "react";
748
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
547
749
  function ResetPasswordForm({
548
750
  email,
549
751
  onSuccess,
550
752
  loginUrl = "/login",
551
753
  authClient
552
754
  }) {
553
- const [otp, setOtp] = useState5("");
554
- const [password, setPassword] = useState5("");
555
- const [confirmPassword, setConfirmPassword] = useState5("");
556
- const [error, setError] = useState5();
557
- const [isResetting, setIsResetting] = useState5(false);
558
- const [isResending, setIsResending] = useState5(false);
559
- const [resendMessage, setResendMessage] = useState5();
755
+ const [otp, setOtp] = useState6("");
756
+ const [password, setPassword] = useState6("");
757
+ const [confirmPassword, setConfirmPassword] = useState6("");
758
+ const [error, setError] = useState6();
759
+ const [isResetting, setIsResetting] = useState6(false);
760
+ const [isResending, setIsResending] = useState6(false);
761
+ const [resendMessage, setResendMessage] = useState6();
560
762
  const handleSubmit = async (e) => {
561
763
  e.preventDefault();
562
764
  if (!otp.trim() || otp.length < 6) {
@@ -609,20 +811,20 @@ function ResetPasswordForm({
609
811
  setIsResending(false);
610
812
  }
611
813
  };
612
- return /* @__PURE__ */ jsxs6("div", { className: "space-y-8", children: [
613
- /* @__PURE__ */ jsxs6("div", { children: [
614
- /* @__PURE__ */ jsx6("h1", { className: "text-2xl font-bold tracking-tight", children: "Reset your password" }),
615
- /* @__PURE__ */ jsxs6("p", { className: "mt-1 text-sm text-muted-foreground", children: [
814
+ return /* @__PURE__ */ jsxs8("div", { className: "space-y-8", children: [
815
+ /* @__PURE__ */ jsxs8("div", { children: [
816
+ /* @__PURE__ */ jsx8("h1", { className: "text-2xl font-bold tracking-tight", children: "Reset your password" }),
817
+ /* @__PURE__ */ jsxs8("p", { className: "mt-1 text-sm text-muted-foreground", children: [
616
818
  "Enter the 6-digit code sent to",
617
819
  " ",
618
- /* @__PURE__ */ jsx6("span", { className: "font-medium text-foreground", children: email }),
820
+ /* @__PURE__ */ jsx8("span", { className: "font-medium text-foreground", children: email }),
619
821
  " and your new password."
620
822
  ] })
621
823
  ] }),
622
- error && /* @__PURE__ */ jsx6("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
623
- resendMessage && /* @__PURE__ */ jsx6("div", { className: "rounded-lg border border-green-200 bg-green-50 px-3 py-2 text-xs text-green-700", children: resendMessage }),
624
- /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
625
- /* @__PURE__ */ jsx6(
824
+ error && /* @__PURE__ */ jsx8("div", { className: "rounded-lg border border-destructive/20 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
825
+ resendMessage && /* @__PURE__ */ jsx8("div", { className: "rounded-lg border border-green-200 bg-green-50 px-3 py-2 text-xs text-green-700", children: resendMessage }),
826
+ /* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
827
+ /* @__PURE__ */ jsx8(
626
828
  "input",
627
829
  {
628
830
  type: "text",
@@ -638,7 +840,7 @@ function ResetPasswordForm({
638
840
  className: "flex h-12 w-full rounded-md border border-input bg-background px-3 py-2 text-center text-lg tracking-[0.4em] font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
639
841
  }
640
842
  ),
641
- /* @__PURE__ */ jsx6(
843
+ /* @__PURE__ */ jsx8(
642
844
  "input",
643
845
  {
644
846
  type: "password",
@@ -651,7 +853,7 @@ function ResetPasswordForm({
651
853
  className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
652
854
  }
653
855
  ),
654
- /* @__PURE__ */ jsx6(
856
+ /* @__PURE__ */ jsx8(
655
857
  "input",
656
858
  {
657
859
  type: "password",
@@ -664,7 +866,7 @@ function ResetPasswordForm({
664
866
  className: "flex h-11 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
665
867
  }
666
868
  ),
667
- /* @__PURE__ */ jsx6(
869
+ /* @__PURE__ */ jsx8(
668
870
  "button",
669
871
  {
670
872
  type: "submit",
@@ -673,7 +875,7 @@ function ResetPasswordForm({
673
875
  children: isResetting ? "Resetting..." : "Reset password"
674
876
  }
675
877
  ),
676
- /* @__PURE__ */ jsx6(
878
+ /* @__PURE__ */ jsx8(
677
879
  "button",
678
880
  {
679
881
  type: "button",
@@ -684,10 +886,10 @@ function ResetPasswordForm({
684
886
  }
685
887
  )
686
888
  ] }),
687
- /* @__PURE__ */ jsxs6("p", { className: "text-center text-sm text-muted-foreground", children: [
889
+ /* @__PURE__ */ jsxs8("p", { className: "text-center text-sm text-muted-foreground", children: [
688
890
  "Remember your password?",
689
891
  " ",
690
- /* @__PURE__ */ jsx6(
892
+ /* @__PURE__ */ jsx8(
691
893
  "a",
692
894
  {
693
895
  href: loginUrl,
@@ -700,7 +902,7 @@ function ResetPasswordForm({
700
902
  }
701
903
 
702
904
  // src/components/auth-layout.tsx
703
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
905
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
704
906
  function AuthLayout({
705
907
  logo,
706
908
  title,
@@ -708,19 +910,19 @@ function AuthLayout({
708
910
  children,
709
911
  footer
710
912
  }) {
711
- return /* @__PURE__ */ jsx7("div", { className: "flex min-h-screen items-center justify-center bg-background", children: /* @__PURE__ */ jsxs7("div", { className: "w-full max-w-md", children: [
712
- /* @__PURE__ */ jsxs7("div", { className: "mb-10 text-center", children: [
713
- logo && /* @__PURE__ */ jsx7("div", { className: "mb-6 flex justify-center", children: logo }),
714
- /* @__PURE__ */ jsx7("h1", { className: "text-[32px] font-light tracking-tight", children: title }),
715
- subtitle && /* @__PURE__ */ jsx7("p", { className: "mt-2 text-sm text-muted-foreground", children: subtitle })
913
+ return /* @__PURE__ */ jsx9("div", { className: "flex min-h-dvh flex-col bg-background px-5 pb-10 pt-12 sm:items-center sm:justify-center sm:bg-muted/40 sm:px-6 sm:py-12", children: /* @__PURE__ */ jsxs9("div", { className: "mx-auto w-full max-w-[420px]", children: [
914
+ /* @__PURE__ */ jsxs9("div", { className: "mb-8 text-center sm:mb-7", children: [
915
+ logo && /* @__PURE__ */ jsx9("div", { className: "mb-5 flex justify-center", children: logo }),
916
+ /* @__PURE__ */ jsx9("p", { className: "text-sm font-medium tracking-[0.02em] text-foreground", children: title }),
917
+ subtitle && /* @__PURE__ */ jsx9("p", { className: "mt-1 text-sm text-muted-foreground", children: subtitle })
716
918
  ] }),
717
- /* @__PURE__ */ jsx7("div", { className: "rounded-xl border bg-card p-8 shadow-sm", children }),
718
- footer && /* @__PURE__ */ jsx7("div", { className: "mt-6 text-center text-xs text-muted-foreground", children: footer })
919
+ /* @__PURE__ */ jsx9("div", { className: "sm:rounded-2xl sm:border sm:border-border/70 sm:bg-card sm:p-8 sm:shadow-[0_1px_2px_rgba(0,0,0,0.04),0_8px_24px_-12px_rgba(0,0,0,0.12)]", children }),
920
+ footer && /* @__PURE__ */ jsx9("div", { className: "mt-6 text-center text-xs leading-relaxed text-muted-foreground", children: footer })
719
921
  ] }) });
720
922
  }
721
923
 
722
924
  // src/components/invitation-notice.tsx
723
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
925
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
724
926
  function defaultSupportEmail() {
725
927
  if (typeof window === "undefined") return void 0;
726
928
  const host = window.location.hostname;
@@ -740,15 +942,15 @@ function InvitationNotice({
740
942
  action
741
943
  }) {
742
944
  const contact = supportEmail ?? defaultSupportEmail();
743
- return /* @__PURE__ */ jsxs8("div", { className: "space-y-8", children: [
744
- /* @__PURE__ */ jsxs8("div", { children: [
745
- /* @__PURE__ */ jsx8("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
746
- /* @__PURE__ */ jsx8("p", { className: "mt-1 text-sm text-muted-foreground", children: REASON_MESSAGE[reason] ?? REASON_MESSAGE.unknown })
945
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-8", children: [
946
+ /* @__PURE__ */ jsxs10("div", { children: [
947
+ /* @__PURE__ */ jsx10("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
948
+ /* @__PURE__ */ jsx10("p", { className: "mt-1 text-sm text-muted-foreground", children: REASON_MESSAGE[reason] ?? REASON_MESSAGE.unknown })
747
949
  ] }),
748
- contact ? /* @__PURE__ */ jsxs8("p", { className: "text-sm text-muted-foreground", children: [
950
+ contact ? /* @__PURE__ */ jsxs10("p", { className: "text-sm text-muted-foreground", children: [
749
951
  "\xC9crivez-nous \xE0",
750
952
  " ",
751
- /* @__PURE__ */ jsx8(
953
+ /* @__PURE__ */ jsx10(
752
954
  "a",
753
955
  {
754
956
  href: `mailto:${contact}`,
@@ -763,7 +965,9 @@ function InvitationNotice({
763
965
  ] });
764
966
  }
765
967
  export {
968
+ AuthField,
766
969
  AuthLayout,
970
+ AuthSubmit,
767
971
  ForgotPasswordForm,
768
972
  InvitationNotice,
769
973
  LoginForm,