@mesob/auth-react 0.0.3
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/components/auth-card.d.ts +9 -0
- package/dist/components/auth-card.js +11 -0
- package/dist/components/auth-card.js.map +1 -0
- package/dist/components/auth-page-layout.d.ts +14 -0
- package/dist/components/auth-page-layout.js +28 -0
- package/dist/components/auth-page-layout.js.map +1 -0
- package/dist/components/countdown.d.ts +10 -0
- package/dist/components/countdown.js +57 -0
- package/dist/components/countdown.js.map +1 -0
- package/dist/components/forgot-password.d.ts +13 -0
- package/dist/components/forgot-password.js +67 -0
- package/dist/components/forgot-password.js.map +1 -0
- package/dist/components/pages/forgot-password-page.d.ts +17 -0
- package/dist/components/pages/forgot-password-page.js +224 -0
- package/dist/components/pages/forgot-password-page.js.map +1 -0
- package/dist/components/pages/reset-password-page.d.ts +19 -0
- package/dist/components/pages/reset-password-page.js +357 -0
- package/dist/components/pages/reset-password-page.js.map +1 -0
- package/dist/components/pages/sign-in-page.d.ts +19 -0
- package/dist/components/pages/sign-in-page.js +343 -0
- package/dist/components/pages/sign-in-page.js.map +1 -0
- package/dist/components/pages/sign-up-page.d.ts +18 -0
- package/dist/components/pages/sign-up-page.js +360 -0
- package/dist/components/pages/sign-up-page.js.map +1 -0
- package/dist/components/pages/verify-email-page.d.ts +19 -0
- package/dist/components/pages/verify-email-page.js +356 -0
- package/dist/components/pages/verify-email-page.js.map +1 -0
- package/dist/components/pages/verify-phone-page.d.ts +20 -0
- package/dist/components/pages/verify-phone-page.js +368 -0
- package/dist/components/pages/verify-phone-page.js.map +1 -0
- package/dist/components/reset-password-form.d.ts +16 -0
- package/dist/components/reset-password-form.js +142 -0
- package/dist/components/reset-password-form.js.map +1 -0
- package/dist/components/sign-in.d.ts +16 -0
- package/dist/components/sign-in.js +128 -0
- package/dist/components/sign-in.js.map +1 -0
- package/dist/components/sign-up.d.ts +17 -0
- package/dist/components/sign-up.js +179 -0
- package/dist/components/sign-up.js.map +1 -0
- package/dist/components/verification-form.d.ts +15 -0
- package/dist/components/verification-form.js +155 -0
- package/dist/components/verification-form.js.map +1 -0
- package/dist/index.d.ts +222 -0
- package/dist/index.js +1640 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/pages/verify-phone-page.tsx
|
|
4
|
+
import { useTranslations as useTranslations3 } from "next-intl";
|
|
5
|
+
import { useState as useState3 } from "react";
|
|
6
|
+
|
|
7
|
+
// src/context/auth-provider.tsx
|
|
8
|
+
import {
|
|
9
|
+
createContext,
|
|
10
|
+
useCallback,
|
|
11
|
+
useContext,
|
|
12
|
+
useEffect,
|
|
13
|
+
useState
|
|
14
|
+
} from "react";
|
|
15
|
+
import { jsx } from "react/jsx-runtime";
|
|
16
|
+
var AuthContext = createContext(null);
|
|
17
|
+
var useAuth = () => {
|
|
18
|
+
const context = useContext(AuthContext);
|
|
19
|
+
if (!context) {
|
|
20
|
+
throw new Error("useAuth must be used within AuthProvider");
|
|
21
|
+
}
|
|
22
|
+
return context;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/client.ts
|
|
26
|
+
var AuthError = class extends Error {
|
|
27
|
+
code;
|
|
28
|
+
status;
|
|
29
|
+
details;
|
|
30
|
+
constructor(message, code, status, details) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "AuthError";
|
|
33
|
+
this.code = code;
|
|
34
|
+
this.status = status;
|
|
35
|
+
this.details = details;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/constants/auth.error.codes.ts
|
|
40
|
+
var validCodes = [
|
|
41
|
+
"USER_NOT_FOUND",
|
|
42
|
+
"INVALID_PASSWORD",
|
|
43
|
+
"USER_EXISTS",
|
|
44
|
+
"VERIFICATION_EXPIRED",
|
|
45
|
+
"VERIFICATION_MISMATCH",
|
|
46
|
+
"VERIFICATION_NOT_FOUND",
|
|
47
|
+
"TOO_MANY_ATTEMPTS",
|
|
48
|
+
"REQUIRES_VERIFICATION",
|
|
49
|
+
"UNAUTHORIZED",
|
|
50
|
+
"ACCESS_DENIED",
|
|
51
|
+
"HAS_NO_PASSWORD"
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
// src/utils/handle-error.ts
|
|
55
|
+
var handleError = (err, setError, t) => {
|
|
56
|
+
if (err instanceof AuthError) {
|
|
57
|
+
let errorKey = "errors.fallback";
|
|
58
|
+
if (err.code) {
|
|
59
|
+
errorKey = `errors.${err.code.toLowerCase()}`;
|
|
60
|
+
} else if (err.message) {
|
|
61
|
+
const messageUpper = err.message.toUpperCase().trim();
|
|
62
|
+
if (validCodes.includes(messageUpper)) {
|
|
63
|
+
errorKey = `errors.${messageUpper.toLowerCase()}`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
setError(t(errorKey, { defaultValue: err.message }));
|
|
67
|
+
} else {
|
|
68
|
+
setError(err instanceof Error ? err.message : t("errors.fallback"));
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/components/auth-page-layout.tsx
|
|
73
|
+
import { Alert, AlertDescription } from "@mesob/ui/components/alert";
|
|
74
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
75
|
+
var AuthPageLayout = ({
|
|
76
|
+
title,
|
|
77
|
+
description,
|
|
78
|
+
children,
|
|
79
|
+
error,
|
|
80
|
+
footer,
|
|
81
|
+
logoImage
|
|
82
|
+
}) => {
|
|
83
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
84
|
+
/* @__PURE__ */ jsx2("div", { className: "flex size-8 mb-6 w-full items-center justify-center rounded-md", children: /* @__PURE__ */ jsx2("img", { src: logoImage || "", alt: "Jiret", width: 42, height: 42 }) }),
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
86
|
+
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
|
|
87
|
+
description && /* @__PURE__ */ jsx2("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
|
|
88
|
+
] }),
|
|
89
|
+
children,
|
|
90
|
+
error && /* @__PURE__ */ jsx2(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx2(AlertDescription, { children: error }) }),
|
|
91
|
+
/* @__PURE__ */ jsx2("div", { className: "mt-2 w-full", children: footer && /* @__PURE__ */ jsx2("div", { className: "w-full text-center text-sm text-muted-foreground", children: footer }) })
|
|
92
|
+
] });
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// src/components/verification-form.tsx
|
|
96
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
97
|
+
import { Button as Button2 } from "@mesob/ui/components/button";
|
|
98
|
+
import {
|
|
99
|
+
Form,
|
|
100
|
+
FormControl,
|
|
101
|
+
FormField,
|
|
102
|
+
FormItem,
|
|
103
|
+
FormMessage
|
|
104
|
+
} from "@mesob/ui/components/form";
|
|
105
|
+
import {
|
|
106
|
+
InputOTP,
|
|
107
|
+
InputOTPGroup,
|
|
108
|
+
InputOTPSlot
|
|
109
|
+
} from "@mesob/ui/components/input-otp";
|
|
110
|
+
import { useTranslations as useTranslations2 } from "next-intl";
|
|
111
|
+
import { useMemo } from "react";
|
|
112
|
+
import { useForm } from "react-hook-form";
|
|
113
|
+
import { z } from "zod";
|
|
114
|
+
|
|
115
|
+
// src/components/countdown.tsx
|
|
116
|
+
import { Button } from "@mesob/ui/components/button";
|
|
117
|
+
import { useTranslations } from "next-intl";
|
|
118
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
119
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
120
|
+
var Countdown = ({
|
|
121
|
+
initialSeconds = 60,
|
|
122
|
+
onResend,
|
|
123
|
+
resending = false
|
|
124
|
+
}) => {
|
|
125
|
+
const t = useTranslations("Common");
|
|
126
|
+
const [seconds, setSeconds] = useState2(initialSeconds);
|
|
127
|
+
const [isResending, setIsResending] = useState2(false);
|
|
128
|
+
useEffect2(() => {
|
|
129
|
+
if (seconds <= 0) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const timer = setInterval(() => {
|
|
133
|
+
setSeconds((prev) => {
|
|
134
|
+
if (prev <= 1) {
|
|
135
|
+
clearInterval(timer);
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
return prev - 1;
|
|
139
|
+
});
|
|
140
|
+
}, 1e3);
|
|
141
|
+
return () => clearInterval(timer);
|
|
142
|
+
}, [seconds]);
|
|
143
|
+
const handleResend = async () => {
|
|
144
|
+
setIsResending(true);
|
|
145
|
+
try {
|
|
146
|
+
await onResend();
|
|
147
|
+
setSeconds(initialSeconds);
|
|
148
|
+
} catch (_error) {
|
|
149
|
+
} finally {
|
|
150
|
+
setIsResending(false);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
if (seconds > 0) {
|
|
154
|
+
return /* @__PURE__ */ jsx3(Button, { variant: "ghost", disabled: true, children: t("resendIn", { seconds }) });
|
|
155
|
+
}
|
|
156
|
+
return /* @__PURE__ */ jsx3(
|
|
157
|
+
Button,
|
|
158
|
+
{
|
|
159
|
+
variant: "ghost",
|
|
160
|
+
onClick: handleResend,
|
|
161
|
+
disabled: isResending || resending,
|
|
162
|
+
children: isResending || resending ? t("resending") : t("resend")
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/components/verification-form.tsx
|
|
168
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
169
|
+
var VerificationForm = ({
|
|
170
|
+
onSubmit,
|
|
171
|
+
onResend,
|
|
172
|
+
isLoading = false
|
|
173
|
+
}) => {
|
|
174
|
+
const t = useTranslations2("Auth.verification");
|
|
175
|
+
const verificationSchema = useMemo(
|
|
176
|
+
() => z.object({
|
|
177
|
+
code: z.string().length(6, t("form.codeLength"))
|
|
178
|
+
}),
|
|
179
|
+
[t]
|
|
180
|
+
);
|
|
181
|
+
const form = useForm({
|
|
182
|
+
resolver: zodResolver(verificationSchema),
|
|
183
|
+
defaultValues: {
|
|
184
|
+
code: ""
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
const handleComplete = async (value) => {
|
|
188
|
+
const valid = await form.trigger("code");
|
|
189
|
+
if (valid) {
|
|
190
|
+
await onSubmit({ code: value });
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
return /* @__PURE__ */ jsx4(Form, { ...form, children: /* @__PURE__ */ jsxs2("form", { className: "space-y-4", children: [
|
|
194
|
+
/* @__PURE__ */ jsx4(
|
|
195
|
+
FormField,
|
|
196
|
+
{
|
|
197
|
+
control: form.control,
|
|
198
|
+
name: "code",
|
|
199
|
+
render: ({ field }) => /* @__PURE__ */ jsxs2(FormItem, { children: [
|
|
200
|
+
/* @__PURE__ */ jsx4(FormControl, { children: /* @__PURE__ */ jsx4("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx4(
|
|
201
|
+
InputOTP,
|
|
202
|
+
{
|
|
203
|
+
maxLength: 6,
|
|
204
|
+
value: field.value,
|
|
205
|
+
onChange: (value) => {
|
|
206
|
+
field.onChange(value);
|
|
207
|
+
if (value.length === 6) {
|
|
208
|
+
handleComplete(value);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
disabled: isLoading,
|
|
212
|
+
children: /* @__PURE__ */ jsxs2(InputOTPGroup, { children: [
|
|
213
|
+
/* @__PURE__ */ jsx4(InputOTPSlot, { index: 0 }),
|
|
214
|
+
/* @__PURE__ */ jsx4(InputOTPSlot, { index: 1 }),
|
|
215
|
+
/* @__PURE__ */ jsx4(InputOTPSlot, { index: 2 }),
|
|
216
|
+
/* @__PURE__ */ jsx4(InputOTPSlot, { index: 3 }),
|
|
217
|
+
/* @__PURE__ */ jsx4(InputOTPSlot, { index: 4 }),
|
|
218
|
+
/* @__PURE__ */ jsx4(InputOTPSlot, { index: 5 })
|
|
219
|
+
] })
|
|
220
|
+
}
|
|
221
|
+
) }) }),
|
|
222
|
+
/* @__PURE__ */ jsx4(FormMessage, {})
|
|
223
|
+
] })
|
|
224
|
+
}
|
|
225
|
+
),
|
|
226
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between items-center", children: [
|
|
227
|
+
/* @__PURE__ */ jsx4(Countdown, { onResend, resending: isLoading }),
|
|
228
|
+
/* @__PURE__ */ jsx4(
|
|
229
|
+
Button2,
|
|
230
|
+
{
|
|
231
|
+
type: "button",
|
|
232
|
+
onClick: () => {
|
|
233
|
+
form.handleSubmit(async (values) => {
|
|
234
|
+
await onSubmit(values);
|
|
235
|
+
})();
|
|
236
|
+
},
|
|
237
|
+
disabled: isLoading || form.watch("code").length !== 6,
|
|
238
|
+
children: t("form.confirm")
|
|
239
|
+
}
|
|
240
|
+
)
|
|
241
|
+
] })
|
|
242
|
+
] }) });
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/components/pages/verify-phone-page.tsx
|
|
246
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
247
|
+
var VerifyPhonePage = ({
|
|
248
|
+
verificationId,
|
|
249
|
+
context,
|
|
250
|
+
phone = "",
|
|
251
|
+
onNavigate,
|
|
252
|
+
linkComponent: Link,
|
|
253
|
+
links,
|
|
254
|
+
logoImage
|
|
255
|
+
}) => {
|
|
256
|
+
const t = useTranslations3("Auth.verification");
|
|
257
|
+
const common = useTranslations3("Common");
|
|
258
|
+
const footer = useTranslations3("Auth.forgotPassword.footer");
|
|
259
|
+
const { client, refresh, setAuth } = useAuth();
|
|
260
|
+
const [isLoading, setIsLoading] = useState3(false);
|
|
261
|
+
const [error, setError] = useState3(null);
|
|
262
|
+
const signInLink = links?.signIn || "/auth/sign-in";
|
|
263
|
+
const handleSubmit = async (values) => {
|
|
264
|
+
if (!verificationId) {
|
|
265
|
+
setError(t("errors.fallback"));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
setIsLoading(true);
|
|
269
|
+
setError(null);
|
|
270
|
+
try {
|
|
271
|
+
const res = await client.verifyPhoneOtp({
|
|
272
|
+
verificationId,
|
|
273
|
+
code: values.code,
|
|
274
|
+
context
|
|
275
|
+
});
|
|
276
|
+
if (res && "user" in res && "session" in res && res.session) {
|
|
277
|
+
setAuth(res);
|
|
278
|
+
onNavigate("/dashboard");
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
await refresh();
|
|
282
|
+
onNavigate("/dashboard");
|
|
283
|
+
} catch (err) {
|
|
284
|
+
handleError(err, setError, t);
|
|
285
|
+
} finally {
|
|
286
|
+
setIsLoading(false);
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
const handleResend = async () => {
|
|
290
|
+
setError(null);
|
|
291
|
+
try {
|
|
292
|
+
const targetPhone = context === "sign-up" ? phone : null;
|
|
293
|
+
if (!targetPhone) {
|
|
294
|
+
setError(t("phone.missingPhone"));
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const res = await client.requestPhoneOtp({ phone: targetPhone, context });
|
|
298
|
+
if (res && "verificationId" in res && res.verificationId) {
|
|
299
|
+
onNavigate(
|
|
300
|
+
`/auth/verify-phone?context=${context}&verificationId=${res.verificationId}&phone=${targetPhone}`
|
|
301
|
+
);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
setError(t("phone.resendFailed"));
|
|
305
|
+
} catch (err) {
|
|
306
|
+
handleError(err, setError, t);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
if (!verificationId) {
|
|
310
|
+
return /* @__PURE__ */ jsx5(
|
|
311
|
+
AuthPageLayout,
|
|
312
|
+
{
|
|
313
|
+
title: common("invalidLinkTitle"),
|
|
314
|
+
description: common("invalidLinkDescription"),
|
|
315
|
+
footer: Link ? /* @__PURE__ */ jsx5(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx5(
|
|
316
|
+
"a",
|
|
317
|
+
{
|
|
318
|
+
href: signInLink,
|
|
319
|
+
onClick: (e) => {
|
|
320
|
+
e.preventDefault();
|
|
321
|
+
onNavigate(signInLink);
|
|
322
|
+
},
|
|
323
|
+
className: "text-primary hover:underline",
|
|
324
|
+
children: footer("backToSignIn")
|
|
325
|
+
}
|
|
326
|
+
),
|
|
327
|
+
children: /* @__PURE__ */ jsx5("div", {})
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
return /* @__PURE__ */ jsx5(
|
|
332
|
+
AuthPageLayout,
|
|
333
|
+
{
|
|
334
|
+
title: t("phone.title"),
|
|
335
|
+
description: t("phone.description", {
|
|
336
|
+
target: phone || t("phone.missingPhone")
|
|
337
|
+
}),
|
|
338
|
+
error,
|
|
339
|
+
logoImage,
|
|
340
|
+
footer: Link ? /* @__PURE__ */ jsx5(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx5(
|
|
341
|
+
"a",
|
|
342
|
+
{
|
|
343
|
+
href: signInLink,
|
|
344
|
+
onClick: (e) => {
|
|
345
|
+
e.preventDefault();
|
|
346
|
+
onNavigate(signInLink);
|
|
347
|
+
},
|
|
348
|
+
className: "text-primary hover:underline",
|
|
349
|
+
children: footer("backToSignIn")
|
|
350
|
+
}
|
|
351
|
+
),
|
|
352
|
+
children: /* @__PURE__ */ jsx5(
|
|
353
|
+
VerificationForm,
|
|
354
|
+
{
|
|
355
|
+
verificationId,
|
|
356
|
+
onSubmit: handleSubmit,
|
|
357
|
+
onResend: handleResend,
|
|
358
|
+
isLoading,
|
|
359
|
+
error
|
|
360
|
+
}
|
|
361
|
+
)
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
};
|
|
365
|
+
export {
|
|
366
|
+
VerifyPhonePage
|
|
367
|
+
};
|
|
368
|
+
//# sourceMappingURL=verify-phone-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/pages/verify-phone-page.tsx","../../../src/context/auth-provider.tsx","../../../src/client.ts","../../../src/constants/auth.error.codes.ts","../../../src/utils/handle-error.ts","../../../src/components/auth-page-layout.tsx","../../../src/components/verification-form.tsx","../../../src/components/countdown.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport type { ComponentProps } from 'react';\nimport { useState } from 'react';\nimport { useAuth } from '../../context/auth-provider';\nimport type { AuthResponse } from '../../types';\nimport { handleError } from '../../utils/handle-error';\nimport { AuthPageLayout } from '../auth-page-layout';\nimport { VerificationForm } from '../verification-form';\n\ntype VerifyPhonePageProps = {\n locale?: string;\n verificationId: string;\n context: 'sign-in' | 'sign-up';\n phone?: string;\n onNavigate: (path: string) => void;\n linkComponent?: React.ComponentType<ComponentProps<'a'> & { href: string }>;\n links?: {\n signIn?: string;\n };\n logoImage?: string;\n};\nexport const VerifyPhonePage = ({\n verificationId,\n context,\n phone = '',\n onNavigate,\n linkComponent: Link,\n links,\n logoImage,\n}: VerifyPhonePageProps) => {\n const t = useTranslations('Auth.verification');\n const common = useTranslations('Common');\n const footer = useTranslations('Auth.forgotPassword.footer');\n const { client, refresh, setAuth } = useAuth();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const signInLink = links?.signIn || '/auth/sign-in';\n\n const handleSubmit = async (values: { code: string }) => {\n if (!verificationId) {\n setError(t('errors.fallback'));\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const res = await client.verifyPhoneOtp({\n verificationId,\n code: values.code,\n context,\n });\n if (res && 'user' in res && 'session' in res && res.session) {\n setAuth(res as AuthResponse);\n onNavigate('/dashboard');\n return;\n }\n await refresh();\n onNavigate('/dashboard');\n } catch (err) {\n handleError(err, setError, t);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleResend = async () => {\n setError(null);\n try {\n const targetPhone = context === 'sign-up' ? phone : null;\n if (!targetPhone) {\n setError(t('phone.missingPhone'));\n return;\n }\n const res = await client.requestPhoneOtp({ phone: targetPhone, context });\n if (res && 'verificationId' in res && res.verificationId) {\n onNavigate(\n `/auth/verify-phone?context=${context}&verificationId=${res.verificationId}&phone=${targetPhone}`,\n );\n return;\n }\n setError(t('phone.resendFailed'));\n } catch (err) {\n handleError(err, setError, t);\n }\n };\n\n if (!verificationId) {\n return (\n <AuthPageLayout\n title={common('invalidLinkTitle')}\n description={common('invalidLinkDescription')}\n footer={\n Link ? (\n <Link href={signInLink} className=\"text-primary hover:underline\">\n {footer('backToSignIn')}\n </Link>\n ) : (\n <a\n href={signInLink}\n onClick={(e) => {\n e.preventDefault();\n onNavigate(signInLink);\n }}\n className=\"text-primary hover:underline\"\n >\n {footer('backToSignIn')}\n </a>\n )\n }\n >\n <div />\n </AuthPageLayout>\n );\n }\n\n return (\n <AuthPageLayout\n title={t('phone.title')}\n description={t('phone.description', {\n target: phone || t('phone.missingPhone'),\n })}\n error={error}\n logoImage={logoImage}\n footer={\n Link ? (\n <Link href={signInLink} className=\"text-primary hover:underline\">\n {footer('backToSignIn')}\n </Link>\n ) : (\n <a\n href={signInLink}\n onClick={(e) => {\n e.preventDefault();\n onNavigate(signInLink);\n }}\n className=\"text-primary hover:underline\"\n >\n {footer('backToSignIn')}\n </a>\n )\n }\n >\n <VerificationForm\n verificationId={verificationId}\n onSubmit={handleSubmit}\n onResend={handleResend}\n isLoading={isLoading}\n error={error}\n />\n </AuthPageLayout>\n );\n};\n","'use client';\n\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport type { AuthClient } from '../client';\nimport type { AuthResponse, Session, User } from '../types';\n\ntype AuthContextValue = {\n user: User | null;\n session: Session | null;\n loading: boolean;\n error: Error | null;\n client: AuthClient;\n refresh: () => Promise<void>;\n setAuth: (data: AuthResponse) => void;\n};\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport const useAuth = () => {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error('useAuth must be used within AuthProvider');\n }\n return context;\n};\n\ntype AuthProviderProps = {\n client: AuthClient;\n children: ReactNode;\n};\n\nexport const AuthProvider = ({ client, children }: AuthProviderProps) => {\n const [user, setUser] = useState<User | null>(null);\n const [session, setSession] = useState<Session | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const refresh = useCallback(async () => {\n try {\n setLoading(true);\n setError(null);\n const data = await client.getSession();\n setUser(data.user);\n setSession(data.session);\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error('Failed to fetch session'),\n );\n setUser(null);\n setSession(null);\n } finally {\n setLoading(false);\n }\n }, [client]);\n\n const setAuth = useCallback((data: AuthResponse) => {\n setUser(data.user);\n setSession(data.session);\n setError(null);\n setLoading(false);\n }, []);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n return (\n <AuthContext.Provider\n value={{\n user,\n session,\n loading,\n error,\n client,\n refresh,\n setAuth,\n }}\n >\n {children}\n </AuthContext.Provider>\n );\n};\n","import type {\n AuthErrorCode,\n AuthErrorResponse,\n AuthResponse,\n SessionResponse,\n User,\n VerificationResponse,\n} from './types';\n\n// Backend returns error code in 'error' field (AUTH_ERRORS values)\n// or in 'code' field, message in 'message' or 'error' field\nconst validErrorCodes: readonly AuthErrorCode[] = [\n 'USER_NOT_FOUND',\n 'INVALID_PASSWORD',\n 'USER_EXISTS',\n 'VERIFICATION_EXPIRED',\n 'VERIFICATION_MISMATCH',\n 'VERIFICATION_NOT_FOUND',\n 'TOO_MANY_ATTEMPTS',\n 'REQUIRES_VERIFICATION',\n 'UNAUTHORIZED',\n 'ACCESS_DENIED',\n 'HAS_NO_PASSWORD',\n] as const;\n\nexport class AuthError extends Error {\n code?: AuthErrorCode;\n status?: number;\n details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code?: AuthErrorCode,\n status?: number,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'AuthError';\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport type AuthClientConfig = {\n baseURL: string;\n};\n\nexport class AuthClient {\n private baseURL: string;\n\n constructor(config: AuthClientConfig) {\n this.baseURL = config.baseURL.replace(/\\/$/, '');\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.baseURL}${endpoint}`;\n const response = await fetch(url, {\n ...options,\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n });\n if (!response.ok) {\n const text = await response.text();\n let errorData: AuthErrorResponse;\n try {\n errorData = JSON.parse(text);\n } catch {\n errorData = { error: 'Unknown error', message: text };\n }\n\n // Extract error code from code, error, or message field\n // Backend returns error codes in 'error' field (e.g., { error: 'INVALID_PASSWORD' })\n const potentialCode =\n errorData.code ||\n (typeof errorData.error === 'string' ? errorData.error : null) ||\n (typeof errorData.message === 'string' ? errorData.message : null);\n const upperCode = potentialCode?.toUpperCase().trim();\n const errorCode =\n upperCode && validErrorCodes.includes(upperCode as AuthErrorCode)\n ? (upperCode as AuthErrorCode)\n : undefined;\n const errorMessage =\n errorData.message || errorData.error || 'Request failed';\n\n throw new AuthError(\n errorMessage,\n errorCode as AuthErrorCode | undefined,\n response.status,\n errorData.details,\n );\n }\n\n const data = await response.json();\n return data;\n }\n\n signUpWithEmail(data: {\n email: string;\n password: string;\n fullName: string;\n handle?: string;\n }): Promise<AuthResponse | VerificationResponse> {\n return this.request<AuthResponse | VerificationResponse>('/sign-up', {\n method: 'POST',\n body: JSON.stringify({\n email: data.email,\n password: data.password,\n fullName: data.fullName,\n handle: data.handle,\n }),\n });\n }\n\n signUpWithPhone(data: {\n phone: string;\n password: string;\n fullName: string;\n handle?: string;\n }): Promise<AuthResponse | VerificationResponse> {\n return this.request<AuthResponse | VerificationResponse>('/sign-up', {\n method: 'POST',\n body: JSON.stringify({\n phone: data.phone,\n password: data.password,\n fullName: data.fullName,\n handle: data.handle,\n }),\n });\n }\n\n checkUser(data: { identifier: string }): Promise<{ exists: boolean }> {\n return this.request<{ exists: boolean }>('/check-user', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n signInWithPassword(data: {\n identifier: string;\n password: string;\n }): Promise<AuthResponse | VerificationResponse> {\n return this.request<AuthResponse | VerificationResponse>('/sign-in', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n signOut(): Promise<{ message: string }> {\n return this.request<{ message: string }>('/sign-out', {\n method: 'POST',\n });\n }\n\n requestEmailVerification(data?: {\n email?: string;\n }): Promise<{ verificationId: string }> {\n return this.request<{ verificationId: string }>(\n '/email/verification/request',\n {\n method: 'POST',\n body: JSON.stringify(data || {}),\n },\n );\n }\n\n verifyEmail(data: {\n verificationId: string;\n code: string;\n }): Promise<AuthResponse> {\n return this.request<AuthResponse>('/email/verification/confirm', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n resendVerification(_verificationId: string): Promise<{\n verificationId: string;\n }> {\n // For email, request new verification\n return this.requestEmailVerification();\n }\n\n requestPhoneOtp(data: {\n phone: string;\n context: 'sign-up' | 'sign-in' | 'change-phone';\n }): Promise<{ verificationId: string }> {\n return this.request<{ verificationId: string }>(\n '/phone/verification/request',\n {\n method: 'POST',\n body: JSON.stringify(data),\n },\n );\n }\n\n verifyPhoneOtp(data: {\n verificationId: string;\n code: string;\n context: 'sign-up' | 'sign-in' | 'change-phone';\n }): Promise<\n AuthResponse | { user: User | null; session: null; verified: boolean }\n > {\n return this.request('/phone/verification/confirm', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n forgotPassword(data: { identifier: string }): Promise<{\n message: string;\n }> {\n return this.request<{ message: string }>('/password/forgot', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n resetPassword(data: {\n verificationId: string;\n code: string;\n password: string;\n }): Promise<AuthResponse> {\n return this.request<AuthResponse>('/password/reset', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n changePassword(data: {\n currentPassword: string;\n newPassword: string;\n }): Promise<{ message: string }> {\n return this.request<{ message: string }>('/password/change', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n getSession(): Promise<SessionResponse> {\n return this.request<SessionResponse>('/session', {\n method: 'GET',\n });\n }\n}\n","export const validCodes = [\n 'USER_NOT_FOUND',\n 'INVALID_PASSWORD',\n 'USER_EXISTS',\n 'VERIFICATION_EXPIRED',\n 'VERIFICATION_MISMATCH',\n 'VERIFICATION_NOT_FOUND',\n 'TOO_MANY_ATTEMPTS',\n 'REQUIRES_VERIFICATION',\n 'UNAUTHORIZED',\n 'ACCESS_DENIED',\n 'HAS_NO_PASSWORD',\n];\n","import type { _Translator } from 'next-intl';\nimport { AuthError } from '../client';\nimport { validCodes } from '../constants/auth.error.codes';\n\nexport const handleError = (\n err: any,\n setError: (error: string | null) => void,\n t: _Translator<Record<string, any>, string>,\n) => {\n if (err instanceof AuthError) {\n let errorKey = 'errors.fallback';\n if (err.code) {\n errorKey = `errors.${err.code.toLowerCase()}`;\n } else if (err.message) {\n // Fallback: try to extract error code from message\n const messageUpper = err.message.toUpperCase().trim();\n\n if (validCodes.includes(messageUpper)) {\n errorKey = `errors.${messageUpper.toLowerCase()}`;\n }\n }\n setError(t(errorKey, { defaultValue: err.message }));\n } else {\n setError(err instanceof Error ? err.message : t('errors.fallback'));\n }\n};\n","'use client';\n\nimport { Alert, AlertDescription } from '@mesob/ui/components/alert';\nimport type { ReactNode } from 'react';\n\ntype AuthPageLayoutProps = {\n title: string;\n description?: string;\n children: ReactNode;\n error?: string | null;\n footer?: ReactNode;\n logoImage?: string;\n};\n\nexport const AuthPageLayout = ({\n title,\n description,\n children,\n error,\n footer,\n logoImage,\n}: AuthPageLayoutProps) => {\n return (\n <div className=\"space-y-4\">\n <div className=\"flex size-8 mb-6 w-full items-center justify-center rounded-md\">\n {/** biome-ignore lint/performance/noImgElement: logo image */}\n <img src={logoImage || ''} alt=\"Jiret\" width={42} height={42} />\n </div>\n <div className=\"text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{title}</h1>\n {description && (\n <p className=\"mt-2 text-sm text-muted-foreground\">{description}</p>\n )}\n </div>\n\n {children}\n\n {error && (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n )}\n <div className=\"mt-2 w-full\">\n {footer && (\n <div className=\"w-full text-center text-sm text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>\n </div>\n );\n};\n","'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Button } from '@mesob/ui/components/button';\nimport {\n Form,\n FormControl,\n FormField,\n FormItem,\n FormMessage,\n} from '@mesob/ui/components/form';\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n} from '@mesob/ui/components/input-otp';\nimport { useTranslations } from 'next-intl';\nimport { useMemo } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { z } from 'zod';\nimport { Countdown } from './countdown';\n\ntype VerificationFormValues = {\n code: string;\n};\n\ntype VerificationFormProps = {\n verificationId: string;\n onSubmit: (values: VerificationFormValues) => Promise<void> | void;\n onResend: () => Promise<void> | void;\n isLoading?: boolean;\n error?: string | null;\n};\n\nexport const VerificationForm = ({\n onSubmit,\n onResend,\n isLoading = false,\n}: VerificationFormProps) => {\n const t = useTranslations('Auth.verification');\n const verificationSchema = useMemo(\n () =>\n z.object({\n code: z.string().length(6, t('form.codeLength')),\n }),\n [t],\n );\n const form = useForm<VerificationFormValues>({\n resolver: zodResolver(verificationSchema),\n defaultValues: {\n code: '',\n },\n });\n const handleComplete = async (value: string) => {\n const valid = await form.trigger('code');\n if (valid) {\n await onSubmit({ code: value });\n }\n };\n\n return (\n <Form {...form}>\n <form className=\"space-y-4\">\n <FormField\n control={form.control}\n name=\"code\"\n render={({ field }) => (\n <FormItem>\n <FormControl>\n <div className=\"flex justify-center\">\n <InputOTP\n maxLength={6}\n value={field.value}\n onChange={(value) => {\n field.onChange(value);\n if (value.length === 6) {\n handleComplete(value);\n }\n }}\n disabled={isLoading}\n >\n <InputOTPGroup>\n <InputOTPSlot index={0} />\n <InputOTPSlot index={1} />\n <InputOTPSlot index={2} />\n <InputOTPSlot index={3} />\n <InputOTPSlot index={4} />\n <InputOTPSlot index={5} />\n </InputOTPGroup>\n </InputOTP>\n </div>\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <div className=\"flex justify-between items-center\">\n <Countdown onResend={onResend} resending={isLoading} />\n <Button\n type=\"button\"\n onClick={() => {\n form.handleSubmit(async (values) => {\n await onSubmit(values);\n })();\n }}\n disabled={isLoading || form.watch('code').length !== 6}\n >\n {t('form.confirm')}\n </Button>\n </div>\n </form>\n </Form>\n );\n};\n","'use client';\n\nimport { Button } from '@mesob/ui/components/button';\nimport { useTranslations } from 'next-intl';\nimport { useEffect, useState } from 'react';\n\ntype CountdownProps = {\n initialSeconds?: number;\n onResend: () => Promise<void> | void;\n resending?: boolean;\n};\n\nexport const Countdown = ({\n initialSeconds = 60,\n onResend,\n resending = false,\n}: CountdownProps) => {\n const t = useTranslations('Common');\n const [seconds, setSeconds] = useState(initialSeconds);\n const [isResending, setIsResending] = useState(false);\n\n useEffect(() => {\n if (seconds <= 0) {\n return;\n }\n\n const timer = setInterval(() => {\n setSeconds((prev) => {\n if (prev <= 1) {\n clearInterval(timer);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(timer);\n }, [seconds]);\n\n const handleResend = async () => {\n setIsResending(true);\n try {\n await onResend();\n setSeconds(initialSeconds);\n } catch (_error) {\n // Error handling is done by parent\n } finally {\n setIsResending(false);\n }\n };\n\n if (seconds > 0) {\n return (\n <Button variant=\"ghost\" disabled>\n {t('resendIn', { seconds })}\n </Button>\n );\n }\n\n return (\n <Button\n variant=\"ghost\"\n onClick={handleResend}\n disabled={isResending || resending}\n >\n {isResending || resending ? t('resending') : t('resend')}\n </Button>\n );\n};\n"],"mappings":"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","names":["useTranslations","useState","jsx","Button","useTranslations","useEffect","useState","jsx","jsx","jsxs","useTranslations","Button","jsx","useTranslations","useState"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type ResetPasswordFormValues = {
|
|
4
|
+
code: string;
|
|
5
|
+
password: string;
|
|
6
|
+
confirmPassword: string;
|
|
7
|
+
};
|
|
8
|
+
type ResetPasswordFormProps = {
|
|
9
|
+
verificationId: string;
|
|
10
|
+
onSubmit: (values: ResetPasswordFormValues) => Promise<void> | void;
|
|
11
|
+
isLoading?: boolean;
|
|
12
|
+
error?: string | null;
|
|
13
|
+
};
|
|
14
|
+
declare const ResetPasswordForm: ({ verificationId, onSubmit, isLoading, error, }: ResetPasswordFormProps) => react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { ResetPasswordForm };
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/reset-password-form.tsx
|
|
4
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
5
|
+
import { Button } from "@mesob/ui/components/button";
|
|
6
|
+
import {
|
|
7
|
+
Form,
|
|
8
|
+
FormControl,
|
|
9
|
+
FormField,
|
|
10
|
+
FormItem,
|
|
11
|
+
FormLabel,
|
|
12
|
+
FormMessage
|
|
13
|
+
} from "@mesob/ui/components/form";
|
|
14
|
+
import { Input } from "@mesob/ui/components/input";
|
|
15
|
+
import {
|
|
16
|
+
InputOTP,
|
|
17
|
+
InputOTPGroup,
|
|
18
|
+
InputOTPSlot
|
|
19
|
+
} from "@mesob/ui/components/input-otp";
|
|
20
|
+
import { Eye, EyeOff } from "lucide-react";
|
|
21
|
+
import { useTranslations } from "next-intl";
|
|
22
|
+
import { useMemo, useState } from "react";
|
|
23
|
+
import { useForm } from "react-hook-form";
|
|
24
|
+
import { z } from "zod";
|
|
25
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
+
var ResetPasswordForm = ({
|
|
27
|
+
verificationId,
|
|
28
|
+
onSubmit,
|
|
29
|
+
isLoading = false,
|
|
30
|
+
error
|
|
31
|
+
}) => {
|
|
32
|
+
const t = useTranslations("Auth.resetPassword");
|
|
33
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
34
|
+
const resetPasswordSchema = useMemo(
|
|
35
|
+
() => z.object({
|
|
36
|
+
code: z.string().length(6, t("errors.codeLength")),
|
|
37
|
+
password: z.string().min(8, t("errors.passwordLength")),
|
|
38
|
+
confirmPassword: z.string()
|
|
39
|
+
}).refine((data) => data.password === data.confirmPassword, {
|
|
40
|
+
message: t("errors.passwordsMismatch"),
|
|
41
|
+
path: ["confirmPassword"]
|
|
42
|
+
}),
|
|
43
|
+
[t]
|
|
44
|
+
);
|
|
45
|
+
const form = useForm({
|
|
46
|
+
resolver: zodResolver(resetPasswordSchema),
|
|
47
|
+
defaultValues: {
|
|
48
|
+
code: "",
|
|
49
|
+
password: "",
|
|
50
|
+
confirmPassword: ""
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const handleSubmit = form.handleSubmit(async (values) => {
|
|
54
|
+
await onSubmit(values);
|
|
55
|
+
});
|
|
56
|
+
return /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
57
|
+
/* @__PURE__ */ jsx(
|
|
58
|
+
FormField,
|
|
59
|
+
{
|
|
60
|
+
control: form.control,
|
|
61
|
+
name: "code",
|
|
62
|
+
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
63
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(FormLabel, { children: t("form.codeLabel") }) }),
|
|
64
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(InputOTP, { maxLength: 6, ...field, children: /* @__PURE__ */ jsxs(InputOTPGroup, { children: [
|
|
65
|
+
/* @__PURE__ */ jsx(InputOTPSlot, { index: 0 }),
|
|
66
|
+
/* @__PURE__ */ jsx(InputOTPSlot, { index: 1 }),
|
|
67
|
+
/* @__PURE__ */ jsx(InputOTPSlot, { index: 2 }),
|
|
68
|
+
/* @__PURE__ */ jsx(InputOTPSlot, { index: 3 }),
|
|
69
|
+
/* @__PURE__ */ jsx(InputOTPSlot, { index: 4 }),
|
|
70
|
+
/* @__PURE__ */ jsx(InputOTPSlot, { index: 5 })
|
|
71
|
+
] }) }) }) }),
|
|
72
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
73
|
+
] })
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
FormField,
|
|
78
|
+
{
|
|
79
|
+
control: form.control,
|
|
80
|
+
name: "password",
|
|
81
|
+
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
82
|
+
/* @__PURE__ */ jsx(FormLabel, { children: t("form.passwordLabel") }),
|
|
83
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
84
|
+
/* @__PURE__ */ jsx(
|
|
85
|
+
Input,
|
|
86
|
+
{
|
|
87
|
+
type: showPassword ? "text" : "password",
|
|
88
|
+
placeholder: t("form.passwordPlaceholder"),
|
|
89
|
+
...field
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
"button",
|
|
94
|
+
{
|
|
95
|
+
type: "button",
|
|
96
|
+
onClick: () => setShowPassword(!showPassword),
|
|
97
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
98
|
+
children: showPassword ? /* @__PURE__ */ jsx(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4" })
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
] }) }),
|
|
102
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
103
|
+
] })
|
|
104
|
+
}
|
|
105
|
+
),
|
|
106
|
+
/* @__PURE__ */ jsx(
|
|
107
|
+
FormField,
|
|
108
|
+
{
|
|
109
|
+
control: form.control,
|
|
110
|
+
name: "confirmPassword",
|
|
111
|
+
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
112
|
+
/* @__PURE__ */ jsx(FormLabel, { children: t("form.confirmPasswordLabel") }),
|
|
113
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
Input,
|
|
116
|
+
{
|
|
117
|
+
type: showPassword ? "text" : "password",
|
|
118
|
+
placeholder: t("form.passwordPlaceholder"),
|
|
119
|
+
...field
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
/* @__PURE__ */ jsx(
|
|
123
|
+
"button",
|
|
124
|
+
{
|
|
125
|
+
type: "button",
|
|
126
|
+
onClick: () => setShowPassword(!showPassword),
|
|
127
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
128
|
+
children: showPassword ? /* @__PURE__ */ jsx(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4" })
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
] }) }),
|
|
132
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
133
|
+
] })
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? t("form.submitting") : t("form.submit") })
|
|
137
|
+
] }) });
|
|
138
|
+
};
|
|
139
|
+
export {
|
|
140
|
+
ResetPasswordForm
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=reset-password-form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/reset-password-form.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Button } from '@mesob/ui/components/button';\nimport {\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@mesob/ui/components/form';\nimport { Input } from '@mesob/ui/components/input';\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n} from '@mesob/ui/components/input-otp';\nimport { Eye, EyeOff } from 'lucide-react';\nimport { useTranslations } from 'next-intl';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { z } from 'zod';\n\ntype ResetPasswordFormValues = {\n code: string;\n password: string;\n confirmPassword: string;\n};\n\ntype ResetPasswordFormProps = {\n verificationId: string;\n onSubmit: (values: ResetPasswordFormValues) => Promise<void> | void;\n isLoading?: boolean;\n error?: string | null;\n};\n\nexport const ResetPasswordForm = ({\n verificationId,\n onSubmit,\n isLoading = false,\n error,\n}: ResetPasswordFormProps) => {\n const t = useTranslations('Auth.resetPassword');\n const [showPassword, setShowPassword] = useState(false);\n const resetPasswordSchema = useMemo(\n () =>\n z\n .object({\n code: z.string().length(6, t('errors.codeLength')),\n password: z.string().min(8, t('errors.passwordLength')),\n confirmPassword: z.string(),\n })\n .refine((data) => data.password === data.confirmPassword, {\n message: t('errors.passwordsMismatch'),\n path: ['confirmPassword'],\n }),\n [t],\n );\n\n const form = useForm<ResetPasswordFormValues>({\n resolver: zodResolver(resetPasswordSchema),\n defaultValues: {\n code: '',\n password: '',\n confirmPassword: '',\n },\n });\n\n const handleSubmit = form.handleSubmit(async (values) => {\n await onSubmit(values);\n });\n\n return (\n <Form {...form}>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <FormField\n control={form.control}\n name=\"code\"\n render={({ field }) => (\n <FormItem>\n <div className=\"flex justify-center\">\n <FormLabel>{t('form.codeLabel')}</FormLabel>\n </div>\n <FormControl>\n <div className=\"flex justify-center\">\n <InputOTP maxLength={6} {...field}>\n <InputOTPGroup>\n <InputOTPSlot index={0} />\n <InputOTPSlot index={1} />\n <InputOTPSlot index={2} />\n <InputOTPSlot index={3} />\n <InputOTPSlot index={4} />\n <InputOTPSlot index={5} />\n </InputOTPGroup>\n </InputOTP>\n </div>\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"password\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.passwordLabel')}</FormLabel>\n <FormControl>\n <div className=\"relative\">\n <Input\n type={showPassword ? 'text' : 'password'}\n placeholder={t('form.passwordPlaceholder')}\n {...field}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n >\n {showPassword ? (\n <EyeOff className=\"h-4 w-4\" />\n ) : (\n <Eye className=\"h-4 w-4\" />\n )}\n </button>\n </div>\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"confirmPassword\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.confirmPasswordLabel')}</FormLabel>\n <FormControl>\n <div className=\"relative\">\n <Input\n type={showPassword ? 'text' : 'password'}\n placeholder={t('form.passwordPlaceholder')}\n {...field}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n >\n {showPassword ? (\n <EyeOff className=\"h-4 w-4\" />\n ) : (\n <Eye className=\"h-4 w-4\" />\n )}\n </button>\n </div>\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <Button type=\"submit\" className=\"w-full\" disabled={isLoading}>\n {isLoading ? t('form.submitting') : t('form.submit')}\n </Button>\n </form>\n </Form>\n );\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type SignInFormValues = {
|
|
4
|
+
account: string;
|
|
5
|
+
password: string;
|
|
6
|
+
};
|
|
7
|
+
type SignInProps = {
|
|
8
|
+
onSubmit: (values: SignInFormValues, step: 'identifier' | 'password') => Promise<void> | void;
|
|
9
|
+
isLoading?: boolean;
|
|
10
|
+
identifier?: string;
|
|
11
|
+
step?: 'identifier' | 'password';
|
|
12
|
+
onBack?: () => void;
|
|
13
|
+
};
|
|
14
|
+
declare const SignIn: ({ onSubmit, isLoading, identifier, step, onBack: _onBack, }: SignInProps) => react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { SignIn };
|