@greatapps/common 1.1.676 → 1.1.677
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 +8 -6
- package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -1
- package/dist/components/account/ConfirmDeleteAccountModal.mjs +20 -19
- package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/ConfirmGlobalPreferencesModal.mjs +10 -11
- package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -1
- package/dist/components/account/DeleteAccountModal.mjs +34 -28
- package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/DisableTwoFactorAuthModal.mjs +7 -5
- package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/IsntPossibleDeleteAccountModal.mjs +8 -9
- package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/TwoFactorAuthModal.mjs +22 -23
- package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/constants.mjs +4 -4
- package/dist/components/account/constants.mjs.map +1 -1
- package/dist/components/account/hooks/useChangeEmailForm.mjs +5 -3
- package/dist/components/account/hooks/useChangeEmailForm.mjs.map +1 -1
- package/dist/components/account/hooks/useChangePasswordForm.mjs +26 -3
- package/dist/components/account/hooks/useChangePasswordForm.mjs.map +1 -1
- package/dist/components/account/hooks/useChangePhoneForm.mjs +18 -9
- package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
- package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs +26 -3
- package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs.map +1 -1
- package/dist/components/account/hooks/useOtpVerification.mjs +19 -3
- package/dist/components/account/hooks/useOtpVerification.mjs.map +1 -1
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs +27 -4
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
- package/dist/components/account/sections/ChangeEmailModal.mjs +25 -28
- package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
- package/dist/components/account/sections/ChangePasswordSection.mjs +8 -6
- package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
- package/dist/components/account/sections/ChangePhoneModal.mjs +24 -27
- package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
- package/dist/components/account/sections/MyProfileSection.mjs +37 -22
- package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
- package/dist/components/account/sections/PreferencesSection.mjs +48 -24
- package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
- package/dist/components/account/sections/SecuritySection.mjs +11 -9
- package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
- package/dist/components/account/sections/TokenSection.mjs +24 -8
- package/dist/components/account/sections/TokenSection.mjs.map +1 -1
- package/dist/components/layouts/AppMobileNavBar.mjs +2 -148
- package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
- package/dist/components/layouts/NavBar.mjs +5 -3
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/components/layouts/NotificationsPopover.mjs +5 -3
- package/dist/components/layouts/NotificationsPopover.mjs.map +1 -1
- package/dist/components/layouts/ProfilePopover.mjs +6 -4
- package/dist/components/layouts/ProfilePopover.mjs.map +1 -1
- package/dist/components/layouts/UsersSelectorPopover.mjs +9 -7
- package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
- package/dist/components/modals/BuyCreditsModal.mjs +17 -18
- package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
- package/dist/components/modals/CreditsDisabledModal.mjs +6 -4
- package/dist/components/modals/CreditsDisabledModal.mjs.map +1 -1
- package/dist/components/modals/PaidPlanRequiredModal.mjs +5 -3
- package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
- package/dist/components/modals/cards/AddCardModal.mjs +64 -46
- package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CannotDeleteCardModal.mjs +9 -7
- package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CardFormFields.mjs +65 -51
- package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
- package/dist/components/modals/cards/DeleteCardModal.mjs +10 -8
- package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs +4 -2
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
- package/dist/components/navigation/OverdueInvoiceBanner.mjs +4 -2
- package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/PendingCancellationBanner.mjs +4 -6
- package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
- package/dist/components/navigation/ProjectSelectorPopover.mjs +8 -6
- package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
- package/dist/components/navigation/UpcomingInvoiceBanner.mjs +4 -6
- package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/BottomLinks.mjs +5 -3
- package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/CreditsCard.mjs +3 -1
- package/dist/components/navigation/subcomponents/CreditsCard.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/PlanCard.mjs +3 -1
- package/dist/components/navigation/subcomponents/PlanCard.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/ProjectSelector.mjs +5 -3
- package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
- package/dist/components/pages/NotFoundPage.mjs +5 -3
- package/dist/components/pages/NotFoundPage.mjs.map +1 -1
- package/dist/components/pages/notifications/Notifications.mjs +13 -10
- package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
- package/dist/components/ui/buttons/CopyButton.mjs +9 -5
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
- package/dist/components/ui/data-display/CardItem.mjs +7 -5
- package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
- package/dist/components/ui/data-display/PaymentInfoCard.mjs +10 -8
- package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
- package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs +3 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
- package/dist/components/ui/form/ComboboxField.mjs +11 -6
- package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
- package/dist/components/ui/form/DatePicker.mjs +5 -2
- package/dist/components/ui/form/DatePicker.mjs.map +1 -1
- package/dist/components/ui/form/DateRangePicker.mjs +5 -2
- package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
- package/dist/components/ui/form/PhoneInput.mjs +5 -3
- package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
- package/dist/components/ui/form/SelectField.mjs +6 -3
- package/dist/components/ui/form/SelectField.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageCropModal.mjs +11 -18
- package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs +6 -15
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
- package/dist/i18n/config.mjs +13 -0
- package/dist/i18n/config.mjs.map +1 -0
- package/dist/i18n/country-language.mjs +74 -0
- package/dist/i18n/country-language.mjs.map +1 -0
- package/dist/i18n/messages/en-us.mjs +494 -0
- package/dist/i18n/messages/en-us.mjs.map +1 -0
- package/dist/i18n/messages/es-es.mjs +494 -0
- package/dist/i18n/messages/es-es.mjs.map +1 -0
- package/dist/i18n/messages/index.mjs +16 -0
- package/dist/i18n/messages/index.mjs.map +1 -0
- package/dist/i18n/messages/pt-br.mjs +507 -0
- package/dist/i18n/messages/pt-br.mjs.map +1 -0
- package/dist/i18n/normalize.mjs +12 -0
- package/dist/i18n/normalize.mjs.map +1 -0
- package/dist/i18n/resolve-locale.mjs +42 -0
- package/dist/i18n/resolve-locale.mjs.map +1 -0
- package/dist/i18n.mjs +14 -0
- package/dist/i18n.mjs.map +1 -0
- package/dist/index.mjs +19 -3
- package/dist/index.mjs.map +1 -1
- package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs +20 -0
- package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -0
- package/dist/modules/cards/hooks/handle-delete-card.hook.mjs +2 -1
- package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
- package/dist/modules/images/utils/validate-image.mjs +8 -8
- package/dist/modules/images/utils/validate-image.mjs.map +1 -1
- package/dist/modules/plans/hooks/list-plans.hook.mjs +2 -2
- package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
- package/dist/modules/plans/services/plans.service.mjs +1 -1
- package/dist/modules/plans/services/plans.service.mjs.map +1 -1
- package/dist/modules/plans/types/plan.type.mjs +5 -1
- package/dist/modules/plans/types/plan.type.mjs.map +1 -1
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs +61 -35
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
- package/dist/modules/projects/services/projects.service.mjs +9 -0
- package/dist/modules/projects/services/projects.service.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/periodicity.mjs +20 -14
- package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
- package/dist/providers/auth.provider.mjs +9 -1
- package/dist/providers/auth.provider.mjs.map +1 -1
- package/dist/server.mjs +2 -0
- package/dist/server.mjs.map +1 -1
- package/dist/utils/format/currency.mjs +32 -4
- package/dist/utils/format/currency.mjs.map +1 -1
- package/dist/utils/intl/cookie-domain.mjs +17 -0
- package/dist/utils/intl/cookie-domain.mjs.map +1 -0
- package/dist/utils/intl/locale-cookie.mjs +13 -0
- package/dist/utils/intl/locale-cookie.mjs.map +1 -0
- package/dist/utils/intl/locales.mjs +3 -2
- package/dist/utils/intl/locales.mjs.map +1 -1
- package/package.json +7 -1
- package/src/components/account/ConfigurationsMyAccountModal.tsx +10 -6
- package/src/components/account/ConfirmDeleteAccountModal.tsx +22 -13
- package/src/components/account/ConfirmGlobalPreferencesModal.tsx +12 -10
- package/src/components/account/DeleteAccountModal.tsx +34 -24
- package/src/components/account/DisableTwoFactorAuthModal.tsx +11 -6
- package/src/components/account/IsntPossibleDeleteAccountModal.tsx +8 -6
- package/src/components/account/TwoFactorAuthModal.tsx +33 -29
- package/src/components/account/constants.ts +8 -5
- package/src/components/account/hooks/useChangeEmailForm.tsx +5 -3
- package/src/components/account/hooks/useChangePasswordForm.tsx +20 -6
- package/src/components/account/hooks/useChangePhoneForm.tsx +16 -10
- package/src/components/account/hooks/useDisableTwoFactorAuthForm.tsx +20 -6
- package/src/components/account/hooks/useOtpVerification.tsx +16 -4
- package/src/components/account/hooks/useTwoFactorAuthForm.tsx +21 -7
- package/src/components/account/sections/ChangeEmailModal.tsx +35 -21
- package/src/components/account/sections/ChangePasswordSection.tsx +10 -6
- package/src/components/account/sections/ChangePhoneModal.tsx +50 -22
- package/src/components/account/sections/MyProfileSection.tsx +37 -23
- package/src/components/account/sections/PreferencesSection.tsx +52 -25
- package/src/components/account/sections/SecuritySection.tsx +19 -10
- package/src/components/account/sections/TokenSection.tsx +22 -10
- package/src/components/layouts/AppMobileNavBar.tsx +1 -154
- package/src/components/layouts/NavBar.tsx +5 -3
- package/src/components/layouts/NotificationsPopover.tsx +5 -3
- package/src/components/layouts/ProfilePopover.tsx +6 -4
- package/src/components/layouts/UsersSelectorPopover.tsx +9 -7
- package/src/components/modals/BuyCreditsModal.tsx +18 -16
- package/src/components/modals/CreditsDisabledModal.tsx +6 -6
- package/src/components/modals/PaidPlanRequiredModal.tsx +5 -3
- package/src/components/modals/cards/AddCardModal.tsx +89 -62
- package/src/components/modals/cards/CannotDeleteCardModal.tsx +9 -8
- package/src/components/modals/cards/CardFormFields.tsx +93 -75
- package/src/components/modals/cards/DeleteCardModal.tsx +10 -8
- package/src/components/navigation/CancelledSubscriptionBanner.tsx +4 -2
- package/src/components/navigation/OverdueInvoiceBanner.tsx +4 -2
- package/src/components/navigation/PendingCancellationBanner.tsx +4 -2
- package/src/components/navigation/ProjectSelectorPopover.tsx +8 -6
- package/src/components/navigation/UpcomingInvoiceBanner.tsx +4 -2
- package/src/components/navigation/subcomponents/BottomLinks.tsx +5 -3
- package/src/components/navigation/subcomponents/CreditsCard.tsx +3 -1
- package/src/components/navigation/subcomponents/PlanCard.tsx +3 -1
- package/src/components/navigation/subcomponents/ProjectSelector.tsx +5 -3
- package/src/components/pages/NotFoundPage.tsx +5 -3
- package/src/components/pages/notifications/Notifications.tsx +13 -10
- package/src/components/ui/buttons/CopyButton.tsx +10 -5
- package/src/components/ui/data-display/CardItem.tsx +7 -5
- package/src/components/ui/data-display/PaymentInfoCard.tsx +10 -8
- package/src/components/ui/feedback/CircularProgress.tsx +4 -0
- package/src/components/ui/feedback/DefaultCircularProgress.tsx +3 -1
- package/src/components/ui/form/ComboboxField.tsx +11 -6
- package/src/components/ui/form/DatePicker.tsx +5 -2
- package/src/components/ui/form/DateRangePicker.tsx +5 -2
- package/src/components/ui/form/PhoneInput.tsx +5 -3
- package/src/components/ui/form/SelectField.tsx +6 -3
- package/src/components/widgets/ImageUpload/ImageCropModal.tsx +19 -11
- package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +6 -5
- package/src/i18n/config.ts +17 -0
- package/src/i18n/country-language.ts +60 -0
- package/src/i18n/messages/en-us.ts +514 -0
- package/src/i18n/messages/es-es.ts +515 -0
- package/src/i18n/messages/index.ts +24 -0
- package/src/i18n/messages/pt-br.ts +538 -0
- package/src/i18n/normalize.ts +15 -0
- package/src/i18n/resolve-locale.ts +77 -0
- package/src/i18n.ts +10 -0
- package/src/index.ts +13 -2
- package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -0
- package/src/modules/cards/hooks/handle-delete-card.hook.ts +8 -3
- package/src/modules/images/utils/validate-image.ts +23 -8
- package/src/modules/plans/hooks/list-plans.hook.ts +2 -2
- package/src/modules/plans/services/plans.service.ts +1 -1
- package/src/modules/plans/types/plan.type.ts +4 -0
- package/src/modules/plans/utils/map-api-plan-to-ui.ts +109 -47
- package/src/modules/projects/services/projects.service.ts +12 -0
- package/src/modules/subscriptions/utils/periodicity.ts +29 -12
- package/src/providers/auth.provider.tsx +13 -1
- package/src/server.ts +2 -0
- package/src/utils/format/currency.ts +62 -7
- package/src/utils/intl/cookie-domain.ts +29 -0
- package/src/utils/intl/locale-cookie.ts +18 -0
- package/src/utils/intl/locales.ts +3 -2
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
import { useState, useCallback } from 'react';
|
|
4
4
|
import { useForm } from 'react-hook-form';
|
|
5
5
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
6
|
+
import { useTranslations } from 'next-intl';
|
|
6
7
|
import { toast } from 'sonner';
|
|
7
8
|
import { Toast } from '../../ui/feedback/Toast';
|
|
8
9
|
import { changeEmailSchema, type ChangeEmailFormData } from '../../../utils/validators/account';
|
|
9
10
|
import { requestEmailChangeAction } from '../../../modules/accounts/actions/account-management.action';
|
|
10
11
|
|
|
11
12
|
export default function useChangeEmailForm() {
|
|
13
|
+
const translate = useTranslations();
|
|
12
14
|
const [showVerification, setShowVerification] = useState(false);
|
|
13
15
|
|
|
14
16
|
const { register, handleSubmit, reset, watch, formState: { errors, isSubmitting } } = useForm<ChangeEmailFormData>({
|
|
@@ -21,11 +23,11 @@ export default function useChangeEmailForm() {
|
|
|
21
23
|
const result = await requestEmailChangeAction(data.email);
|
|
22
24
|
|
|
23
25
|
if (!result.success) {
|
|
24
|
-
toast.custom((
|
|
26
|
+
toast.custom((toastId) => (
|
|
25
27
|
<Toast
|
|
26
28
|
variant="error"
|
|
27
|
-
message={result.error ?? '
|
|
28
|
-
toastId={
|
|
29
|
+
message={result.error ?? translate('common.account.changeEmail.emailExistsError')}
|
|
30
|
+
toastId={toastId}
|
|
29
31
|
/>
|
|
30
32
|
));
|
|
31
33
|
return;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useForm } from 'react-hook-form';
|
|
4
4
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
5
5
|
import { useMutation } from '@tanstack/react-query';
|
|
6
|
+
import { useTranslations } from 'next-intl';
|
|
6
7
|
import { toast } from 'sonner';
|
|
7
8
|
import { Toast } from '../../ui/feedback/Toast';
|
|
8
9
|
import { changePasswordSchema, type ChangePasswordFormData } from '../../../utils/validators/account';
|
|
@@ -13,6 +14,7 @@ interface UseChangePasswordFormProps {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export default function useChangePasswordForm({ onSuccess }: UseChangePasswordFormProps = {}) {
|
|
17
|
+
const translate = useTranslations();
|
|
16
18
|
const form = useForm<ChangePasswordFormData>({
|
|
17
19
|
resolver: zodResolver(changePasswordSchema),
|
|
18
20
|
mode: 'onChange',
|
|
@@ -26,22 +28,34 @@ export default function useChangePasswordForm({ onSuccess }: UseChangePasswordFo
|
|
|
26
28
|
mutationFn: changePasswordAction,
|
|
27
29
|
onSuccess: (result) => {
|
|
28
30
|
if (!result.success) {
|
|
29
|
-
toast.custom((
|
|
30
|
-
<Toast
|
|
31
|
+
toast.custom((toastId) => (
|
|
32
|
+
<Toast
|
|
33
|
+
variant="error"
|
|
34
|
+
message={result.error ?? translate('common.account.changePassword.changeError')}
|
|
35
|
+
toastId={toastId}
|
|
36
|
+
/>
|
|
31
37
|
));
|
|
32
38
|
return;
|
|
33
39
|
}
|
|
34
40
|
|
|
35
|
-
toast.custom((
|
|
36
|
-
<Toast
|
|
41
|
+
toast.custom((toastId) => (
|
|
42
|
+
<Toast
|
|
43
|
+
variant="success"
|
|
44
|
+
message={translate('common.account.changePassword.changedSuccess')}
|
|
45
|
+
toastId={toastId}
|
|
46
|
+
/>
|
|
37
47
|
));
|
|
38
48
|
|
|
39
49
|
form.reset();
|
|
40
50
|
onSuccess?.();
|
|
41
51
|
},
|
|
42
52
|
onError: () => {
|
|
43
|
-
toast.custom((
|
|
44
|
-
<Toast
|
|
53
|
+
toast.custom((toastId) => (
|
|
54
|
+
<Toast
|
|
55
|
+
variant="error"
|
|
56
|
+
message={translate('common.account.changePassword.genericError')}
|
|
57
|
+
toastId={toastId}
|
|
58
|
+
/>
|
|
45
59
|
));
|
|
46
60
|
},
|
|
47
61
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useCallback } from 'react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import { toast } from 'sonner';
|
|
5
6
|
import { Toast } from '../../ui/feedback/Toast';
|
|
6
7
|
import { requestPhoneChangeAction, updateUserAction } from '../../../modules/accounts/actions/account-management.action';
|
|
@@ -18,6 +19,7 @@ interface UseChangePhoneFormOptions {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export default function useChangePhoneForm({ hasExistingPhone, onDirectUpdateSuccess }: UseChangePhoneFormOptions) {
|
|
22
|
+
const translate = useTranslations();
|
|
21
23
|
const [showVerification, setShowVerification] = useState(false);
|
|
22
24
|
const [phoneValue, setPhoneValue] = useState('');
|
|
23
25
|
const [phoneError, setPhoneError] = useState('');
|
|
@@ -35,7 +37,7 @@ export default function useChangePhoneForm({ hasExistingPhone, onDirectUpdateSuc
|
|
|
35
37
|
const { ddi, local } = splitPhoneValue(phoneValue);
|
|
36
38
|
|
|
37
39
|
if (!local || local.replace(/\D/g, '').length < 8) {
|
|
38
|
-
setPhoneError('
|
|
40
|
+
setPhoneError(translate('common.account.changePhone.invalidNumber'));
|
|
39
41
|
return;
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -45,18 +47,22 @@ export default function useChangePhoneForm({ hasExistingPhone, onDirectUpdateSuc
|
|
|
45
47
|
const result = await updateUserAction({ phone: local, ddi });
|
|
46
48
|
|
|
47
49
|
if (!result.success) {
|
|
48
|
-
toast.custom((
|
|
50
|
+
toast.custom((toastId) => (
|
|
49
51
|
<Toast
|
|
50
52
|
variant="error"
|
|
51
|
-
message={result.error ?? '
|
|
52
|
-
toastId={
|
|
53
|
+
message={result.error ?? translate('common.account.changePhone.saveError')}
|
|
54
|
+
toastId={toastId}
|
|
53
55
|
/>
|
|
54
56
|
));
|
|
55
57
|
return;
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
toast.custom((
|
|
59
|
-
<Toast
|
|
60
|
+
toast.custom((toastId) => (
|
|
61
|
+
<Toast
|
|
62
|
+
variant="success"
|
|
63
|
+
message={translate('common.account.changePhone.phoneAdded')}
|
|
64
|
+
toastId={toastId}
|
|
65
|
+
/>
|
|
60
66
|
));
|
|
61
67
|
onDirectUpdateSuccess?.();
|
|
62
68
|
return;
|
|
@@ -65,11 +71,11 @@ export default function useChangePhoneForm({ hasExistingPhone, onDirectUpdateSuc
|
|
|
65
71
|
const result = await requestPhoneChangeAction(local, ddi);
|
|
66
72
|
|
|
67
73
|
if (!result.success) {
|
|
68
|
-
toast.custom((
|
|
74
|
+
toast.custom((toastId) => (
|
|
69
75
|
<Toast
|
|
70
76
|
variant="error"
|
|
71
|
-
message={result.error ?? '
|
|
72
|
-
toastId={
|
|
77
|
+
message={result.error ?? translate('common.account.changePhone.numberExistsError')}
|
|
78
|
+
toastId={toastId}
|
|
73
79
|
/>
|
|
74
80
|
));
|
|
75
81
|
return;
|
|
@@ -80,7 +86,7 @@ export default function useChangePhoneForm({ hasExistingPhone, onDirectUpdateSuc
|
|
|
80
86
|
} finally {
|
|
81
87
|
setIsSubmitting(false);
|
|
82
88
|
}
|
|
83
|
-
}, [phoneValue, hasExistingPhone, onDirectUpdateSuccess]);
|
|
89
|
+
}, [phoneValue, hasExistingPhone, onDirectUpdateSuccess, translate]);
|
|
84
90
|
|
|
85
91
|
const handleBack = useCallback(() => {
|
|
86
92
|
setShowVerification(false);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useState, useCallback } from 'react';
|
|
4
4
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
5
|
+
import { useTranslations } from 'next-intl';
|
|
5
6
|
import { toast } from 'sonner';
|
|
6
7
|
import { Toast } from '../../ui/feedback/Toast';
|
|
7
8
|
import { USER_QUERY_KEY } from '../../../modules/auth/hooks/useUserQuery';
|
|
@@ -17,6 +18,7 @@ export default function useDisableTwoFactorAuthForm({
|
|
|
17
18
|
onClose,
|
|
18
19
|
onSuccess,
|
|
19
20
|
}: UseDisableTwoFactorAuthFormProps) {
|
|
21
|
+
const translate = useTranslations();
|
|
20
22
|
const [code, setCode] = useState('');
|
|
21
23
|
const queryClient = useQueryClient();
|
|
22
24
|
const userKey = useWlQueryKey([...USER_QUERY_KEY]);
|
|
@@ -28,23 +30,35 @@ export default function useDisableTwoFactorAuthForm({
|
|
|
28
30
|
onSuccess: (result) => {
|
|
29
31
|
if (!result.success) {
|
|
30
32
|
setCode('');
|
|
31
|
-
toast.custom((
|
|
32
|
-
<Toast
|
|
33
|
+
toast.custom((toastId) => (
|
|
34
|
+
<Toast
|
|
35
|
+
variant="error"
|
|
36
|
+
message={result.error ?? translate('common.account.twoFactor.invalidCode')}
|
|
37
|
+
toastId={toastId}
|
|
38
|
+
/>
|
|
33
39
|
));
|
|
34
40
|
return;
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
queryClient.invalidateQueries({ queryKey: userKey });
|
|
38
|
-
toast.custom((
|
|
39
|
-
<Toast
|
|
44
|
+
toast.custom((toastId) => (
|
|
45
|
+
<Toast
|
|
46
|
+
variant="success"
|
|
47
|
+
message={translate('common.account.twoFactor.disabledSuccess')}
|
|
48
|
+
toastId={toastId}
|
|
49
|
+
/>
|
|
40
50
|
));
|
|
41
51
|
setCode('');
|
|
42
52
|
onSuccess?.();
|
|
43
53
|
},
|
|
44
54
|
onError: () => {
|
|
45
55
|
setCode('');
|
|
46
|
-
toast.custom((
|
|
47
|
-
<Toast
|
|
56
|
+
toast.custom((toastId) => (
|
|
57
|
+
<Toast
|
|
58
|
+
variant="error"
|
|
59
|
+
message={translate('common.account.twoFactor.disableError')}
|
|
60
|
+
toastId={toastId}
|
|
61
|
+
/>
|
|
48
62
|
));
|
|
49
63
|
},
|
|
50
64
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useCallback } from 'react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import { toast } from 'sonner';
|
|
5
6
|
import { Toast } from '../../ui/feedback/Toast';
|
|
6
7
|
import useCountdownTimer from '../../../hooks/useCountdownTimer';
|
|
@@ -20,6 +21,7 @@ export default function useOtpVerification({
|
|
|
20
21
|
validateFn,
|
|
21
22
|
resendFn,
|
|
22
23
|
}: UseOtpVerificationOptions) {
|
|
24
|
+
const translate = useTranslations();
|
|
23
25
|
const [code, setCode] = useState('');
|
|
24
26
|
const [isLoading, setIsLoading] = useState(false);
|
|
25
27
|
const [hasError, setHasError] = useState(false);
|
|
@@ -85,14 +87,24 @@ export default function useOtpVerification({
|
|
|
85
87
|
await resendFn();
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
toast.custom((
|
|
90
|
+
toast.custom((toastId) => (
|
|
91
|
+
<Toast
|
|
92
|
+
variant="success"
|
|
93
|
+
message={translate('common.account.twoFactor.codeResent')}
|
|
94
|
+
toastId={toastId}
|
|
95
|
+
/>
|
|
96
|
+
));
|
|
89
97
|
} catch (error) {
|
|
90
98
|
console.error('Erro ao reenviar código:', error);
|
|
91
|
-
toast.custom((
|
|
92
|
-
<Toast
|
|
99
|
+
toast.custom((toastId) => (
|
|
100
|
+
<Toast
|
|
101
|
+
variant="error"
|
|
102
|
+
message={translate('common.account.twoFactor.resendError')}
|
|
103
|
+
toastId={toastId}
|
|
104
|
+
/>
|
|
93
105
|
));
|
|
94
106
|
}
|
|
95
|
-
}, [canResend, resetTimer, resendFn]);
|
|
107
|
+
}, [canResend, resetTimer, resendFn, translate]);
|
|
96
108
|
|
|
97
109
|
const reset = useCallback(() => {
|
|
98
110
|
setCode('');
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useState, useCallback, useEffect } from 'react';
|
|
4
4
|
import { useMutation } from '@tanstack/react-query';
|
|
5
|
+
import { useTranslations } from 'next-intl';
|
|
5
6
|
import { toast } from 'sonner';
|
|
6
7
|
import { Toast } from '../../ui/feedback/Toast';
|
|
7
8
|
import { copyToClipboard } from '../../../utils/browser/clipboard';
|
|
@@ -19,14 +20,19 @@ interface UseTwoFactorAuthFormProps {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAuthFormProps = {}) {
|
|
23
|
+
const translate = useTranslations();
|
|
22
24
|
const [code, setCode] = useState('');
|
|
23
25
|
const [step, setStep] = useState<Step>('code');
|
|
24
26
|
|
|
25
27
|
const generateMutation = useMutation({
|
|
26
28
|
mutationFn: withAction(generateTwoFactorAction),
|
|
27
29
|
onError: () => {
|
|
28
|
-
toast.custom((
|
|
29
|
-
<Toast
|
|
30
|
+
toast.custom((toastId) => (
|
|
31
|
+
<Toast
|
|
32
|
+
variant="error"
|
|
33
|
+
message={translate('common.account.twoFactor.generateError')}
|
|
34
|
+
toastId={toastId}
|
|
35
|
+
/>
|
|
30
36
|
));
|
|
31
37
|
},
|
|
32
38
|
});
|
|
@@ -38,8 +44,12 @@ export default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAu
|
|
|
38
44
|
},
|
|
39
45
|
onError: () => {
|
|
40
46
|
setCode('');
|
|
41
|
-
toast.custom((
|
|
42
|
-
<Toast
|
|
47
|
+
toast.custom((toastId) => (
|
|
48
|
+
<Toast
|
|
49
|
+
variant="error"
|
|
50
|
+
message={translate('common.account.twoFactor.confirmError')}
|
|
51
|
+
toastId={toastId}
|
|
52
|
+
/>
|
|
43
53
|
));
|
|
44
54
|
},
|
|
45
55
|
});
|
|
@@ -70,11 +80,15 @@ export default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAu
|
|
|
70
80
|
const codes = generateMutation.data?.backupCodes ?? [];
|
|
71
81
|
const success = await copyToClipboard(codes.join('\n'));
|
|
72
82
|
if (success) {
|
|
73
|
-
toast.custom((
|
|
74
|
-
<Toast
|
|
83
|
+
toast.custom((toastId) => (
|
|
84
|
+
<Toast
|
|
85
|
+
variant="success"
|
|
86
|
+
message={translate('common.account.twoFactor.codesCopied')}
|
|
87
|
+
toastId={toastId}
|
|
88
|
+
/>
|
|
75
89
|
));
|
|
76
90
|
}
|
|
77
|
-
}, [generateMutation.data]);
|
|
91
|
+
}, [generateMutation.data, translate]);
|
|
78
92
|
|
|
79
93
|
const resetForm = () => {
|
|
80
94
|
setCode('');
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
3
4
|
import { IconChevronLeft, IconX, IconMail } from '@tabler/icons-react';
|
|
4
5
|
import { Button } from '../../ui/buttons/Button';
|
|
5
6
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';
|
|
@@ -20,6 +21,7 @@ interface ChangeEmailModalProps {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
24
|
+
const translate = useTranslations();
|
|
23
25
|
const { user } = useAuth();
|
|
24
26
|
const invalidateUser = useInvalidateUser();
|
|
25
27
|
|
|
@@ -53,7 +55,7 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
53
55
|
reset: resetOtp,
|
|
54
56
|
} = useOtpVerification({
|
|
55
57
|
onSuccess: handleSuccess,
|
|
56
|
-
successMessage: '
|
|
58
|
+
successMessage: translate('common.account.changeEmail.emailChanged'),
|
|
57
59
|
validateFn: async (token) => {
|
|
58
60
|
const result = await confirmEmailChangeAction(token, emailToVerify);
|
|
59
61
|
return result.success;
|
|
@@ -91,7 +93,7 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
91
93
|
<IconChevronLeft size={20} className="text-gray-950" />
|
|
92
94
|
</Button>
|
|
93
95
|
<DialogTitle className="paragraph-medium-semibold text-gray-950 text-center flex-1">
|
|
94
|
-
|
|
96
|
+
{translate('common.account.changeEmail.title')}
|
|
95
97
|
</DialogTitle>
|
|
96
98
|
<Button variant="ghost" className="size-8! p-0" onClick={handleClose}>
|
|
97
99
|
<IconX size={18} className="text-gray-500" />
|
|
@@ -100,11 +102,11 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
100
102
|
) : (
|
|
101
103
|
<>
|
|
102
104
|
<DialogHeader className="sr-only">
|
|
103
|
-
<DialogTitle>
|
|
105
|
+
<DialogTitle>{translate('common.account.changeEmail.title')}</DialogTitle>
|
|
104
106
|
</DialogHeader>
|
|
105
107
|
<div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
|
|
106
108
|
<span className="paragraph-medium-semibold text-gray-950 text-center">
|
|
107
|
-
|
|
109
|
+
{translate('common.account.changeEmail.title')}
|
|
108
110
|
</span>
|
|
109
111
|
<Button
|
|
110
112
|
variant="ghost"
|
|
@@ -133,10 +135,16 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
133
135
|
</div>
|
|
134
136
|
|
|
135
137
|
<div className="flex flex-col gap-1">
|
|
136
|
-
<h3 className="paragraph-medium-semibold text-gray-950">
|
|
138
|
+
<h3 className="paragraph-medium-semibold text-gray-950">
|
|
139
|
+
{translate('common.account.otp.validationCode')}
|
|
140
|
+
</h3>
|
|
137
141
|
<p className="paragraph-small-regular text-gray-600">
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
{translate.rich('common.account.changeEmail.sentCodeTo', {
|
|
143
|
+
email: user?.email ?? '',
|
|
144
|
+
b: (chunks) => (
|
|
145
|
+
<span className="font-semibold text-gray-950 break-all">{chunks}</span>
|
|
146
|
+
),
|
|
147
|
+
})}
|
|
140
148
|
</p>
|
|
141
149
|
</div>
|
|
142
150
|
|
|
@@ -153,7 +161,9 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
153
161
|
</InputOTPGroup>
|
|
154
162
|
</InputOTP>
|
|
155
163
|
{hasError && (
|
|
156
|
-
<p className="paragraph-small-regular text-red-500">
|
|
164
|
+
<p className="paragraph-small-regular text-red-500">
|
|
165
|
+
{translate('common.account.otp.incorrectCode')}
|
|
166
|
+
</p>
|
|
157
167
|
)}
|
|
158
168
|
</div>
|
|
159
169
|
|
|
@@ -163,14 +173,16 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
163
173
|
onClick={handleResend}
|
|
164
174
|
className="paragraph-small-medium text-gray-950 underline cursor-pointer hover:text-gray-700 w-fit"
|
|
165
175
|
>
|
|
166
|
-
|
|
176
|
+
{translate('common.account.otp.resend')}
|
|
167
177
|
</button>
|
|
168
178
|
) : (
|
|
169
179
|
<p className="paragraph-small-regular text-gray-500">
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
180
|
+
{translate.rich('common.account.otp.resendIn', {
|
|
181
|
+
time: formatTimer(timer),
|
|
182
|
+
b: (chunks) => (
|
|
183
|
+
<span className="paragraph-small-semibold text-gray-950">{chunks}</span>
|
|
184
|
+
),
|
|
185
|
+
})}
|
|
174
186
|
</p>
|
|
175
187
|
)}
|
|
176
188
|
</div>
|
|
@@ -179,10 +191,12 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
179
191
|
|
|
180
192
|
<div className="flex items-center justify-between px-4 lg:px-5 py-4 lg:py-5 mt-auto lg:mt-0">
|
|
181
193
|
<Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
|
|
182
|
-
|
|
194
|
+
{translate('common.actions.cancel')}
|
|
183
195
|
</Button>
|
|
184
196
|
<Button className="h-10!" type="submit" disabled={!isValidLength || isLoading}>
|
|
185
|
-
{isLoading
|
|
197
|
+
{isLoading
|
|
198
|
+
? translate('common.account.otp.validating')
|
|
199
|
+
: translate('common.account.changeEmail.confirm')}
|
|
186
200
|
</Button>
|
|
187
201
|
</div>
|
|
188
202
|
</form>
|
|
@@ -191,16 +205,16 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
191
205
|
<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">
|
|
192
206
|
<div className="flex flex-col gap-1">
|
|
193
207
|
<span className="paragraph-medium-semibold text-gray-950">
|
|
194
|
-
|
|
208
|
+
{translate('common.account.changeEmail.updateTitle')}
|
|
195
209
|
</span>
|
|
196
210
|
<span className="paragraph-small-regular text-gray-600">
|
|
197
|
-
|
|
211
|
+
{translate('common.account.changeEmail.updateDescription')}
|
|
198
212
|
</span>
|
|
199
213
|
</div>
|
|
200
214
|
|
|
201
215
|
<FormField
|
|
202
|
-
label=
|
|
203
|
-
placeholder=
|
|
216
|
+
label={translate('common.account.changeEmail.newEmail')}
|
|
217
|
+
placeholder={translate('common.account.changeEmail.newEmailPlaceholder')}
|
|
204
218
|
type="email"
|
|
205
219
|
{...register('email')}
|
|
206
220
|
error={!!errors.email}
|
|
@@ -211,10 +225,10 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
211
225
|
|
|
212
226
|
<div className="flex items-center justify-between p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0">
|
|
213
227
|
<Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
|
|
214
|
-
|
|
228
|
+
{translate('common.actions.cancel')}
|
|
215
229
|
</Button>
|
|
216
230
|
<Button className="h-10!" type="submit" disabled={isSubmitting}>
|
|
217
|
-
{isSubmitting ? '
|
|
231
|
+
{isSubmitting ? translate('common.actions.sending') : translate('common.actions.continue')}
|
|
218
232
|
</Button>
|
|
219
233
|
</div>
|
|
220
234
|
</form>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { IconLock, IconX } from '@tabler/icons-react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import { Button } from '../../ui/buttons/Button';
|
|
5
6
|
import { FormField } from '../../ui/form/FormField';
|
|
6
7
|
import useChangePasswordForm from '../hooks/useChangePasswordForm';
|
|
@@ -11,6 +12,7 @@ interface ChangePasswordSectionProps {
|
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export function ChangePasswordSection({ onBack }: ChangePasswordSectionProps) {
|
|
15
|
+
const translate = useTranslations();
|
|
14
16
|
const { register, handleSubmit, errors } = useChangePasswordForm({
|
|
15
17
|
onSuccess: onBack,
|
|
16
18
|
});
|
|
@@ -23,7 +25,9 @@ export function ChangePasswordSection({ onBack }: ChangePasswordSectionProps) {
|
|
|
23
25
|
className="flex-1 overflow-y-auto px-4 pb-5 lg:p-5 flex flex-col h-full lg:h-full gap-5 lg:gap-6"
|
|
24
26
|
>
|
|
25
27
|
<div className="flex items-center justify-between">
|
|
26
|
-
<span className="paragraph-medium-semibold text-gray-950">
|
|
28
|
+
<span className="paragraph-medium-semibold text-gray-950">
|
|
29
|
+
{translate('common.account.changePassword.title')}
|
|
30
|
+
</span>
|
|
27
31
|
<Button type="button" variant="ghost" className="size-8! p-0" onClick={onBack}>
|
|
28
32
|
<IconX size={18} />
|
|
29
33
|
</Button>
|
|
@@ -31,9 +35,9 @@ export function ChangePasswordSection({ onBack }: ChangePasswordSectionProps) {
|
|
|
31
35
|
|
|
32
36
|
<div className="flex flex-col gap-4">
|
|
33
37
|
<FormField
|
|
34
|
-
label=
|
|
38
|
+
label={translate('common.account.changePassword.currentPassword')}
|
|
35
39
|
type="password"
|
|
36
|
-
placeholder=
|
|
40
|
+
placeholder={translate('common.account.changePassword.currentPasswordPlaceholder')}
|
|
37
41
|
leftIcon={IconLock}
|
|
38
42
|
error={!!errors.currentPassword}
|
|
39
43
|
errorMessage={errors.currentPassword?.message}
|
|
@@ -43,9 +47,9 @@ export function ChangePasswordSection({ onBack }: ChangePasswordSectionProps) {
|
|
|
43
47
|
{...register('currentPassword')}
|
|
44
48
|
/>
|
|
45
49
|
<FormField
|
|
46
|
-
label=
|
|
50
|
+
label={translate('common.account.changePassword.newPassword')}
|
|
47
51
|
type="password"
|
|
48
|
-
placeholder=
|
|
52
|
+
placeholder={translate('common.account.changePassword.newPasswordPlaceholder')}
|
|
49
53
|
leftIcon={IconLock}
|
|
50
54
|
error={!!errors.newPassword}
|
|
51
55
|
errorMessage={errors.newPassword?.message}
|
|
@@ -57,7 +61,7 @@ export function ChangePasswordSection({ onBack }: ChangePasswordSectionProps) {
|
|
|
57
61
|
</div>
|
|
58
62
|
|
|
59
63
|
<Button type="submit" className="w-fit h-10!">
|
|
60
|
-
|
|
64
|
+
{translate('common.account.changePassword.submit')}
|
|
61
65
|
</Button>
|
|
62
66
|
</form>
|
|
63
67
|
);
|