@greatapps/common 1.1.24 → 1.1.25
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/account/ConfigurationsMyAccountModal.mjs +121 -0
- package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -0
- package/dist/components/account/ConfirmGlobalPreferencesModal.mjs +45 -0
- package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -0
- package/dist/components/account/DisableTwoFactorAuthModal.mjs +67 -0
- package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -0
- package/dist/components/account/TwoFactorAuthModal.mjs +190 -0
- package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -0
- package/dist/components/account/constants.mjs +32 -0
- package/dist/components/account/constants.mjs.map +1 -0
- package/dist/components/account/hooks/useChangeEmailForm.mjs +53 -0
- package/dist/components/account/hooks/useChangeEmailForm.mjs.map +1 -0
- package/dist/components/account/hooks/useChangePasswordForm.mjs +47 -0
- package/dist/components/account/hooks/useChangePasswordForm.mjs.map +1 -0
- package/dist/components/account/hooks/useChangePhoneForm.mjs +64 -0
- package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -0
- package/dist/components/account/hooks/useConfigurationsModal.mjs +33 -0
- package/dist/components/account/hooks/useConfigurationsModal.mjs.map +1 -0
- package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs +54 -0
- package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs.map +1 -0
- package/dist/components/account/hooks/useOtpVerification.mjs +94 -0
- package/dist/components/account/hooks/useOtpVerification.mjs.map +1 -0
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs +88 -0
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -0
- package/dist/components/account/sections/ChangeEmailModal.mjs +180 -0
- package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -0
- package/dist/components/account/sections/ChangePasswordSection.mjs +64 -0
- package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -0
- package/dist/components/account/sections/ChangePhoneModal.mjs +182 -0
- package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -0
- package/dist/components/account/sections/MyProfileSection.mjs +312 -0
- package/dist/components/account/sections/MyProfileSection.mjs.map +1 -0
- package/dist/components/account/sections/PreferencesSection.mjs +246 -0
- package/dist/components/account/sections/PreferencesSection.mjs.map +1 -0
- package/dist/components/account/sections/SecuritySection.mjs +147 -0
- package/dist/components/account/sections/SecuritySection.mjs.map +1 -0
- package/dist/components/ui/form/ComboboxField.mjs +130 -0
- package/dist/components/ui/form/ComboboxField.mjs.map +1 -0
- package/dist/components/ui/form/FormField.mjs +103 -0
- package/dist/components/ui/form/FormField.mjs.map +1 -0
- package/dist/components/ui/form/PhoneInput.mjs +78 -0
- package/dist/components/ui/form/PhoneInput.mjs.map +1 -0
- package/dist/components/ui/form/SelectField.mjs +80 -0
- package/dist/components/ui/form/SelectField.mjs.map +1 -0
- package/dist/components/ui/form/SwitchOptionFieldWithIcon.mjs +40 -0
- package/dist/components/ui/form/SwitchOptionFieldWithIcon.mjs.map +1 -0
- package/dist/components/ui/form/TextAreaField.mjs +56 -0
- package/dist/components/ui/form/TextAreaField.mjs.map +1 -0
- package/dist/enums/AccountSectionType.mjs +11 -0
- package/dist/enums/AccountSectionType.mjs.map +1 -0
- package/dist/hooks/useCountdownTimer.mjs +29 -0
- package/dist/hooks/useCountdownTimer.mjs.map +1 -0
- package/dist/hooks/useIsMobile.mjs +18 -0
- package/dist/hooks/useIsMobile.mjs.map +1 -0
- package/dist/hooks/usePasswordVisibility.mjs +13 -0
- package/dist/hooks/usePasswordVisibility.mjs.map +1 -0
- package/dist/index.mjs +80 -0
- package/dist/index.mjs.map +1 -1
- package/dist/modules/accounts/actions/account-management.action.mjs +163 -0
- package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -0
- package/dist/modules/accounts/hooks/useAccountManagement.mjs +64 -0
- package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -0
- package/dist/modules/accounts/services/account.service.mjs +162 -25
- package/dist/modules/accounts/services/account.service.mjs.map +1 -1
- package/dist/modules/accounts/services/two-factor.service.mjs +77 -0
- package/dist/modules/accounts/services/two-factor.service.mjs.map +1 -0
- package/dist/server.mjs +36 -0
- package/dist/server.mjs.map +1 -1
- package/dist/utils/browser/clipboard.mjs +36 -0
- package/dist/utils/browser/clipboard.mjs.map +1 -0
- package/dist/utils/file/index.mjs +9 -0
- package/dist/utils/file/index.mjs.map +1 -0
- package/dist/utils/format/masks.mjs +56 -0
- package/dist/utils/format/masks.mjs.map +1 -0
- package/dist/utils/intl/locales.mjs +12 -0
- package/dist/utils/intl/locales.mjs.map +1 -0
- package/dist/utils/intl/timezones.mjs +41 -0
- package/dist/utils/intl/timezones.mjs.map +1 -0
- package/dist/utils/validators/account.mjs +26 -0
- package/dist/utils/validators/account.mjs.map +1 -0
- package/dist/utils/validators/common.mjs +47 -0
- package/dist/utils/validators/common.mjs.map +1 -0
- package/package.json +5 -1
- package/src/components/account/ConfigurationsMyAccountModal.tsx +147 -0
- package/src/components/account/ConfirmGlobalPreferencesModal.tsx +66 -0
- package/src/components/account/DisableTwoFactorAuthModal.tsx +86 -0
- package/src/components/account/TwoFactorAuthModal.tsx +221 -0
- package/src/components/account/constants.ts +29 -0
- package/src/components/account/hooks/useChangeEmailForm.tsx +56 -0
- package/src/components/account/hooks/useChangePasswordForm.tsx +59 -0
- package/src/components/account/hooks/useChangePhoneForm.tsx +69 -0
- package/src/components/account/hooks/useConfigurationsModal.ts +40 -0
- package/src/components/account/hooks/useDisableTwoFactorAuthForm.tsx +69 -0
- package/src/components/account/hooks/useOtpVerification.tsx +116 -0
- package/src/components/account/hooks/useTwoFactorAuthForm.tsx +114 -0
- package/src/components/account/sections/ChangeEmailModal.tsx +224 -0
- package/src/components/account/sections/ChangePasswordSection.tsx +64 -0
- package/src/components/account/sections/ChangePhoneModal.tsx +229 -0
- package/src/components/account/sections/MyProfileSection.tsx +337 -0
- package/src/components/account/sections/PreferencesSection.tsx +277 -0
- package/src/components/account/sections/SecuritySection.tsx +160 -0
- package/src/components/ui/form/ComboboxField.tsx +154 -0
- package/src/components/ui/form/FormField.tsx +130 -0
- package/src/components/ui/form/PhoneInput.tsx +98 -0
- package/src/components/ui/form/SelectField.tsx +118 -0
- package/src/components/ui/form/SwitchOptionFieldWithIcon.tsx +47 -0
- package/src/components/ui/form/TextAreaField.tsx +70 -0
- package/src/enums/AccountSectionType.ts +6 -0
- package/src/hooks/useCountdownTimer.ts +41 -0
- package/src/hooks/useIsMobile.ts +19 -0
- package/src/hooks/usePasswordVisibility.ts +13 -0
- package/src/index.ts +70 -0
- package/src/modules/accounts/actions/account-management.action.ts +197 -0
- package/src/modules/accounts/hooks/useAccountManagement.ts +79 -0
- package/src/modules/accounts/services/account.service.ts +229 -50
- package/src/modules/accounts/services/two-factor.service.ts +98 -0
- package/src/modules/accounts/types.ts +157 -0
- package/src/server.ts +21 -0
- package/src/utils/browser/clipboard.ts +34 -0
- package/src/utils/file/index.ts +5 -0
- package/src/utils/format/masks.ts +52 -0
- package/src/utils/intl/locales.ts +15 -0
- package/src/utils/intl/timezones.ts +53 -0
- package/src/utils/validators/account.ts +36 -0
- package/src/utils/validators/common.ts +43 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useForm } from "react-hook-form";
|
|
4
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
5
|
+
import { useMutation } from "@tanstack/react-query";
|
|
6
|
+
import { toast } from "sonner";
|
|
7
|
+
import { Toast } from "../../ui/feedback/Toast";
|
|
8
|
+
import { changePasswordSchema } from "../../../utils/validators/account";
|
|
9
|
+
import { changePasswordAction } from "../../../modules/accounts/actions/account-management.action";
|
|
10
|
+
function useChangePasswordForm({ onSuccess } = {}) {
|
|
11
|
+
const form = useForm({
|
|
12
|
+
resolver: zodResolver(changePasswordSchema),
|
|
13
|
+
mode: "onChange",
|
|
14
|
+
defaultValues: {
|
|
15
|
+
currentPassword: "",
|
|
16
|
+
newPassword: ""
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const mutation = useMutation({
|
|
20
|
+
mutationFn: changePasswordAction,
|
|
21
|
+
onSuccess: (result) => {
|
|
22
|
+
if (!result.success) {
|
|
23
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: result.error ?? "Erro ao alterar senha", toastId: t }));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: "Senha alterada com sucesso", toastId: t }));
|
|
27
|
+
form.reset();
|
|
28
|
+
onSuccess?.();
|
|
29
|
+
},
|
|
30
|
+
onError: () => {
|
|
31
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: "Erro ao alterar senha. Tente novamente.", toastId: t }));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const onSubmit = (data) => {
|
|
35
|
+
mutation.mutate(data);
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
register: form.register,
|
|
39
|
+
handleSubmit: form.handleSubmit(onSubmit),
|
|
40
|
+
errors: form.formState.errors,
|
|
41
|
+
isLoading: mutation.isPending
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
useChangePasswordForm as default
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=useChangePasswordForm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/account/hooks/useChangePasswordForm.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useForm } from 'react-hook-form';\r\nimport { zodResolver } from '@hookform/resolvers/zod';\r\nimport { useMutation } from '@tanstack/react-query';\r\nimport { toast } from 'sonner';\r\nimport { Toast } from '../../ui/feedback/Toast';\r\nimport { changePasswordSchema, type ChangePasswordFormData } from '../../../utils/validators/account';\r\nimport { changePasswordAction } from '../../../modules/accounts/actions/account-management.action';\r\n\r\ninterface UseChangePasswordFormProps {\r\n onSuccess?: () => void;\r\n}\r\n\r\nexport default function useChangePasswordForm({ onSuccess }: UseChangePasswordFormProps = {}) {\r\n const form = useForm<ChangePasswordFormData>({\r\n resolver: zodResolver(changePasswordSchema),\r\n mode: 'onChange',\r\n defaultValues: {\r\n currentPassword: '',\r\n newPassword: '',\r\n },\r\n });\r\n\r\n const mutation = useMutation({\r\n mutationFn: changePasswordAction,\r\n onSuccess: (result) => {\r\n if (!result.success) {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message={result.error ?? 'Erro ao alterar senha'} toastId={t} />\r\n ));\r\n return;\r\n }\r\n\r\n toast.custom((t) => (\r\n <Toast variant=\"success\" message=\"Senha alterada com sucesso\" toastId={t} />\r\n ));\r\n\r\n form.reset();\r\n onSuccess?.();\r\n },\r\n onError: () => {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message=\"Erro ao alterar senha. Tente novamente.\" toastId={t} />\r\n ));\r\n },\r\n });\r\n\r\n const onSubmit = (data: ChangePasswordFormData) => {\r\n mutation.mutate(data);\r\n };\r\n\r\n return {\r\n register: form.register,\r\n handleSubmit: form.handleSubmit(onSubmit),\r\n errors: form.formState.errors,\r\n isLoading: mutation.isPending,\r\n };\r\n}\r\n"],"mappings":";AA6BU;AA3BV,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,4BAAyD;AAClE,SAAS,4BAA4B;AAMtB,SAAR,sBAAuC,EAAE,UAAU,IAAgC,CAAC,GAAG;AAC5F,QAAM,OAAO,QAAgC;AAAA,IAC3C,UAAU,YAAY,oBAAoB;AAAA,IAC1C,MAAM;AAAA,IACN,eAAe;AAAA,MACb,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAED,QAAM,WAAW,YAAY;AAAA,IAC3B,YAAY;AAAA,IACZ,WAAW,CAAC,WAAW;AACrB,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAS,OAAO,SAAS,yBAAyB,SAAS,GAAG,CACtF;AACD;AAAA,MACF;AAEA,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAQ,8BAA6B,SAAS,GAAG,CAC3E;AAED,WAAK,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,2CAA0C,SAAS,GAAG,CACtF;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,WAAW,CAAC,SAAiC;AACjD,aAAS,OAAO,IAAI;AAAA,EACtB;AAEA,SAAO;AAAA,IACL,UAAU,KAAK;AAAA,IACf,cAAc,KAAK,aAAa,QAAQ;AAAA,IACxC,QAAQ,KAAK,UAAU;AAAA,IACvB,WAAW,SAAS;AAAA,EACtB;AACF;","names":[]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback } from "react";
|
|
4
|
+
import { useForm } from "react-hook-form";
|
|
5
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
6
|
+
import { toast } from "sonner";
|
|
7
|
+
import { Toast } from "../../ui/feedback/Toast";
|
|
8
|
+
import { changePhoneSchema } from "../../../utils/validators/account";
|
|
9
|
+
import { formatPhone } from "../../../utils/format/masks";
|
|
10
|
+
import { requestPhoneChangeAction } from "../../../modules/accounts/actions/account-management.action";
|
|
11
|
+
function useChangePhoneForm() {
|
|
12
|
+
const [showVerification, setShowVerification] = useState(false);
|
|
13
|
+
const form = useForm({
|
|
14
|
+
resolver: zodResolver(changePhoneSchema),
|
|
15
|
+
mode: "onChange",
|
|
16
|
+
defaultValues: { phone: "" }
|
|
17
|
+
});
|
|
18
|
+
const phoneValue = form.watch("phone");
|
|
19
|
+
const errors = form.formState.errors;
|
|
20
|
+
const isSubmitting = form.formState.isSubmitting;
|
|
21
|
+
const handlePhoneChange = useCallback(
|
|
22
|
+
(e) => {
|
|
23
|
+
const formatted = formatPhone(e.target.value);
|
|
24
|
+
form.setValue("phone", formatted, { shouldValidate: true });
|
|
25
|
+
},
|
|
26
|
+
[form]
|
|
27
|
+
);
|
|
28
|
+
const handleContinue = form.handleSubmit(async (data) => {
|
|
29
|
+
const result = await requestPhoneChangeAction(data.phone);
|
|
30
|
+
if (!result.success) {
|
|
31
|
+
toast.custom((t) => /* @__PURE__ */ jsx(
|
|
32
|
+
Toast,
|
|
33
|
+
{
|
|
34
|
+
variant: "error",
|
|
35
|
+
message: result.error ?? "N\xFAmero j\xE1 existente ou ocorreu um erro. Tente novamente mais tarde.",
|
|
36
|
+
toastId: t
|
|
37
|
+
}
|
|
38
|
+
));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
setShowVerification(true);
|
|
42
|
+
});
|
|
43
|
+
const handleBack = useCallback(() => {
|
|
44
|
+
setShowVerification(false);
|
|
45
|
+
}, []);
|
|
46
|
+
const resetForm = useCallback(() => {
|
|
47
|
+
form.reset();
|
|
48
|
+
setShowVerification(false);
|
|
49
|
+
}, [form]);
|
|
50
|
+
return {
|
|
51
|
+
showVerification,
|
|
52
|
+
phoneValue,
|
|
53
|
+
isSubmitting,
|
|
54
|
+
errors,
|
|
55
|
+
handlePhoneChange,
|
|
56
|
+
handleContinue,
|
|
57
|
+
handleBack,
|
|
58
|
+
resetForm
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
useChangePhoneForm as default
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=useChangePhoneForm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/account/hooks/useChangePhoneForm.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useCallback } from 'react';\r\nimport { useForm } from 'react-hook-form';\r\nimport { zodResolver } from '@hookform/resolvers/zod';\r\nimport { toast } from 'sonner';\r\nimport { Toast } from '../../ui/feedback/Toast';\r\nimport { changePhoneSchema, type ChangePhoneFormData } from '../../../utils/validators/account';\r\nimport { formatPhone } from '../../../utils/format/masks';\r\nimport { requestPhoneChangeAction } from '../../../modules/accounts/actions/account-management.action';\r\n\r\nexport default function useChangePhoneForm() {\r\n const [showVerification, setShowVerification] = useState(false);\r\n\r\n const form = useForm<ChangePhoneFormData>({\r\n resolver: zodResolver(changePhoneSchema),\r\n mode: 'onChange',\r\n defaultValues: { phone: '' },\r\n });\r\n\r\n const phoneValue = form.watch('phone');\r\n const errors = form.formState.errors;\r\n const isSubmitting = form.formState.isSubmitting;\r\n\r\n const handlePhoneChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const formatted = formatPhone(e.target.value);\r\n form.setValue('phone', formatted, { shouldValidate: true });\r\n },\r\n [form]\r\n );\r\n\r\n const handleContinue = form.handleSubmit(async (data) => {\r\n const result = await requestPhoneChangeAction(data.phone);\r\n\r\n if (!result.success) {\r\n toast.custom((t) => (\r\n <Toast\r\n variant=\"error\"\r\n message={result.error ?? 'Número já existente ou ocorreu um erro. Tente novamente mais tarde.'}\r\n toastId={t}\r\n />\r\n ));\r\n return;\r\n }\r\n\r\n setShowVerification(true);\r\n });\r\n\r\n const handleBack = useCallback(() => {\r\n setShowVerification(false);\r\n }, []);\r\n\r\n const resetForm = useCallback(() => {\r\n form.reset();\r\n setShowVerification(false);\r\n }, [form]);\r\n\r\n return {\r\n showVerification,\r\n phoneValue,\r\n isSubmitting,\r\n errors,\r\n handlePhoneChange,\r\n handleContinue,\r\n handleBack,\r\n resetForm,\r\n };\r\n}\r\n"],"mappings":";AAqCQ;AAnCR,SAAS,UAAU,mBAAmB;AACtC,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,yBAAmD;AAC5D,SAAS,mBAAmB;AAC5B,SAAS,gCAAgC;AAE1B,SAAR,qBAAsC;AAC3C,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,KAAK;AAE9D,QAAM,OAAO,QAA6B;AAAA,IACxC,UAAU,YAAY,iBAAiB;AAAA,IACvC,MAAM;AAAA,IACN,eAAe,EAAE,OAAO,GAAG;AAAA,EAC7B,CAAC;AAED,QAAM,aAAa,KAAK,MAAM,OAAO;AACrC,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,eAAe,KAAK,UAAU;AAEpC,QAAM,oBAAoB;AAAA,IACxB,CAAC,MAA2C;AAC1C,YAAM,YAAY,YAAY,EAAE,OAAO,KAAK;AAC5C,WAAK,SAAS,SAAS,WAAW,EAAE,gBAAgB,KAAK,CAAC;AAAA,IAC5D;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AAEA,QAAM,iBAAiB,KAAK,aAAa,OAAO,SAAS;AACvD,UAAM,SAAS,MAAM,yBAAyB,KAAK,KAAK;AAExD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,OAAO,CAAC,MACZ;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS,OAAO,SAAS;AAAA,UACzB,SAAS;AAAA;AAAA,MACX,CACD;AACD;AAAA,IACF;AAEA,wBAAoB,IAAI;AAAA,EAC1B,CAAC;AAED,QAAM,aAAa,YAAY,MAAM;AACnC,wBAAoB,KAAK;AAAA,EAC3B,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,YAAY,MAAM;AAClC,SAAK,MAAM;AACX,wBAAoB,KAAK;AAAA,EAC3B,GAAG,CAAC,IAAI,CAAC;AAET,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useCallback, useEffect } from "react";
|
|
3
|
+
import { AccountSectionType } from "../../../enums/AccountSectionType";
|
|
4
|
+
function useConfigurationsModal({
|
|
5
|
+
isOpen,
|
|
6
|
+
initialSection
|
|
7
|
+
}) {
|
|
8
|
+
const [activeSection, setActiveSection] = useState(
|
|
9
|
+
AccountSectionType.MY_PROFILE
|
|
10
|
+
);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (isOpen && initialSection) {
|
|
13
|
+
setActiveSection(initialSection);
|
|
14
|
+
} else if (isOpen && !initialSection) {
|
|
15
|
+
setActiveSection(AccountSectionType.MY_PROFILE);
|
|
16
|
+
}
|
|
17
|
+
}, [isOpen, initialSection]);
|
|
18
|
+
const handleSectionChange = useCallback((section) => {
|
|
19
|
+
setActiveSection(section);
|
|
20
|
+
}, []);
|
|
21
|
+
const resetSection = useCallback(() => {
|
|
22
|
+
setActiveSection(AccountSectionType.MY_PROFILE);
|
|
23
|
+
}, []);
|
|
24
|
+
return {
|
|
25
|
+
activeSection,
|
|
26
|
+
setActiveSection: handleSectionChange,
|
|
27
|
+
resetSection
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
useConfigurationsModal as default
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=useConfigurationsModal.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/account/hooks/useConfigurationsModal.ts"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useCallback, useEffect } from 'react';\r\nimport { AccountSectionType } from '../../../enums/AccountSectionType';\r\n\r\ninterface UseConfigurationsModalProps {\r\n isOpen: boolean;\r\n initialSection?: AccountSectionType;\r\n}\r\n\r\nexport default function useConfigurationsModal({\r\n isOpen,\r\n initialSection,\r\n}: UseConfigurationsModalProps) {\r\n const [activeSection, setActiveSection] = useState<AccountSectionType>(\r\n AccountSectionType.MY_PROFILE\r\n );\r\n\r\n useEffect(() => {\r\n if (isOpen && initialSection) {\r\n setActiveSection(initialSection);\r\n } else if (isOpen && !initialSection) {\r\n setActiveSection(AccountSectionType.MY_PROFILE);\r\n }\r\n }, [isOpen, initialSection]);\r\n\r\n const handleSectionChange = useCallback((section: AccountSectionType) => {\r\n setActiveSection(section);\r\n }, []);\r\n\r\n const resetSection = useCallback(() => {\r\n setActiveSection(AccountSectionType.MY_PROFILE);\r\n }, []);\r\n\r\n return {\r\n activeSection,\r\n setActiveSection: handleSectionChange,\r\n resetSection,\r\n };\r\n}\r\n"],"mappings":";AAEA,SAAS,UAAU,aAAa,iBAAiB;AACjD,SAAS,0BAA0B;AAOpB,SAAR,uBAAwC;AAAA,EAC7C;AAAA,EACA;AACF,GAAgC;AAC9B,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC,mBAAmB;AAAA,EACrB;AAEA,YAAU,MAAM;AACd,QAAI,UAAU,gBAAgB;AAC5B,uBAAiB,cAAc;AAAA,IACjC,WAAW,UAAU,CAAC,gBAAgB;AACpC,uBAAiB,mBAAmB,UAAU;AAAA,IAChD;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,QAAM,sBAAsB,YAAY,CAAC,YAAgC;AACvE,qBAAiB,OAAO;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,YAAY,MAAM;AACrC,qBAAiB,mBAAmB,UAAU;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB;AAAA,IAClB;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback } from "react";
|
|
4
|
+
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
5
|
+
import { toast } from "sonner";
|
|
6
|
+
import { Toast } from "../../ui/feedback/Toast";
|
|
7
|
+
import { USER_QUERY_KEY } from "../../../modules/auth/hooks/useUserQuery";
|
|
8
|
+
import { disableTwoFactorAction } from "../../../modules/accounts/actions/account-management.action";
|
|
9
|
+
function useDisableTwoFactorAuthForm({
|
|
10
|
+
onClose,
|
|
11
|
+
onSuccess
|
|
12
|
+
}) {
|
|
13
|
+
const [code, setCode] = useState("");
|
|
14
|
+
const queryClient = useQueryClient();
|
|
15
|
+
const isValid = code.length === 6;
|
|
16
|
+
const mutation = useMutation({
|
|
17
|
+
mutationFn: (otpCode) => disableTwoFactorAction(otpCode),
|
|
18
|
+
onSuccess: (result) => {
|
|
19
|
+
if (!result.success) {
|
|
20
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: result.error ?? "C\xF3digo inv\xE1lido", toastId: t }));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
queryClient.invalidateQueries({ queryKey: USER_QUERY_KEY });
|
|
24
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: "Autentica\xE7\xE3o de dois fatores desabilitada", toastId: t }));
|
|
25
|
+
setCode("");
|
|
26
|
+
onSuccess?.();
|
|
27
|
+
},
|
|
28
|
+
onError: () => {
|
|
29
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: "Erro ao desabilitar 2FA. Tente novamente.", toastId: t }));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const { mutate, reset } = mutation;
|
|
33
|
+
const handleClose = useCallback(() => {
|
|
34
|
+
setCode("");
|
|
35
|
+
reset();
|
|
36
|
+
onClose();
|
|
37
|
+
}, [onClose, reset]);
|
|
38
|
+
const handleSubmit = useCallback(() => {
|
|
39
|
+
if (!isValid) return;
|
|
40
|
+
mutate(code);
|
|
41
|
+
}, [code, isValid, mutate]);
|
|
42
|
+
return {
|
|
43
|
+
code,
|
|
44
|
+
setCode,
|
|
45
|
+
isValid,
|
|
46
|
+
isLoading: mutation.isPending,
|
|
47
|
+
handleClose,
|
|
48
|
+
handleSubmit
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
useDisableTwoFactorAuthForm as default
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=useDisableTwoFactorAuthForm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/account/hooks/useDisableTwoFactorAuthForm.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useCallback } from 'react';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { toast } from 'sonner';\r\nimport { Toast } from '../../ui/feedback/Toast';\r\nimport { USER_QUERY_KEY } from '../../../modules/auth/hooks/useUserQuery';\r\nimport { disableTwoFactorAction } from '../../../modules/accounts/actions/account-management.action';\r\n\r\ninterface UseDisableTwoFactorAuthFormProps {\r\n onClose: () => void;\r\n onSuccess?: () => void;\r\n}\r\n\r\nexport default function useDisableTwoFactorAuthForm({\r\n onClose,\r\n onSuccess,\r\n}: UseDisableTwoFactorAuthFormProps) {\r\n const [code, setCode] = useState('');\r\n const queryClient = useQueryClient();\r\n\r\n const isValid = code.length === 6;\r\n\r\n const mutation = useMutation({\r\n mutationFn: (otpCode: string) => disableTwoFactorAction(otpCode),\r\n onSuccess: (result) => {\r\n if (!result.success) {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message={result.error ?? 'Código inválido'} toastId={t} />\r\n ));\r\n return;\r\n }\r\n\r\n queryClient.invalidateQueries({ queryKey: USER_QUERY_KEY });\r\n toast.custom((t) => (\r\n <Toast variant=\"success\" message=\"Autenticação de dois fatores desabilitada\" toastId={t} />\r\n ));\r\n setCode('');\r\n onSuccess?.();\r\n },\r\n onError: () => {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message=\"Erro ao desabilitar 2FA. Tente novamente.\" toastId={t} />\r\n ));\r\n },\r\n });\r\n\r\n const { mutate, reset } = mutation;\r\n\r\n const handleClose = useCallback(() => {\r\n setCode('');\r\n reset();\r\n onClose();\r\n }, [onClose, reset]);\r\n\r\n const handleSubmit = useCallback(() => {\r\n if (!isValid) return;\r\n mutate(code);\r\n }, [code, isValid, mutate]);\r\n\r\n return {\r\n code,\r\n setCode,\r\n isValid,\r\n isLoading: mutation.isPending,\r\n handleClose,\r\n handleSubmit,\r\n };\r\n}\r\n"],"mappings":";AA4BU;AA1BV,SAAS,UAAU,mBAAmB;AACtC,SAAS,aAAa,sBAAsB;AAC5C,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,sBAAsB;AAC/B,SAAS,8BAA8B;AAOxB,SAAR,4BAA6C;AAAA,EAClD;AAAA,EACA;AACF,GAAqC;AACnC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,cAAc,eAAe;AAEnC,QAAM,UAAU,KAAK,WAAW;AAEhC,QAAM,WAAW,YAAY;AAAA,IAC3B,YAAY,CAAC,YAAoB,uBAAuB,OAAO;AAAA,IAC/D,WAAW,CAAC,WAAW;AACrB,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAS,OAAO,SAAS,yBAAmB,SAAS,GAAG,CAChF;AACD;AAAA,MACF;AAEA,kBAAY,kBAAkB,EAAE,UAAU,eAAe,CAAC;AAC1D,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAQ,mDAA4C,SAAS,GAAG,CAC1F;AACD,cAAQ,EAAE;AACV,kBAAY;AAAA,IACd;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,6CAA4C,SAAS,GAAG,CACxF;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,EAAE,QAAQ,MAAM,IAAI;AAE1B,QAAM,cAAc,YAAY,MAAM;AACpC,YAAQ,EAAE;AACV,UAAM;AACN,YAAQ;AAAA,EACV,GAAG,CAAC,SAAS,KAAK,CAAC;AAEnB,QAAM,eAAe,YAAY,MAAM;AACrC,QAAI,CAAC,QAAS;AACd,WAAO,IAAI;AAAA,EACb,GAAG,CAAC,MAAM,SAAS,MAAM,CAAC;AAE1B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,SAAS;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback } from "react";
|
|
4
|
+
import { toast } from "sonner";
|
|
5
|
+
import { Toast } from "../../ui/feedback/Toast";
|
|
6
|
+
import useCountdownTimer from "../../../hooks/useCountdownTimer";
|
|
7
|
+
import { OTP_CODE_LENGTH, VALID_OTP_CODE } from "../../../utils/validators/account";
|
|
8
|
+
import { hasExactLength } from "../../../utils/validators/common";
|
|
9
|
+
function useOtpVerification({
|
|
10
|
+
onSuccess,
|
|
11
|
+
successMessage,
|
|
12
|
+
validateFn,
|
|
13
|
+
resendFn
|
|
14
|
+
}) {
|
|
15
|
+
const [code, setCode] = useState("");
|
|
16
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
17
|
+
const [hasError, setHasError] = useState(false);
|
|
18
|
+
const {
|
|
19
|
+
seconds: timer,
|
|
20
|
+
isExpired: canResend,
|
|
21
|
+
reset: resetTimer
|
|
22
|
+
} = useCountdownTimer({ initialSeconds: 59 });
|
|
23
|
+
const handleCodeChange = useCallback(
|
|
24
|
+
(value) => {
|
|
25
|
+
setCode(value.toUpperCase());
|
|
26
|
+
if (hasError) {
|
|
27
|
+
setHasError(false);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
[hasError]
|
|
31
|
+
);
|
|
32
|
+
const handleValidate = useCallback(async () => {
|
|
33
|
+
if (!hasExactLength(code, OTP_CODE_LENGTH)) return;
|
|
34
|
+
setIsLoading(true);
|
|
35
|
+
setHasError(false);
|
|
36
|
+
try {
|
|
37
|
+
let isValid;
|
|
38
|
+
if (validateFn) {
|
|
39
|
+
isValid = await validateFn(code);
|
|
40
|
+
} else {
|
|
41
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
42
|
+
isValid = code === VALID_OTP_CODE;
|
|
43
|
+
}
|
|
44
|
+
if (!isValid) {
|
|
45
|
+
setHasError(true);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: successMessage, toastId: t }));
|
|
49
|
+
setCode("");
|
|
50
|
+
onSuccess();
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("Erro ao validar c\xF3digo:", error);
|
|
53
|
+
setHasError(true);
|
|
54
|
+
} finally {
|
|
55
|
+
setIsLoading(false);
|
|
56
|
+
}
|
|
57
|
+
}, [code, onSuccess, successMessage, validateFn]);
|
|
58
|
+
const handleResend = useCallback(async () => {
|
|
59
|
+
if (!canResend) return;
|
|
60
|
+
try {
|
|
61
|
+
resetTimer();
|
|
62
|
+
setHasError(false);
|
|
63
|
+
setCode("");
|
|
64
|
+
if (resendFn) {
|
|
65
|
+
await resendFn();
|
|
66
|
+
}
|
|
67
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: "C\xF3digo reenviado", toastId: t }));
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error("Erro ao reenviar c\xF3digo:", error);
|
|
70
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: "Erro ao reenviar c\xF3digo. Tente novamente.", toastId: t }));
|
|
71
|
+
}
|
|
72
|
+
}, [canResend, resetTimer, resendFn]);
|
|
73
|
+
const reset = useCallback(() => {
|
|
74
|
+
setCode("");
|
|
75
|
+
setHasError(false);
|
|
76
|
+
}, []);
|
|
77
|
+
const isValidLength = hasExactLength(code, OTP_CODE_LENGTH);
|
|
78
|
+
return {
|
|
79
|
+
code,
|
|
80
|
+
isLoading,
|
|
81
|
+
hasError,
|
|
82
|
+
timer,
|
|
83
|
+
canResend,
|
|
84
|
+
isValidLength,
|
|
85
|
+
handleCodeChange,
|
|
86
|
+
handleValidate,
|
|
87
|
+
handleResend,
|
|
88
|
+
reset
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
useOtpVerification as default
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=useOtpVerification.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/account/hooks/useOtpVerification.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useCallback } from 'react';\r\nimport { toast } from 'sonner';\r\nimport { Toast } from '../../ui/feedback/Toast';\r\nimport useCountdownTimer from '../../../hooks/useCountdownTimer';\r\nimport { OTP_CODE_LENGTH, VALID_OTP_CODE } from '../../../utils/validators/account';\r\nimport { hasExactLength } from '../../../utils/validators/common';\r\n\r\ninterface UseOtpVerificationOptions {\r\n onSuccess: () => void;\r\n successMessage: string;\r\n validateFn?: (code: string) => Promise<boolean>;\r\n resendFn?: () => Promise<void>;\r\n}\r\n\r\nexport default function useOtpVerification({\r\n onSuccess,\r\n successMessage,\r\n validateFn,\r\n resendFn,\r\n}: UseOtpVerificationOptions) {\r\n const [code, setCode] = useState('');\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [hasError, setHasError] = useState(false);\r\n\r\n const {\r\n seconds: timer,\r\n isExpired: canResend,\r\n reset: resetTimer,\r\n } = useCountdownTimer({ initialSeconds: 59 });\r\n\r\n const handleCodeChange = useCallback(\r\n (value: string) => {\r\n setCode(value.toUpperCase());\r\n if (hasError) {\r\n setHasError(false);\r\n }\r\n },\r\n [hasError]\r\n );\r\n\r\n const handleValidate = useCallback(async () => {\r\n if (!hasExactLength(code, OTP_CODE_LENGTH)) return;\r\n\r\n setIsLoading(true);\r\n setHasError(false);\r\n\r\n try {\r\n let isValid: boolean;\r\n\r\n if (validateFn) {\r\n isValid = await validateFn(code);\r\n } else {\r\n await new Promise((resolve) => setTimeout(resolve, 500));\r\n isValid = code === VALID_OTP_CODE;\r\n }\r\n\r\n if (!isValid) {\r\n setHasError(true);\r\n return;\r\n }\r\n\r\n toast.custom((t) => <Toast variant=\"success\" message={successMessage} toastId={t} />);\r\n\r\n setCode('');\r\n onSuccess();\r\n } catch (error) {\r\n console.error('Erro ao validar código:', error);\r\n setHasError(true);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [code, onSuccess, successMessage, validateFn]);\r\n\r\n const handleResend = useCallback(async () => {\r\n if (!canResend) return;\r\n\r\n try {\r\n resetTimer();\r\n setHasError(false);\r\n setCode('');\r\n\r\n if (resendFn) {\r\n await resendFn();\r\n }\r\n\r\n toast.custom((t) => <Toast variant=\"success\" message=\"Código reenviado\" toastId={t} />);\r\n } catch (error) {\r\n console.error('Erro ao reenviar código:', error);\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message=\"Erro ao reenviar código. Tente novamente.\" toastId={t} />\r\n ));\r\n }\r\n }, [canResend, resetTimer, resendFn]);\r\n\r\n const reset = useCallback(() => {\r\n setCode('');\r\n setHasError(false);\r\n }, []);\r\n\r\n const isValidLength = hasExactLength(code, OTP_CODE_LENGTH);\r\n\r\n return {\r\n code,\r\n isLoading,\r\n hasError,\r\n timer,\r\n canResend,\r\n isValidLength,\r\n handleCodeChange,\r\n handleValidate,\r\n handleResend,\r\n reset,\r\n };\r\n}\r\n"],"mappings":";AA+D0B;AA7D1B,SAAS,UAAU,mBAAmB;AACtC,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,OAAO,uBAAuB;AAC9B,SAAS,iBAAiB,sBAAsB;AAChD,SAAS,sBAAsB;AAShB,SAAR,mBAAoC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,QAAM;AAAA,IACJ,SAAS;AAAA,IACT,WAAW;AAAA,IACX,OAAO;AAAA,EACT,IAAI,kBAAkB,EAAE,gBAAgB,GAAG,CAAC;AAE5C,QAAM,mBAAmB;AAAA,IACvB,CAAC,UAAkB;AACjB,cAAQ,MAAM,YAAY,CAAC;AAC3B,UAAI,UAAU;AACZ,oBAAY,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,QAAM,iBAAiB,YAAY,YAAY;AAC7C,QAAI,CAAC,eAAe,MAAM,eAAe,EAAG;AAE5C,iBAAa,IAAI;AACjB,gBAAY,KAAK;AAEjB,QAAI;AACF,UAAI;AAEJ,UAAI,YAAY;AACd,kBAAU,MAAM,WAAW,IAAI;AAAA,MACjC,OAAO;AACL,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,kBAAU,SAAS;AAAA,MACrB;AAEA,UAAI,CAAC,SAAS;AACZ,oBAAY,IAAI;AAChB;AAAA,MACF;AAEA,YAAM,OAAO,CAAC,MAAM,oBAAC,SAAM,SAAQ,WAAU,SAAS,gBAAgB,SAAS,GAAG,CAAE;AAEpF,cAAQ,EAAE;AACV,gBAAU;AAAA,IACZ,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA2B,KAAK;AAC9C,kBAAY,IAAI;AAAA,IAClB,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,MAAM,WAAW,gBAAgB,UAAU,CAAC;AAEhD,QAAM,eAAe,YAAY,YAAY;AAC3C,QAAI,CAAC,UAAW;AAEhB,QAAI;AACF,iBAAW;AACX,kBAAY,KAAK;AACjB,cAAQ,EAAE;AAEV,UAAI,UAAU;AACZ,cAAM,SAAS;AAAA,MACjB;AAEA,YAAM,OAAO,CAAC,MAAM,oBAAC,SAAM,SAAQ,WAAU,SAAQ,uBAAmB,SAAS,GAAG,CAAE;AAAA,IACxF,SAAS,OAAO;AACd,cAAQ,MAAM,+BAA4B,KAAK;AAC/C,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,gDAA4C,SAAS,GAAG,CACxF;AAAA,IACH;AAAA,EACF,GAAG,CAAC,WAAW,YAAY,QAAQ,CAAC;AAEpC,QAAM,QAAQ,YAAY,MAAM;AAC9B,YAAQ,EAAE;AACV,gBAAY,KAAK;AAAA,EACnB,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,eAAe,MAAM,eAAe;AAE1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback, useEffect } from "react";
|
|
4
|
+
import { useMutation } from "@tanstack/react-query";
|
|
5
|
+
import { toast } from "sonner";
|
|
6
|
+
import { Toast } from "../../ui/feedback/Toast";
|
|
7
|
+
import { copyToClipboard } from "../../../utils/browser/clipboard";
|
|
8
|
+
import {
|
|
9
|
+
generateTwoFactorAction,
|
|
10
|
+
confirmTwoFactorAction
|
|
11
|
+
} from "../../../modules/accounts/actions/account-management.action";
|
|
12
|
+
function useTwoFactorAuthForm({ onSuccess, open } = {}) {
|
|
13
|
+
const [code, setCode] = useState("");
|
|
14
|
+
const [step, setStep] = useState("code");
|
|
15
|
+
const generateMutation = useMutation({
|
|
16
|
+
mutationFn: generateTwoFactorAction,
|
|
17
|
+
onSuccess: (result) => {
|
|
18
|
+
if (!result.success) {
|
|
19
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: result.error ?? "Erro ao gerar QR Code. Tente novamente.", toastId: t }));
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
onError: () => {
|
|
23
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: "Erro ao gerar QR Code. Tente novamente.", toastId: t }));
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const confirmMutation = useMutation({
|
|
27
|
+
mutationFn: (otpCode) => confirmTwoFactorAction(otpCode),
|
|
28
|
+
onSuccess: (result) => {
|
|
29
|
+
if (!result.success) {
|
|
30
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: result.error ?? "C\xF3digo inv\xE1lido", toastId: t }));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
setStep("recovery");
|
|
34
|
+
},
|
|
35
|
+
onError: () => {
|
|
36
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: "Erro ao confirmar c\xF3digo. Tente novamente.", toastId: t }));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const { mutate: triggerGenerate } = generateMutation;
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (open) {
|
|
42
|
+
triggerGenerate();
|
|
43
|
+
}
|
|
44
|
+
}, [open, triggerGenerate]);
|
|
45
|
+
const generateFailed = generateMutation.isSuccess && !generateMutation.data?.success || generateMutation.isError;
|
|
46
|
+
const isCodeComplete = code.length === 6;
|
|
47
|
+
const handleSubmit = () => {
|
|
48
|
+
if (!isCodeComplete) return;
|
|
49
|
+
confirmMutation.mutate(code);
|
|
50
|
+
};
|
|
51
|
+
const handleFinalize = () => {
|
|
52
|
+
onSuccess?.();
|
|
53
|
+
setTimeout(resetForm, 300);
|
|
54
|
+
};
|
|
55
|
+
const handleCopyCodes = useCallback(async () => {
|
|
56
|
+
const codes = generateMutation.data?.backupCodes ?? [];
|
|
57
|
+
const success = await copyToClipboard(codes.join("\n"));
|
|
58
|
+
if (success) {
|
|
59
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: "C\xF3digos copiados com sucesso", toastId: t }));
|
|
60
|
+
}
|
|
61
|
+
}, [generateMutation.data]);
|
|
62
|
+
const resetForm = () => {
|
|
63
|
+
setCode("");
|
|
64
|
+
setStep("code");
|
|
65
|
+
generateMutation.reset();
|
|
66
|
+
confirmMutation.reset();
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
code,
|
|
70
|
+
setCode,
|
|
71
|
+
isCodeComplete,
|
|
72
|
+
isGenerating: generateMutation.isPending,
|
|
73
|
+
isConfirming: confirmMutation.isPending,
|
|
74
|
+
generateFailed,
|
|
75
|
+
retryGenerate: triggerGenerate,
|
|
76
|
+
qrcode: generateMutation.data?.qrcode,
|
|
77
|
+
backupCodes: generateMutation.data?.backupCodes ?? [],
|
|
78
|
+
step,
|
|
79
|
+
handleSubmit,
|
|
80
|
+
handleFinalize,
|
|
81
|
+
handleCopyCodes,
|
|
82
|
+
resetForm
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
useTwoFactorAuthForm as default
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=useTwoFactorAuthForm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/account/hooks/useTwoFactorAuthForm.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useCallback, useEffect } from 'react';\r\nimport { useMutation } from '@tanstack/react-query';\r\nimport { toast } from 'sonner';\r\nimport { Toast } from '../../ui/feedback/Toast';\r\nimport { copyToClipboard } from '../../../utils/browser/clipboard';\r\nimport {\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n} from '../../../modules/accounts/actions/account-management.action';\r\n\r\ntype Step = 'code' | 'recovery';\r\n\r\ninterface UseTwoFactorAuthFormProps {\r\n onSuccess?: () => void;\r\n open?: boolean;\r\n}\r\n\r\nexport default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAuthFormProps = {}) {\r\n const [code, setCode] = useState('');\r\n const [step, setStep] = useState<Step>('code');\r\n\r\n const generateMutation = useMutation({\r\n mutationFn: generateTwoFactorAction,\r\n onSuccess: (result) => {\r\n if (!result.success) {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message={result.error ?? 'Erro ao gerar QR Code. Tente novamente.'} toastId={t} />\r\n ));\r\n }\r\n },\r\n onError: () => {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message=\"Erro ao gerar QR Code. Tente novamente.\" toastId={t} />\r\n ));\r\n },\r\n });\r\n\r\n const confirmMutation = useMutation({\r\n mutationFn: (otpCode: string) => confirmTwoFactorAction(otpCode),\r\n onSuccess: (result) => {\r\n if (!result.success) {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message={result.error ?? 'Código inválido'} toastId={t} />\r\n ));\r\n return;\r\n }\r\n setStep('recovery');\r\n },\r\n onError: () => {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message=\"Erro ao confirmar código. Tente novamente.\" toastId={t} />\r\n ));\r\n },\r\n });\r\n\r\n const { mutate: triggerGenerate } = generateMutation;\r\n\r\n useEffect(() => {\r\n if (open) {\r\n triggerGenerate();\r\n }\r\n }, [open, triggerGenerate]);\r\n\r\n const generateFailed =\r\n (generateMutation.isSuccess && !generateMutation.data?.success) || generateMutation.isError;\r\n\r\n const isCodeComplete = code.length === 6;\r\n\r\n const handleSubmit = () => {\r\n if (!isCodeComplete) return;\r\n confirmMutation.mutate(code);\r\n };\r\n\r\n const handleFinalize = () => {\r\n onSuccess?.();\r\n setTimeout(resetForm, 300);\r\n };\r\n\r\n const handleCopyCodes = useCallback(async () => {\r\n const codes = generateMutation.data?.backupCodes ?? [];\r\n const success = await copyToClipboard(codes.join('\\n'));\r\n if (success) {\r\n toast.custom((t) => (\r\n <Toast variant=\"success\" message=\"Códigos copiados com sucesso\" toastId={t} />\r\n ));\r\n }\r\n }, [generateMutation.data]);\r\n\r\n const resetForm = () => {\r\n setCode('');\r\n setStep('code');\r\n generateMutation.reset();\r\n confirmMutation.reset();\r\n };\r\n\r\n return {\r\n code,\r\n setCode,\r\n isCodeComplete,\r\n isGenerating: generateMutation.isPending,\r\n isConfirming: confirmMutation.isPending,\r\n generateFailed,\r\n retryGenerate: triggerGenerate,\r\n qrcode: generateMutation.data?.qrcode,\r\n backupCodes: generateMutation.data?.backupCodes ?? [],\r\n step,\r\n handleSubmit,\r\n handleFinalize,\r\n handleCopyCodes,\r\n resetForm,\r\n };\r\n}\r\n"],"mappings":";AA4BU;AA1BV,SAAS,UAAU,aAAa,iBAAiB;AACjD,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AASQ,SAAR,qBAAsC,EAAE,WAAW,KAAK,IAA+B,CAAC,GAAG;AAChG,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAe,MAAM;AAE7C,QAAM,mBAAmB,YAAY;AAAA,IACnC,YAAY;AAAA,IACZ,WAAW,CAAC,WAAW;AACrB,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAS,OAAO,SAAS,2CAA2C,SAAS,GAAG,CACxG;AAAA,MACH;AAAA,IACF;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,2CAA0C,SAAS,GAAG,CACtF;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,YAAY;AAAA,IAClC,YAAY,CAAC,YAAoB,uBAAuB,OAAO;AAAA,IAC/D,WAAW,CAAC,WAAW;AACrB,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAS,OAAO,SAAS,yBAAmB,SAAS,GAAG,CAChF;AACD;AAAA,MACF;AACA,cAAQ,UAAU;AAAA,IACpB;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,iDAA6C,SAAS,GAAG,CACzF;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,EAAE,QAAQ,gBAAgB,IAAI;AAEpC,YAAU,MAAM;AACd,QAAI,MAAM;AACR,sBAAgB;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,MAAM,eAAe,CAAC;AAE1B,QAAM,iBACH,iBAAiB,aAAa,CAAC,iBAAiB,MAAM,WAAY,iBAAiB;AAEtF,QAAM,iBAAiB,KAAK,WAAW;AAEvC,QAAM,eAAe,MAAM;AACzB,QAAI,CAAC,eAAgB;AACrB,oBAAgB,OAAO,IAAI;AAAA,EAC7B;AAEA,QAAM,iBAAiB,MAAM;AAC3B,gBAAY;AACZ,eAAW,WAAW,GAAG;AAAA,EAC3B;AAEA,QAAM,kBAAkB,YAAY,YAAY;AAC9C,UAAM,QAAQ,iBAAiB,MAAM,eAAe,CAAC;AACrD,UAAM,UAAU,MAAM,gBAAgB,MAAM,KAAK,IAAI,CAAC;AACtD,QAAI,SAAS;AACX,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAQ,mCAA+B,SAAS,GAAG,CAC7E;AAAA,IACH;AAAA,EACF,GAAG,CAAC,iBAAiB,IAAI,CAAC;AAE1B,QAAM,YAAY,MAAM;AACtB,YAAQ,EAAE;AACV,YAAQ,MAAM;AACd,qBAAiB,MAAM;AACvB,oBAAgB,MAAM;AAAA,EACxB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,cAAc,gBAAgB;AAAA,IAC9B;AAAA,IACA,eAAe;AAAA,IACf,QAAQ,iBAAiB,MAAM;AAAA,IAC/B,aAAa,iBAAiB,MAAM,eAAe,CAAC;AAAA,IACpD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronLeft, X, Mail } from "lucide-react";
|
|
4
|
+
import { Button } from "../../ui/buttons/Button";
|
|
5
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../../ui/overlay/Dialog";
|
|
6
|
+
import { Separator } from "../../ui/data-display/Separator";
|
|
7
|
+
import { InputOTP, InputOTPGroup, InputOTPSlot } from "../../ui/form/InputOtp";
|
|
8
|
+
import { FormField } from "../../ui/form/FormField";
|
|
9
|
+
import { formatTimer } from "../../../utils/format/masks";
|
|
10
|
+
import { OTP_CODE_LENGTH } from "../../../utils/validators/account";
|
|
11
|
+
import { useAuth } from "../../../providers/auth.provider";
|
|
12
|
+
import { useInvalidateUser } from "../../../modules/auth/hooks/useUserQuery";
|
|
13
|
+
import { confirmEmailChangeAction } from "../../../modules/accounts/actions/account-management.action";
|
|
14
|
+
import useChangeEmailForm from "../hooks/useChangeEmailForm";
|
|
15
|
+
import useOtpVerification from "../hooks/useOtpVerification";
|
|
16
|
+
function ChangeEmailModal({ open, onClose }) {
|
|
17
|
+
const { user } = useAuth();
|
|
18
|
+
const invalidateUser = useInvalidateUser();
|
|
19
|
+
const {
|
|
20
|
+
showVerification,
|
|
21
|
+
emailToVerify,
|
|
22
|
+
isSubmitting,
|
|
23
|
+
errors,
|
|
24
|
+
register,
|
|
25
|
+
handleContinue,
|
|
26
|
+
handleBack,
|
|
27
|
+
resetForm
|
|
28
|
+
} = useChangeEmailForm();
|
|
29
|
+
const handleSuccess = () => {
|
|
30
|
+
invalidateUser();
|
|
31
|
+
resetForm();
|
|
32
|
+
onClose();
|
|
33
|
+
};
|
|
34
|
+
const {
|
|
35
|
+
code,
|
|
36
|
+
isLoading,
|
|
37
|
+
hasError,
|
|
38
|
+
timer,
|
|
39
|
+
canResend,
|
|
40
|
+
isValidLength,
|
|
41
|
+
handleCodeChange,
|
|
42
|
+
handleValidate,
|
|
43
|
+
handleResend,
|
|
44
|
+
reset: resetOtp
|
|
45
|
+
} = useOtpVerification({
|
|
46
|
+
onSuccess: handleSuccess,
|
|
47
|
+
successMessage: "E-mail alterado com sucesso",
|
|
48
|
+
validateFn: async (token) => {
|
|
49
|
+
const result = await confirmEmailChangeAction(token, emailToVerify);
|
|
50
|
+
return result.success;
|
|
51
|
+
},
|
|
52
|
+
resendFn: async () => {
|
|
53
|
+
const { requestEmailChangeAction } = await import("../../../modules/accounts/actions/account-management.action");
|
|
54
|
+
const result = await requestEmailChangeAction(emailToVerify);
|
|
55
|
+
if (!result.success) {
|
|
56
|
+
throw new Error(result.error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const handleClose = () => {
|
|
61
|
+
resetForm();
|
|
62
|
+
resetOtp();
|
|
63
|
+
onClose();
|
|
64
|
+
};
|
|
65
|
+
const handleBackFromVerification = () => {
|
|
66
|
+
resetOtp();
|
|
67
|
+
handleBack();
|
|
68
|
+
};
|
|
69
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(
|
|
70
|
+
DialogContent,
|
|
71
|
+
{
|
|
72
|
+
showCloseButton: false,
|
|
73
|
+
className: "flex flex-col p-0 gap-0 max-w-full! border-0 rounded-t-2xl rounded-b-none h-dvh top-0! bottom-0! left-0! right-0! translate-x-0! translate-y-0! lg:max-w-125! lg:h-auto! lg:rounded-lg lg:border lg:top-[50%]! lg:left-[50%]! lg:right-auto! lg:bottom-auto! lg:translate-x-[-50%]! lg:translate-y-[-50%]!",
|
|
74
|
+
children: [
|
|
75
|
+
showVerification ? /* @__PURE__ */ jsxs(DialogHeader, { className: "flex flex-row items-center justify-between px-4 py-3 border-b border-gray-200 lg:border-b-0", children: [
|
|
76
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", className: "size-8! p-0", onClick: handleBackFromVerification, children: /* @__PURE__ */ jsx(ChevronLeft, { size: 20, className: "text-gray-950" }) }),
|
|
77
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "paragraph-medium-semibold text-gray-950 text-center flex-1", children: "Alterar e-mail" }),
|
|
78
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", className: "size-8! p-0", onClick: handleClose, children: /* @__PURE__ */ jsx(X, { size: 18, className: "text-gray-500" }) })
|
|
79
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
80
|
+
/* @__PURE__ */ jsx(DialogHeader, { className: "sr-only", children: /* @__PURE__ */ jsx(DialogTitle, { children: "Alterar e-mail" }) }),
|
|
81
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0", children: [
|
|
82
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-medium-semibold text-gray-950 text-center", children: "Alterar e-mail" }),
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
Button,
|
|
85
|
+
{
|
|
86
|
+
variant: "ghost",
|
|
87
|
+
className: "absolute right-2 size-8! p-0",
|
|
88
|
+
onClick: handleClose,
|
|
89
|
+
children: /* @__PURE__ */ jsx(X, { size: 18, className: "text-gray-500" })
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
] })
|
|
93
|
+
] }),
|
|
94
|
+
/* @__PURE__ */ jsx("div", { className: `${showVerification ? "w-full" : "w-1/2"} h-0.75 bg-pages-300` }),
|
|
95
|
+
showVerification ? /* @__PURE__ */ jsxs(
|
|
96
|
+
"form",
|
|
97
|
+
{
|
|
98
|
+
onSubmit: (e) => {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
handleValidate();
|
|
101
|
+
},
|
|
102
|
+
className: "flex flex-col flex-1 lg:flex-none",
|
|
103
|
+
children: [
|
|
104
|
+
/* @__PURE__ */ jsxs("div", { className: "px-4 lg:px-5 py-5 lg:py-6 flex flex-col gap-4 flex-1 lg:flex-none", children: [
|
|
105
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center size-12 bg-white rounded-lg shadow-xs border border-gray-200", children: /* @__PURE__ */ jsx(Mail, { size: 20, className: "text-gray-950" }) }),
|
|
106
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
107
|
+
/* @__PURE__ */ jsx("h3", { className: "paragraph-medium-semibold text-gray-950", children: "C\xF3digo de valida\xE7\xE3o" }),
|
|
108
|
+
/* @__PURE__ */ jsxs("p", { className: "paragraph-small-regular text-gray-600", children: [
|
|
109
|
+
"Enviamos um c\xF3digo de valida\xE7\xE3o para o E-mail",
|
|
110
|
+
" ",
|
|
111
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold text-gray-950 break-all", children: [
|
|
112
|
+
user?.email,
|
|
113
|
+
"."
|
|
114
|
+
] })
|
|
115
|
+
] })
|
|
116
|
+
] }),
|
|
117
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
118
|
+
/* @__PURE__ */ jsx(InputOTP, { maxLength: OTP_CODE_LENGTH, value: code, onChange: handleCodeChange, children: /* @__PURE__ */ jsx(InputOTPGroup, { className: "flex flex-row gap-2", children: [...Array(OTP_CODE_LENGTH)].map((_, i) => /* @__PURE__ */ jsx(
|
|
119
|
+
InputOTPSlot,
|
|
120
|
+
{
|
|
121
|
+
index: i,
|
|
122
|
+
className: `uppercase text-2xl font-medium w-11 lg:w-12 h-13 lg:h-14 rounded-lg border bg-white shadow-none [&_div.animate-caret-blink]:bg-gray-950 ${hasError ? "border-red-500" : "border-gray-200"}`
|
|
123
|
+
},
|
|
124
|
+
i
|
|
125
|
+
)) }) }),
|
|
126
|
+
hasError && /* @__PURE__ */ jsx("p", { className: "paragraph-small-regular text-red-500", children: "C\xF3digo incorreto" })
|
|
127
|
+
] }),
|
|
128
|
+
canResend ? /* @__PURE__ */ jsx(
|
|
129
|
+
"button",
|
|
130
|
+
{
|
|
131
|
+
type: "button",
|
|
132
|
+
onClick: handleResend,
|
|
133
|
+
className: "paragraph-small-medium text-gray-950 underline cursor-pointer hover:text-gray-700 w-fit",
|
|
134
|
+
children: "Reenviar c\xF3digo"
|
|
135
|
+
}
|
|
136
|
+
) : /* @__PURE__ */ jsxs("p", { className: "paragraph-small-regular text-gray-500", children: [
|
|
137
|
+
"Reenviar em",
|
|
138
|
+
" ",
|
|
139
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-gray-950", children: formatTimer(timer) })
|
|
140
|
+
] })
|
|
141
|
+
] }),
|
|
142
|
+
/* @__PURE__ */ jsx(Separator, {}),
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 lg:px-5 py-4 lg:py-5 mt-auto lg:mt-0", children: [
|
|
144
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "h-10!", type: "button", onClick: handleClose, children: "Cancelar" }),
|
|
145
|
+
/* @__PURE__ */ jsx(Button, { className: "h-10!", type: "submit", disabled: !isValidLength || isLoading, children: isLoading ? "Validando..." : "Alterar e-mail" })
|
|
146
|
+
] })
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
) : /* @__PURE__ */ jsxs("form", { onSubmit: handleContinue, className: "flex flex-col flex-1 lg:flex-none", children: [
|
|
150
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none", children: [
|
|
151
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
152
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-medium-semibold text-gray-950", children: "Atualizar E-mail de contato" }),
|
|
153
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-small-regular text-gray-600", children: "Informe o seu novo E-mail para manter seu contato atualizado." })
|
|
154
|
+
] }),
|
|
155
|
+
/* @__PURE__ */ jsx(
|
|
156
|
+
FormField,
|
|
157
|
+
{
|
|
158
|
+
label: "Novo e-mail",
|
|
159
|
+
placeholder: "Digite seu novo e-mail",
|
|
160
|
+
type: "email",
|
|
161
|
+
...register("email"),
|
|
162
|
+
error: !!errors.email,
|
|
163
|
+
errorMessage: errors.email?.message,
|
|
164
|
+
leftIcon: Mail
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
] }),
|
|
168
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0", children: [
|
|
169
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "h-10!", type: "button", onClick: handleClose, children: "Cancelar" }),
|
|
170
|
+
/* @__PURE__ */ jsx(Button, { className: "h-10!", type: "submit", disabled: isSubmitting, children: isSubmitting ? "Enviando..." : "Continuar" })
|
|
171
|
+
] })
|
|
172
|
+
] })
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
) });
|
|
176
|
+
}
|
|
177
|
+
export {
|
|
178
|
+
ChangeEmailModal
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=ChangeEmailModal.mjs.map
|