@greatapps/common 1.1.666 → 1.1.667

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.
Files changed (103) hide show
  1. package/dist/components/account/ConfigurationsMyAccountModal.mjs +8 -6
  2. package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -1
  3. package/dist/components/account/ConfirmDeleteAccountModal.mjs +20 -19
  4. package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
  5. package/dist/components/account/ConfirmGlobalPreferencesModal.mjs +10 -11
  6. package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -1
  7. package/dist/components/account/DeleteAccountModal.mjs +34 -28
  8. package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
  9. package/dist/components/account/DisableTwoFactorAuthModal.mjs +7 -5
  10. package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
  11. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs +8 -9
  12. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
  13. package/dist/components/account/TwoFactorAuthModal.mjs +22 -23
  14. package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
  15. package/dist/components/account/hooks/useChangeEmailForm.mjs +5 -3
  16. package/dist/components/account/hooks/useChangeEmailForm.mjs.map +1 -1
  17. package/dist/components/account/hooks/useChangePasswordForm.mjs +26 -3
  18. package/dist/components/account/hooks/useChangePasswordForm.mjs.map +1 -1
  19. package/dist/components/account/hooks/useChangePhoneForm.mjs +18 -9
  20. package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
  21. package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs +26 -3
  22. package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs.map +1 -1
  23. package/dist/components/account/hooks/useOtpVerification.mjs +19 -3
  24. package/dist/components/account/hooks/useOtpVerification.mjs.map +1 -1
  25. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs +27 -4
  26. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
  27. package/dist/components/account/sections/ChangeEmailModal.mjs +25 -28
  28. package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
  29. package/dist/components/account/sections/ChangePasswordSection.mjs +8 -6
  30. package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
  31. package/dist/components/account/sections/ChangePhoneModal.mjs +24 -27
  32. package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
  33. package/dist/components/account/sections/MyProfileSection.mjs +30 -21
  34. package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
  35. package/dist/components/account/sections/PreferencesSection.mjs +41 -23
  36. package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
  37. package/dist/components/account/sections/SecuritySection.mjs +11 -9
  38. package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
  39. package/dist/components/account/sections/TokenSection.mjs +24 -8
  40. package/dist/components/account/sections/TokenSection.mjs.map +1 -1
  41. package/dist/i18n/config.mjs +13 -0
  42. package/dist/i18n/config.mjs.map +1 -0
  43. package/dist/i18n/country-language.mjs +74 -0
  44. package/dist/i18n/country-language.mjs.map +1 -0
  45. package/dist/i18n/messages/en-us.mjs +211 -0
  46. package/dist/i18n/messages/en-us.mjs.map +1 -0
  47. package/dist/i18n/messages/es-es.mjs +211 -0
  48. package/dist/i18n/messages/es-es.mjs.map +1 -0
  49. package/dist/i18n/messages/index.mjs +16 -0
  50. package/dist/i18n/messages/index.mjs.map +1 -0
  51. package/dist/i18n/messages/pt-br.mjs +216 -0
  52. package/dist/i18n/messages/pt-br.mjs.map +1 -0
  53. package/dist/i18n/normalize.mjs +12 -0
  54. package/dist/i18n/normalize.mjs.map +1 -0
  55. package/dist/i18n/resolve-locale.mjs +42 -0
  56. package/dist/i18n/resolve-locale.mjs.map +1 -0
  57. package/dist/i18n.mjs +14 -0
  58. package/dist/i18n.mjs.map +1 -0
  59. package/dist/providers/auth.provider.mjs +9 -1
  60. package/dist/providers/auth.provider.mjs.map +1 -1
  61. package/dist/server.mjs +2 -0
  62. package/dist/server.mjs.map +1 -1
  63. package/dist/utils/intl/cookie-domain.mjs +17 -0
  64. package/dist/utils/intl/cookie-domain.mjs.map +1 -0
  65. package/dist/utils/intl/locale-cookie.mjs +13 -0
  66. package/dist/utils/intl/locale-cookie.mjs.map +1 -0
  67. package/dist/utils/intl/locales.mjs +3 -2
  68. package/dist/utils/intl/locales.mjs.map +1 -1
  69. package/package.json +7 -1
  70. package/src/components/account/ConfigurationsMyAccountModal.tsx +10 -6
  71. package/src/components/account/ConfirmDeleteAccountModal.tsx +22 -13
  72. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +12 -10
  73. package/src/components/account/DeleteAccountModal.tsx +34 -24
  74. package/src/components/account/DisableTwoFactorAuthModal.tsx +11 -6
  75. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +8 -6
  76. package/src/components/account/TwoFactorAuthModal.tsx +33 -29
  77. package/src/components/account/hooks/useChangeEmailForm.tsx +5 -3
  78. package/src/components/account/hooks/useChangePasswordForm.tsx +20 -6
  79. package/src/components/account/hooks/useChangePhoneForm.tsx +16 -10
  80. package/src/components/account/hooks/useDisableTwoFactorAuthForm.tsx +20 -6
  81. package/src/components/account/hooks/useOtpVerification.tsx +16 -4
  82. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +21 -7
  83. package/src/components/account/sections/ChangeEmailModal.tsx +35 -21
  84. package/src/components/account/sections/ChangePasswordSection.tsx +10 -6
  85. package/src/components/account/sections/ChangePhoneModal.tsx +50 -22
  86. package/src/components/account/sections/MyProfileSection.tsx +30 -22
  87. package/src/components/account/sections/PreferencesSection.tsx +45 -24
  88. package/src/components/account/sections/SecuritySection.tsx +19 -10
  89. package/src/components/account/sections/TokenSection.tsx +22 -10
  90. package/src/i18n/config.ts +17 -0
  91. package/src/i18n/country-language.ts +60 -0
  92. package/src/i18n/messages/en-us.ts +226 -0
  93. package/src/i18n/messages/es-es.ts +227 -0
  94. package/src/i18n/messages/index.ts +24 -0
  95. package/src/i18n/messages/pt-br.ts +236 -0
  96. package/src/i18n/normalize.ts +15 -0
  97. package/src/i18n/resolve-locale.ts +77 -0
  98. package/src/i18n.ts +10 -0
  99. package/src/providers/auth.provider.tsx +13 -1
  100. package/src/server.ts +2 -0
  101. package/src/utils/intl/cookie-domain.ts +29 -0
  102. package/src/utils/intl/locale-cookie.ts +18 -0
  103. package/src/utils/intl/locales.ts +3 -2
