@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/client.d.ts +1 -1
- package/dist/index.d.ts +68 -7
- package/dist/index.js +418 -214
- package/dist/index.js.map +1 -1
- package/dist/{invitation-CzfLna7q.d.ts → invitation-Bucmin-z.d.ts} +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/{types-DxllDyOa.d.ts → types-BXyGxKtF.d.ts} +43 -1
- package/package.json +1 -1
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: "
|
|
23
|
-
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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:
|
|
43
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
72
|
-
const [
|
|
73
|
-
const [
|
|
74
|
-
const [
|
|
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(
|
|
261
|
+
setError(t.emailRequired);
|
|
79
262
|
return;
|
|
80
263
|
}
|
|
81
264
|
if (!password) {
|
|
82
|
-
setError(
|
|
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 ??
|
|
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 :
|
|
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
|
-
|
|
299
|
+
code === "account_not_linked" ? t.accountNotLinked : code === "access_denied" ? t.socialCancelled : t.socialFailed
|
|
116
300
|
);
|
|
117
301
|
}
|
|
118
302
|
};
|
|
119
|
-
return /* @__PURE__ */
|
|
120
|
-
/* @__PURE__ */
|
|
121
|
-
/* @__PURE__ */
|
|
122
|
-
/* @__PURE__ */
|
|
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__ */
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"
|
|
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
|
-
|
|
328
|
+
autoCapitalize: "none",
|
|
329
|
+
spellCheck: false,
|
|
330
|
+
invalid: !!error
|
|
137
331
|
}
|
|
138
332
|
),
|
|
139
|
-
/* @__PURE__ */
|
|
140
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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__ */
|
|
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__ */
|
|
181
|
-
|
|
372
|
+
/* @__PURE__ */ jsxs4("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
373
|
+
t.noAccount,
|
|
182
374
|
" ",
|
|
183
|
-
/* @__PURE__ */
|
|
375
|
+
/* @__PURE__ */ jsx4(
|
|
184
376
|
"a",
|
|
185
377
|
{
|
|
186
378
|
href: registerUrl,
|
|
187
|
-
className: "font-medium text-foreground underline underline-offset-4 hover:
|
|
188
|
-
children:
|
|
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
|
|
197
|
-
import { jsx as
|
|
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
|
|
208
|
-
const [
|
|
209
|
-
const [
|
|
210
|
-
const [
|
|
211
|
-
const [
|
|
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(
|
|
426
|
+
setError(t.nameRequired);
|
|
216
427
|
return;
|
|
217
428
|
}
|
|
218
429
|
if (!email.trim()) {
|
|
219
|
-
setError(
|
|
430
|
+
setError(t.emailRequired);
|
|
220
431
|
return;
|
|
221
432
|
}
|
|
222
433
|
if (password.length < MIN_PASSWORD_LENGTH) {
|
|
223
|
-
setError(
|
|
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 ??
|
|
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 :
|
|
464
|
+
setError(err instanceof Error ? err.message : t.signUpFailed);
|
|
256
465
|
}
|
|
257
466
|
};
|
|
258
|
-
return /* @__PURE__ */
|
|
259
|
-
/* @__PURE__ */
|
|
260
|
-
/* @__PURE__ */
|
|
261
|
-
/* @__PURE__ */
|
|
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__ */
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
"
|
|
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__ */
|
|
279
|
-
|
|
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
|
-
|
|
504
|
+
autoCapitalize: "none",
|
|
505
|
+
spellCheck: false
|
|
289
506
|
}
|
|
290
507
|
),
|
|
291
|
-
/* @__PURE__ */
|
|
292
|
-
|
|
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
|
-
|
|
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
|
-
|
|
318
|
-
|
|
517
|
+
autoComplete: "new-password",
|
|
518
|
+
description: t.passwordHint,
|
|
519
|
+
invalid: tooShort
|
|
319
520
|
}
|
|
320
521
|
),
|
|
321
|
-
|
|
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__ */
|
|
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__ */
|
|
332
|
-
|
|
533
|
+
/* @__PURE__ */ jsxs5("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
534
|
+
t.haveAccount,
|
|
333
535
|
" ",
|
|
334
|
-
/* @__PURE__ */
|
|
536
|
+
/* @__PURE__ */ jsx5(
|
|
335
537
|
"a",
|
|
336
538
|
{
|
|
337
539
|
href: loginUrl,
|
|
338
|
-
className: "font-medium text-foreground underline underline-offset-4 hover:
|
|
339
|
-
children:
|
|
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
|
|
348
|
-
import { Fragment, jsx as
|
|
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] =
|
|
355
|
-
const [isVerifying, setIsVerifying] =
|
|
356
|
-
const [isResending, setIsResending] =
|
|
357
|
-
const [resendMessage, setResendMessage] =
|
|
358
|
-
const [error, setError] =
|
|
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__ */
|
|
402
|
-
/* @__PURE__ */
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
411
|
-
resendMessage && /* @__PURE__ */
|
|
412
|
-
/* @__PURE__ */
|
|
413
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
651
|
+
/* @__PURE__ */ jsxs6("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
450
652
|
"Already verified?",
|
|
451
653
|
" ",
|
|
452
|
-
/* @__PURE__ */
|
|
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
|
|
466
|
-
import { jsx as
|
|
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] =
|
|
473
|
-
const [error, setError] =
|
|
474
|
-
const [isPending, setIsPending] =
|
|
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__ */
|
|
500
|
-
/* @__PURE__ */
|
|
501
|
-
/* @__PURE__ */
|
|
502
|
-
/* @__PURE__ */
|
|
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__ */
|
|
505
|
-
/* @__PURE__ */
|
|
506
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
731
|
+
/* @__PURE__ */ jsxs7("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
530
732
|
"Remember your password?",
|
|
531
733
|
" ",
|
|
532
|
-
/* @__PURE__ */
|
|
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
|
|
546
|
-
import { jsx as
|
|
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] =
|
|
554
|
-
const [password, setPassword] =
|
|
555
|
-
const [confirmPassword, setConfirmPassword] =
|
|
556
|
-
const [error, setError] =
|
|
557
|
-
const [isResetting, setIsResetting] =
|
|
558
|
-
const [isResending, setIsResending] =
|
|
559
|
-
const [resendMessage, setResendMessage] =
|
|
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__ */
|
|
613
|
-
/* @__PURE__ */
|
|
614
|
-
/* @__PURE__ */
|
|
615
|
-
/* @__PURE__ */
|
|
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__ */
|
|
820
|
+
/* @__PURE__ */ jsx8("span", { className: "font-medium text-foreground", children: email }),
|
|
619
821
|
" and your new password."
|
|
620
822
|
] })
|
|
621
823
|
] }),
|
|
622
|
-
error && /* @__PURE__ */
|
|
623
|
-
resendMessage && /* @__PURE__ */
|
|
624
|
-
/* @__PURE__ */
|
|
625
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
889
|
+
/* @__PURE__ */ jsxs8("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
688
890
|
"Remember your password?",
|
|
689
891
|
" ",
|
|
690
|
-
/* @__PURE__ */
|
|
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
|
|
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__ */
|
|
712
|
-
/* @__PURE__ */
|
|
713
|
-
logo && /* @__PURE__ */
|
|
714
|
-
/* @__PURE__ */
|
|
715
|
-
subtitle && /* @__PURE__ */
|
|
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__ */
|
|
718
|
-
footer && /* @__PURE__ */
|
|
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
|
|
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__ */
|
|
744
|
-
/* @__PURE__ */
|
|
745
|
-
/* @__PURE__ */
|
|
746
|
-
/* @__PURE__ */
|
|
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__ */
|
|
950
|
+
contact ? /* @__PURE__ */ jsxs10("p", { className: "text-sm text-muted-foreground", children: [
|
|
749
951
|
"\xC9crivez-nous \xE0",
|
|
750
952
|
" ",
|
|
751
|
-
/* @__PURE__ */
|
|
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,
|