@@ -1,11 +1,13 @@
1
1
  'use client';
2
2
 
3
+ import { useTranslations } from 'next-intl';
3
4
  import { IconAlertTriangle } from '@tabler/icons-react';
4
5
  import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';
5
6
  import { Button } from '../ui/buttons/Button';
6
7
  import { useAccountModals } from '../../store/useAccountModals';
7
8
 
8
9
  export default function IsntPossibleDeleteAccountModal() {
10
+ const translate = useTranslations();
9
11
  const { activeModal, close, config } = useAccountModals();
10
12
  const { onGoToSubscription } = config;
11
13
  const open = activeModal === 'isntPossibleDelete';
@@ -19,12 +21,12 @@ export default function IsntPossibleDeleteAccountModal() {
19
21
  </div>
20
22
  <DialogHeader className="p-0 gap-2">
21
23
  <DialogTitle className="paragraph-medium-semibold text-gray-950">
22
- Não é possível excluir a conta
24
+ {translate('common.account.cantDelete.title')}
23
25
  </DialogTitle>
24
26
  <DialogDescription className="paragraph-small-regular text-gray-600">
25
- Você tem uma assinatura ativa. Para excluir sua conta,{' '}
26
- <span className="font-semibold text-gray-950">primeiro cancele a assinatura</span> na
27
- página Assinatura e depois tente novamente.
27
+ {translate.rich('common.account.cantDelete.description', {
28
+ b: (chunks) => <span className="font-semibold text-gray-950">{chunks}</span>,
29
+ })}
28
30
  </DialogDescription>
29
31
  </DialogHeader>
30
32
  </div>
@@ -33,14 +35,14 @@ export default function IsntPossibleDeleteAccountModal() {
33
35
 
34
36
  <div className="flex flex-row items-center gap-2">
35
37
  <Button className="h-10 flex-1" onClick={close}>
36
- Ok, entendi
38
+ {translate('common.account.cantDelete.confirm')}
37
39
  </Button>
38
40
  <Button
39
41
  variant="secondary"
40
42
  className="h-10 flex-1"
41
43
  onClick={onGoToSubscription ?? close}
42
44
  >
43
- Ir para assinatura
45
+ {translate('common.account.cantDelete.goToSubscription')}
44
46
  </Button>
45
47
  </div>
46
48
  </DialogContent>
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
 
3
+ import { useTranslations } from 'next-intl';
3
4
  import { IconX, IconCopy, IconRefresh } from '@tabler/icons-react';
4
5
  import { Button } from '../ui/buttons/Button';
5
6
  import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';
@@ -15,6 +16,7 @@ interface TwoFactorAuthModalProps {
15
16
  }
16
17
 
17
18
  export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFactorAuthModalProps) {
19
+ const translate = useTranslations();
18
20
  const {
19
21
  code,
20
22
  setCode,
@@ -46,11 +48,11 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
46
48
  className="z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] 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%]"
47
49
  >
48
50
  <DialogHeader className="sr-only">
49
- <DialogTitle>Códigos de segurança</DialogTitle>
51
+ <DialogTitle>{translate('common.account.twoFactor.recoveryTitle')}</DialogTitle>
50
52
  </DialogHeader>
51
53
  <div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
52
54
  <span className="paragraph-medium-semibold text-gray-950 text-center">
53
- Códigos de segurança
55
+ {translate('common.account.twoFactor.recoveryTitle')}
54
56
  </span>
55
57
  <Button
56
58
  type="button"
@@ -65,15 +67,12 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
65
67
  <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">
66
68
  <div className="flex flex-col gap-2">
67
69
  <h3 className="paragraph-medium-semibold text-gray-950 max-w-[269px]">
68
- Salve estes códigos de recuperação de emergência
70
+ {translate('common.account.twoFactor.recoveryHeading')}
69
71
  </h3>
70
72
  <div className="paragraph-small-regular text-gray-600">
71
- <p>
72
- Se você perder acesso ao seu telefone, não será possível fazer login em sua conta
73
- sem um código de dois fatores.
74
- </p>
73
+ <p>{translate('common.account.twoFactor.recoveryText1')}</p>
75
74
  <br />
76
- <p>Imprima, copie ou escreva em um local seguro os códigos abaixo.</p>
75
+ <p>{translate('common.account.twoFactor.recoveryText2')}</p>
77
76
  </div>
78
77
  </div>
79
78
 
@@ -90,17 +89,17 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
90
89
  onClick={handleCopyCodes}
91
90
  >
92
91
  <IconCopy size={16} />
93
- Copiar códigos
92
+ {translate('common.account.twoFactor.copyCodes')}
94
93
  </Button>
95
94
  </div>
96
95
  </div>
97
96
 
98
97
  <div className="flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0">
99
98
  <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
100
- Cancelar
99
+ {translate('common.actions.cancel')}
101
100
  </Button>
102
101
  <Button className="h-10!" type="button" onClick={handleFinalize}>
103
- Finalizar
102
+ {translate('common.account.twoFactor.finish')}
104
103
  </Button>
105
104
  </div>
106
105
  </DialogContent>
@@ -116,11 +115,11 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
116
115
  className="z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:max-h-[90vh] 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%]"
117
116
  >
118
117
  <DialogHeader className="sr-only">
119
- <DialogTitle>Autenticação de dois fatores</DialogTitle>
118
+ <DialogTitle>{translate('common.account.twoFactor.title')}</DialogTitle>
120
119
  </DialogHeader>
121
120
  <div className="shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
122
121
  <span className="paragraph-medium-semibold text-gray-950 text-center">
123
- Autenticação de dois fatores
122
+ {translate('common.account.twoFactor.title')}
124
123
  </span>
125
124
  <Button
126
125
  type="button"
@@ -142,17 +141,18 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
142
141
  <div className="flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible">
143
142
  <div className="flex flex-col items-center gap-4 lg:gap-8 px-4 lg:px-5 py-4 lg:py-6 pb-60 lg:pb-6">
144
143
  <p className="paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]">
145
- Instale um aplicativo autenticador no seu celular (ex.:{' '}
146
- <a
147
- href="https://support.google.com/accounts/answer/1066447"
148
- target="_blank"
149
- rel="noopener noreferrer"
150
- className="paragraph-small-medium underline"
151
- >
152
- Google Authenticator
153
- </a>
154
- ), escaneie o QR Code ao lado ou copie a chave no aplicativo e, em seguida, digite o
155
- código de 6 dígitos gerado para continuar.
144
+ {translate.rich('common.account.twoFactor.instructions', {
145
+ link: (chunks) => (
146
+ <a
147
+ href="https://support.google.com/accounts/answer/1066447"
148
+ target="_blank"
149
+ rel="noopener noreferrer"
150
+ className="paragraph-small-medium underline"
151
+ >
152
+ {chunks}
153
+ </a>
154
+ ),
155
+ })}
156
156
  </p>
157
157
 
158
158
  <div className="border border-gray-200 rounded-lg overflow-hidden p-2 lg:p-3 flex items-center justify-center w-[136px] h-[136px] lg:w-[203px] lg:h-[203px]">
@@ -163,7 +163,9 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
163
163
  className="flex flex-col items-center gap-1.5 text-center"
164
164
  >
165
165
  <IconRefresh size={20} className="text-gray-400" />
166
- <span className="paragraph-xsmall-medium text-gray-500">Tentar novamente</span>
166
+ <span className="paragraph-xsmall-medium text-gray-500">
167
+ {translate('common.account.twoFactor.retry')}
168
+ </span>
167
169
  </button>
168
170
  ) : isGenerating || !qrcode ? (
169
171
  <div className="skeleton w-full h-full rounded" />
@@ -171,7 +173,7 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
171
173
  // eslint-disable-next-line @next/next/no-img-element
172
174
  <img
173
175
  src={qrcode}
174
- alt="QR Code para autenticação de dois fatores"
176
+ alt={translate('common.account.twoFactor.qrAlt')}
175
177
  className="w-full h-full"
176
178
  />
177
179
  )}
@@ -180,7 +182,7 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
180
182
  <div className="flex items-center gap-3 w-full">
181
183
  <Separator className="flex-1" />
182
184
  <span className="paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap">
183
- Cole os 6 dígitos abaixo
185
+ {translate('common.account.twoFactor.pasteDigits')}
184
186
  </span>
185
187
  <Separator className="flex-1" />
186
188
  </div>
@@ -203,10 +205,12 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
203
205
 
204
206
  <div className="shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white">
205
207
  <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
206
- Cancelar
208
+ {translate('common.actions.cancel')}
207
209
  </Button>
208
210
  <Button type="submit" className="h-10!" disabled={!isCodeComplete || isConfirming}>
209
- {isConfirming ? 'Ativando...' : 'Ativar autenticação'}
211
+ {isConfirming
212
+ ? translate('common.account.twoFactor.activating')
213
+ : translate('common.account.twoFactor.activate')}
210
214
  </Button>
211
215
  </div>
212
216
  </form>
@@ -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((t) => (
26
+ toast.custom((toastId) => (
25
27
  <Toast
26
28
  variant="error"
27
- message={result.error ?? 'E-mail já existente ou ocorreu um erro. Tente novamente mais tarde.'}
28
- toastId={t}
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((t) => (
30
- <Toast variant="error" message={result.error ?? 'Erro ao alterar senha'} toastId={t} />
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((t) => (
36
- <Toast variant="success" message="Senha alterada com sucesso" toastId={t} />
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((t) => (
44
- <Toast variant="error" message="Erro ao alterar senha. Tente novamente." toastId={t} />
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('Número de telefone inválido');
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((t) => (
50
+ toast.custom((toastId) => (
49
51
  <Toast
50
52
  variant="error"
51
- message={result.error ?? 'Ocorreu um erro ao salvar o telefone. Tente novamente mais tarde.'}
52
- toastId={t}
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((t) => (
59
- <Toast variant="success" message="Telefone adicionado" toastId={t} />
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((t) => (
74
+ toast.custom((toastId) => (
69
75
  <Toast
70
76
  variant="error"
71
- message={result.error ?? 'Número já existente ou ocorreu um erro. Tente novamente mais tarde.'}
72
- toastId={t}
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((t) => (
32
- <Toast variant="error" message={result.error ?? 'Código inválido'} toastId={t} />
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((t) => (
39
- <Toast variant="success" message="Autenticação de dois fatores desabilitada" toastId={t} />
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((t) => (
47
- <Toast variant="error" message="Erro ao desabilitar 2FA. Tente novamente." toastId={t} />
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((t) => <Toast variant="success" message="Código reenviado" toastId={t} />);
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((t) => (
92
- <Toast variant="error" message="Erro ao reenviar código. Tente novamente." toastId={t} />
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((t) => (
29
- <Toast variant="error" message="Erro ao gerar QR Code. Tente novamente." toastId={t} />
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((t) => (
42
- <Toast variant="error" message="Erro ao confirmar código. Tente novamente." toastId={t} />
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((t) => (
74
- <Toast variant="success" message="Códigos copiados com sucesso" toastId={t} />
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('');