@greatapps/common 1.1.673 → 1.1.675

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 (223) hide show
  1. package/dist/components/account/ConfigurationsMyAccountModal.mjs +6 -8
  2. package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -1
  3. package/dist/components/account/ConfirmDeleteAccountModal.mjs +19 -20
  4. package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
  5. package/dist/components/account/ConfirmGlobalPreferencesModal.mjs +11 -10
  6. package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -1
  7. package/dist/components/account/DeleteAccountModal.mjs +28 -34
  8. package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
  9. package/dist/components/account/DisableTwoFactorAuthModal.mjs +5 -7
  10. package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
  11. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs +9 -8
  12. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
  13. package/dist/components/account/TwoFactorAuthModal.mjs +23 -22
  14. package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
  15. package/dist/components/account/hooks/useChangeEmailForm.mjs +3 -5
  16. package/dist/components/account/hooks/useChangeEmailForm.mjs.map +1 -1
  17. package/dist/components/account/hooks/useChangePasswordForm.mjs +3 -26
  18. package/dist/components/account/hooks/useChangePasswordForm.mjs.map +1 -1
  19. package/dist/components/account/hooks/useChangePhoneForm.mjs +9 -18
  20. package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
  21. package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs +3 -26
  22. package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs.map +1 -1
  23. package/dist/components/account/hooks/useOtpVerification.mjs +3 -19
  24. package/dist/components/account/hooks/useOtpVerification.mjs.map +1 -1
  25. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs +4 -27
  26. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
  27. package/dist/components/account/sections/ChangeEmailModal.mjs +28 -25
  28. package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
  29. package/dist/components/account/sections/ChangePasswordSection.mjs +6 -8
  30. package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
  31. package/dist/components/account/sections/ChangePhoneModal.mjs +27 -24
  32. package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
  33. package/dist/components/account/sections/MyProfileSection.mjs +22 -37
  34. package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
  35. package/dist/components/account/sections/PreferencesSection.mjs +24 -48
  36. package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
  37. package/dist/components/account/sections/SecuritySection.mjs +9 -11
  38. package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
  39. package/dist/components/account/sections/TokenSection.mjs +8 -24
  40. package/dist/components/account/sections/TokenSection.mjs.map +1 -1
  41. package/dist/components/layouts/AppMobileNavBar.mjs +148 -2
  42. package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
  43. package/dist/components/layouts/NavBar.mjs +3 -5
  44. package/dist/components/layouts/NavBar.mjs.map +1 -1
  45. package/dist/components/layouts/NotificationsPopover.mjs +3 -5
  46. package/dist/components/layouts/NotificationsPopover.mjs.map +1 -1
  47. package/dist/components/layouts/ProfilePopover.mjs +4 -6
  48. package/dist/components/layouts/ProfilePopover.mjs.map +1 -1
  49. package/dist/components/layouts/UsersSelectorPopover.mjs +7 -9
  50. package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
  51. package/dist/components/modals/BuyCreditsModal.mjs +18 -17
  52. package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
  53. package/dist/components/modals/CreditsDisabledModal.mjs +4 -6
  54. package/dist/components/modals/CreditsDisabledModal.mjs.map +1 -1
  55. package/dist/components/modals/PaidPlanRequiredModal.mjs +3 -5
  56. package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
  57. package/dist/components/modals/cards/AddCardModal.mjs +24 -27
  58. package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
  59. package/dist/components/modals/cards/CannotDeleteCardModal.mjs +7 -9
  60. package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
  61. package/dist/components/modals/cards/CardFormFields.mjs +22 -25
  62. package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
  63. package/dist/components/modals/cards/DeleteCardModal.mjs +8 -10
  64. package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
  65. package/dist/components/navigation/CancelledSubscriptionBanner.mjs +2 -4
  66. package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
  67. package/dist/components/navigation/OverdueInvoiceBanner.mjs +2 -4
  68. package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
  69. package/dist/components/navigation/PendingCancellationBanner.mjs +6 -4
  70. package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
  71. package/dist/components/navigation/ProjectSelectorPopover.mjs +6 -8
  72. package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
  73. package/dist/components/navigation/UpcomingInvoiceBanner.mjs +6 -4
  74. package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
  75. package/dist/components/navigation/subcomponents/BottomLinks.mjs +3 -5
  76. package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
  77. package/dist/components/navigation/subcomponents/CreditsCard.mjs +1 -3
  78. package/dist/components/navigation/subcomponents/CreditsCard.mjs.map +1 -1
  79. package/dist/components/navigation/subcomponents/PlanCard.mjs +1 -3
  80. package/dist/components/navigation/subcomponents/PlanCard.mjs.map +1 -1
  81. package/dist/components/navigation/subcomponents/ProjectSelector.mjs +3 -5
  82. package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
  83. package/dist/components/pages/NotFoundPage.mjs +3 -5
  84. package/dist/components/pages/NotFoundPage.mjs.map +1 -1
  85. package/dist/components/pages/notifications/Notifications.mjs +10 -13
  86. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  87. package/dist/components/ui/buttons/CopyButton.mjs +5 -9
  88. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  89. package/dist/components/ui/data-display/CardItem.mjs +5 -7
  90. package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
  91. package/dist/components/ui/data-display/PaymentInfoCard.mjs +8 -10
  92. package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
  93. package/dist/components/ui/feedback/DefaultCircularProgress.mjs +1 -3
  94. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  95. package/dist/components/ui/form/ComboboxField.mjs +6 -11
  96. package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
  97. package/dist/components/ui/form/DatePicker.mjs +2 -5
  98. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  99. package/dist/components/ui/form/DateRangePicker.mjs +2 -5
  100. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  101. package/dist/components/ui/form/PhoneInput.mjs +3 -5
  102. package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
  103. package/dist/components/ui/form/SelectField.mjs +3 -6
  104. package/dist/components/ui/form/SelectField.mjs.map +1 -1
  105. package/dist/components/widgets/ImageUpload/ImageCropModal.mjs +18 -11
  106. package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
  107. package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs +15 -6
  108. package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
  109. package/dist/index.mjs +2 -16
  110. package/dist/index.mjs.map +1 -1
  111. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs +1 -2
  112. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
  113. package/dist/modules/plans/types/plan.type.mjs +0 -3
  114. package/dist/modules/plans/types/plan.type.mjs.map +1 -1
  115. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs +8 -15
  116. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
  117. package/dist/providers/auth.provider.mjs +1 -9
  118. package/dist/providers/auth.provider.mjs.map +1 -1
  119. package/dist/server.mjs +0 -2
  120. package/dist/server.mjs.map +1 -1
  121. package/dist/utils/format/currency.mjs +4 -32
  122. package/dist/utils/format/currency.mjs.map +1 -1
  123. package/dist/utils/intl/locales.mjs +2 -3
  124. package/dist/utils/intl/locales.mjs.map +1 -1
  125. package/package.json +1 -7
  126. package/src/components/account/ConfigurationsMyAccountModal.tsx +6 -10
  127. package/src/components/account/ConfirmDeleteAccountModal.tsx +13 -22
  128. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +10 -12
  129. package/src/components/account/DeleteAccountModal.tsx +24 -34
  130. package/src/components/account/DisableTwoFactorAuthModal.tsx +6 -11
  131. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +6 -8
  132. package/src/components/account/TwoFactorAuthModal.tsx +29 -33
  133. package/src/components/account/hooks/useChangeEmailForm.tsx +3 -5
  134. package/src/components/account/hooks/useChangePasswordForm.tsx +6 -20
  135. package/src/components/account/hooks/useChangePhoneForm.tsx +10 -16
  136. package/src/components/account/hooks/useDisableTwoFactorAuthForm.tsx +6 -20
  137. package/src/components/account/hooks/useOtpVerification.tsx +4 -16
  138. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +7 -21
  139. package/src/components/account/sections/ChangeEmailModal.tsx +21 -35
  140. package/src/components/account/sections/ChangePasswordSection.tsx +6 -10
  141. package/src/components/account/sections/ChangePhoneModal.tsx +22 -50
  142. package/src/components/account/sections/MyProfileSection.tsx +23 -37
  143. package/src/components/account/sections/PreferencesSection.tsx +25 -52
  144. package/src/components/account/sections/SecuritySection.tsx +10 -19
  145. package/src/components/account/sections/TokenSection.tsx +10 -22
  146. package/src/components/layouts/AppMobileNavBar.tsx +154 -1
  147. package/src/components/layouts/NavBar.tsx +3 -5
  148. package/src/components/layouts/NotificationsPopover.tsx +3 -5
  149. package/src/components/layouts/ProfilePopover.tsx +4 -6
  150. package/src/components/layouts/UsersSelectorPopover.tsx +7 -9
  151. package/src/components/modals/BuyCreditsModal.tsx +16 -18
  152. package/src/components/modals/CreditsDisabledModal.tsx +6 -6
  153. package/src/components/modals/PaidPlanRequiredModal.tsx +3 -5
  154. package/src/components/modals/cards/AddCardModal.tsx +27 -29
  155. package/src/components/modals/cards/CannotDeleteCardModal.tsx +8 -9
  156. package/src/components/modals/cards/CardFormFields.tsx +22 -25
  157. package/src/components/modals/cards/DeleteCardModal.tsx +8 -10
  158. package/src/components/navigation/CancelledSubscriptionBanner.tsx +2 -4
  159. package/src/components/navigation/OverdueInvoiceBanner.tsx +2 -4
  160. package/src/components/navigation/PendingCancellationBanner.tsx +2 -4
  161. package/src/components/navigation/ProjectSelectorPopover.tsx +6 -8
  162. package/src/components/navigation/UpcomingInvoiceBanner.tsx +2 -4
  163. package/src/components/navigation/subcomponents/BottomLinks.tsx +3 -5
  164. package/src/components/navigation/subcomponents/CreditsCard.tsx +1 -3
  165. package/src/components/navigation/subcomponents/PlanCard.tsx +1 -3
  166. package/src/components/navigation/subcomponents/ProjectSelector.tsx +3 -5
  167. package/src/components/pages/NotFoundPage.tsx +3 -5
  168. package/src/components/pages/notifications/Notifications.tsx +10 -13
  169. package/src/components/ui/buttons/CopyButton.tsx +5 -10
  170. package/src/components/ui/data-display/CardItem.tsx +5 -7
  171. package/src/components/ui/data-display/PaymentInfoCard.tsx +8 -10
  172. package/src/components/ui/feedback/DefaultCircularProgress.tsx +1 -3
  173. package/src/components/ui/form/ComboboxField.tsx +6 -11
  174. package/src/components/ui/form/DatePicker.tsx +2 -5
  175. package/src/components/ui/form/DateRangePicker.tsx +2 -5
  176. package/src/components/ui/form/PhoneInput.tsx +3 -5
  177. package/src/components/ui/form/SelectField.tsx +3 -6
  178. package/src/components/widgets/ImageUpload/ImageCropModal.tsx +11 -19
  179. package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +5 -6
  180. package/src/index.ts +2 -12
  181. package/src/modules/cards/hooks/handle-delete-card.hook.ts +3 -8
  182. package/src/modules/plans/types/plan.type.ts +0 -3
  183. package/src/modules/plans/utils/map-api-plan-to-ui.ts +7 -30
  184. package/src/providers/auth.provider.tsx +1 -13
  185. package/src/server.ts +0 -2
  186. package/src/utils/format/currency.ts +7 -62
  187. package/src/utils/intl/locales.ts +2 -3
  188. package/dist/i18n/config.mjs +0 -13
  189. package/dist/i18n/config.mjs.map +0 -1
  190. package/dist/i18n/country-language.mjs +0 -74
  191. package/dist/i18n/country-language.mjs.map +0 -1
  192. package/dist/i18n/messages/en-us.mjs +0 -450
  193. package/dist/i18n/messages/en-us.mjs.map +0 -1
  194. package/dist/i18n/messages/es-es.mjs +0 -450
  195. package/dist/i18n/messages/es-es.mjs.map +0 -1
  196. package/dist/i18n/messages/index.mjs +0 -16
  197. package/dist/i18n/messages/index.mjs.map +0 -1
  198. package/dist/i18n/messages/pt-br.mjs +0 -463
  199. package/dist/i18n/messages/pt-br.mjs.map +0 -1
  200. package/dist/i18n/normalize.mjs +0 -12
  201. package/dist/i18n/normalize.mjs.map +0 -1
  202. package/dist/i18n/resolve-locale.mjs +0 -42
  203. package/dist/i18n/resolve-locale.mjs.map +0 -1
  204. package/dist/i18n.mjs +0 -14
  205. package/dist/i18n.mjs.map +0 -1
  206. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs +0 -20
  207. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +0 -1
  208. package/dist/utils/intl/cookie-domain.mjs +0 -17
  209. package/dist/utils/intl/cookie-domain.mjs.map +0 -1
  210. package/dist/utils/intl/locale-cookie.mjs +0 -13
  211. package/dist/utils/intl/locale-cookie.mjs.map +0 -1
  212. package/src/i18n/config.ts +0 -17
  213. package/src/i18n/country-language.ts +0 -60
  214. package/src/i18n/messages/en-us.ts +0 -468
  215. package/src/i18n/messages/es-es.ts +0 -469
  216. package/src/i18n/messages/index.ts +0 -24
  217. package/src/i18n/messages/pt-br.ts +0 -492
  218. package/src/i18n/normalize.ts +0 -15
  219. package/src/i18n/resolve-locale.ts +0 -77
  220. package/src/i18n.ts +0 -10
  221. package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +0 -32
  222. package/src/utils/intl/cookie-domain.ts +0 -29
  223. package/src/utils/intl/locale-cookie.ts +0 -18
@@ -2,13 +2,9 @@
2
2
 
3
3
  import { useState, useEffect } from 'react';
4
4
  import { useForm } from 'react-hook-form';
5
- import { useTranslations, useLocale } from 'next-intl';
6
- import { useRouter } from 'next/navigation';
7
5
  import { toast } from 'sonner';
8
6
  import { IconLock } from '@tabler/icons-react';
9
7
  import { cn } from '../../../infra/utils/clsx';
10
- import type { Locale } from '../../../i18n/config';
11
- import { setLocaleCookie } from '../../../utils/intl/locale-cookie';
12
8
  import { Button } from '../../ui/buttons/Button';
13
9
  import { Separator } from '../../ui/data-display/Separator';
14
10
  import { Toast } from '../../ui/feedback/Toast';
@@ -17,7 +13,6 @@ import { ComboboxField } from '../../ui/form/ComboboxField';
17
13
  import { SelectField } from '../../ui/form/SelectField';
18
14
  import ConfirmGlobalPreferencesModal from '../ConfirmGlobalPreferencesModal';
19
15
  import { useAuth } from '../../../providers/auth.provider';
20
- import { useWhitelabel } from '../../../providers/whitelabel.provider';
21
16
  import { UserProfile } from '../../../modules/users/schema';
22
17
  import type { UpdateAccountRequest } from '../../../modules/accounts/types';
23
18
  import {
@@ -46,27 +41,9 @@ interface PreferencesSectionProps {
46
41
  }
47
42
 
48
43
  export function PreferencesSection({ onClose }: PreferencesSectionProps) {
49
- // Padrão raiz: um único `translate` chamado pela chave inteira (`common.<modulo>.<chave>`).
50
- const translate = useTranslations();
51
- // Exceção: chave dinâmica (option.value) numa lista → namespace escopado.
52
- const translateLanguage = useTranslations('common.languages');
53
- const currentLocale = useLocale();
54
- const router = useRouter();
55
44
  const { data: timezones = [] } = useTimezones();
56
45
  const { data: currencies = [] } = useCurrencies();
57
46
  const { user, account } = useAuth();
58
- const { whitelabel } = useWhitelabel();
59
- const languageOptions = LANGUAGE_OPTIONS.map((option) => ({
60
- ...option,
61
- label: translateLanguage(option.value as Locale),
62
- displayValue: translateLanguage(option.value as Locale),
63
- }));
64
- const timeFormatOptions = TIME_FORMAT_OPTIONS.map((option) => ({
65
- ...option,
66
- label: translate(
67
- `common.preferences.timeFormatOptions.${option.value === '24h' ? 'h24' : 'h12'}`,
68
- ),
69
- }));
70
47
  const isOwner = user?.profile === UserProfile.owner;
71
48
  const canEditPreferences = isOwner || user?.profile === UserProfile.admin;
72
49
  const updateAccountUser = useUpdateAccountUser();
@@ -97,7 +74,7 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
97
74
  companyName: account.name ?? '',
98
75
  language: LANGUAGE_OPTIONS.find(
99
76
  (o) => o.apiValue === user.language?.toLowerCase()
100
- )?.value ?? 'pt-br',
77
+ )?.value ?? 'pt-BR',
101
78
  currency: account.currency,
102
79
  timezone: account.timezone,
103
80
  timeFormat: '24h',
@@ -121,20 +98,16 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
121
98
  }
122
99
 
123
100
  reset(data);
124
- toast.custom((toastId) => (
125
- <Toast variant="success" message={translate('common.preferences.savedSuccess')} toastId={toastId} />
101
+ toast.custom((t) => (
102
+ <Toast variant="success" message="Preferências salvas com sucesso" toastId={t} />
126
103
  ));
127
104
  onClose();
128
- if (data.language !== currentLocale) {
129
- setLocaleCookie(data.language, whitelabel?.domain);
130
- router.refresh();
131
- }
132
105
  } catch (error) {
133
- toast.custom((toastId) => (
106
+ toast.custom((t) => (
134
107
  <Toast
135
108
  variant="error"
136
- message={error instanceof Error ? error.message : translate('common.preferences.saveError')}
137
- toastId={toastId}
109
+ message={error instanceof Error ? error.message : 'Erro ao salvar preferências'}
110
+ toastId={t}
138
111
  />
139
112
  ));
140
113
  } finally {
@@ -175,12 +148,12 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
175
148
  <>
176
149
  <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col h-full">
177
150
  <div className="overflow-y-auto overscroll-contain px-4 pb-4 lg:p-5 flex flex-col gap-5 lg:gap-6 flex-1">
178
- <span className="paragraph-medium-semibold text-gray-950">{translate('common.preferences.title')}</span>
151
+ <span className="paragraph-medium-semibold text-gray-950">Preferências</span>
179
152
  <div className="flex flex-col gap-8">
180
153
  <div className="flex flex-col lg:flex-row items-center gap-3">
181
154
  <FormField
182
- label={translate('common.preferences.companyName')}
183
- placeholder={translate('common.preferences.companyNamePlaceholder')}
155
+ label="Nome da empresa"
156
+ placeholder="Digite o nome da empresa"
184
157
  classnameContainer={cn('w-full', !isOwner && 'cursor-not-allowed opacity-50')}
185
158
  value={watch('companyName')}
186
159
  onChange={(e) => setValue('companyName', e.target.value, { shouldDirty: true })}
@@ -190,18 +163,18 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
190
163
 
191
164
  <div className="flex flex-col lg:flex-row items-center gap-3">
192
165
  <ComboboxField
193
- label={translate('common.preferences.language')}
194
- placeholder={translate('common.preferences.languagePlaceholder')}
195
- searchPlaceholder={translate('common.preferences.languageSearch')}
166
+ label="Idioma"
167
+ placeholder="Selecione o idioma"
168
+ searchPlaceholder="Buscar idioma..."
196
169
  containerClassName="w-full"
197
- options={languageOptions}
170
+ options={LANGUAGE_OPTIONS}
198
171
  value={watch('language')}
199
172
  onChange={(value) => setValue('language', value, { shouldDirty: true })}
200
173
  />
201
174
  <ComboboxField
202
- label={translate('common.preferences.currency')}
203
- placeholder={translate('common.preferences.currencyPlaceholder')}
204
- searchPlaceholder={translate('common.preferences.currencySearch')}
175
+ label="Moeda"
176
+ placeholder="Selecione a moeda"
177
+ searchPlaceholder="Buscar moeda..."
205
178
  containerClassName="w-full"
206
179
  options={currencies}
207
180
  value={watch('currency')}
@@ -214,12 +187,12 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
214
187
  <Separator />
215
188
 
216
189
  <div className="flex flex-col gap-4">
217
- <span className="paragraph-medium-semibold text-gray-950">{translate('common.preferences.timeDisplay')}</span>
190
+ <span className="paragraph-medium-semibold text-gray-950">Exibição hora</span>
218
191
  <div className="flex flex-col lg:flex-row items-center gap-3">
219
192
  <ComboboxField
220
- label={translate('common.preferences.timezone')}
221
- placeholder={translate('common.preferences.timezonePlaceholder')}
222
- searchPlaceholder={translate('common.preferences.timezoneSearch')}
193
+ label="Fuso horário"
194
+ placeholder="Selecione o fuso horário"
195
+ searchPlaceholder="Buscar fuso horário..."
223
196
  containerClassName="w-full"
224
197
  options={timezones}
225
198
  value={watch('timezone')}
@@ -228,11 +201,11 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
228
201
  disabled={!canEditPreferences}
229
202
  />
230
203
  <SelectField
231
- label={translate('common.preferences.timeFormat')}
232
- placeholder={translate('common.preferences.timeFormatPlaceholder')}
204
+ label="Formato hora"
205
+ placeholder="Selecione o formato"
233
206
  className="h-10!"
234
207
  containerClassName="w-full"
235
- options={timeFormatOptions}
208
+ options={TIME_FORMAT_OPTIONS}
236
209
  value={watch('timeFormat')}
237
210
  onChange={(value) =>
238
211
  setValue('timeFormat', value as string, { shouldDirty: true })
@@ -257,10 +230,10 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
257
230
  onClose();
258
231
  }}
259
232
  >
260
- {translate('common.actions.cancel')}
233
+ Cancelar
261
234
  </Button>
262
235
  <Button className="h-10!" type="submit" disabled={isSaving}>
263
- {isSaving ? translate('common.actions.saving') : translate('common.actions.saveChanges')}
236
+ {isSaving ? 'Salvando...' : 'Salvar alterações'}
264
237
  </Button>
265
238
  </div>
266
239
  </form>
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import { IconAlertTriangle, IconBrandGoogleFilled } from '@tabler/icons-react';
4
- import { useTranslations } from 'next-intl';
5
4
  import { toast } from 'sonner';
6
5
  import { useQueryClient } from '@tanstack/react-query';
7
6
  import { useAuth } from '../../../providers/auth.provider';
@@ -19,7 +18,6 @@ interface SecuritySectionProps {
19
18
  export function SecuritySection({
20
19
  onDeleteAccount,
21
20
  }: SecuritySectionProps) {
22
- const translate = useTranslations();
23
21
  const { user } = useAuth();
24
22
  const queryClient = useQueryClient();
25
23
  const { mutateAsync: unlinkGoogle, isPending: isUnlinking } = useUnlinkGoogle();
@@ -34,16 +32,14 @@ export function SecuritySection({
34
32
  queryClient.invalidateQueries({ queryKey: USER_QUERY_KEY });
35
33
  } catch (error) {
36
34
  const message =
37
- error instanceof Error ? error.message : translate('common.account.security.unlinkError');
38
- toast.custom((toastId) => <Toast variant="error" message={message} toastId={toastId} />);
35
+ error instanceof Error ? error.message : 'Erro ao desvincular conta Google.';
36
+ toast.custom((t) => <Toast variant="error" message={message} toastId={t} />);
39
37
  }
40
38
  };
41
39
 
42
40
  return (
43
41
  <div className="h-full overflow-y-auto overscroll-contain px-4 pb-20 lg:p-5 lg:pt-5 flex flex-col gap-5 lg:gap-6 lg:pb-31 lg:overscroll-auto">
44
- <span className="paragraph-medium-semibold text-gray-950 hidden lg:block">
45
- {translate('common.account.security.title')}
46
- </span>
42
+ <span className="paragraph-medium-semibold text-gray-950 hidden lg:block">Segurança</span>
47
43
 
48
44
  {hasGoogleLinked && (
49
45
  <div className="flex flex-col items-center lg:items-start gap-4">
@@ -52,11 +48,10 @@ export function SecuritySection({
52
48
  </div>
53
49
 
54
50
  <div className="flex flex-col gap-2">
55
- <span className="paragraph-medium-semibold text-gray-950">
56
- {translate('common.account.security.googleLinkedTitle')}
57
- </span>
51
+ <span className="paragraph-medium-semibold text-gray-950">Conta Google vinculada</span>
58
52
  <span className="paragraph-small-regular text-gray-600">
59
- {translate('common.account.security.googleLinkedDescription')}
53
+ Sua conta está vinculada ao Google. Se desvincular, use &quot;Esqueci minha senha&quot; para
54
+ redefinir uma senha de acesso por e-mail.
60
55
  </span>
61
56
  </div>
62
57
 
@@ -66,9 +61,7 @@ export function SecuritySection({
66
61
  className="paragraph-small-semibold text-zinc-700 bg-zinc-100 rounded-lg px-3 py-2 cursor-pointer hover:bg-zinc-200 transition-colors w-fit disabled:opacity-50 disabled:cursor-not-allowed"
67
62
  onClick={handleUnlinkGoogle}
68
63
  >
69
- {isUnlinking
70
- ? translate('common.account.security.unlinking')
71
- : translate('common.account.security.unlinkGoogle')}
64
+ {isUnlinking ? 'Desvinculando...' : 'Desvincular Google'}
72
65
  </button>
73
66
  </div>
74
67
  )}
@@ -79,11 +72,9 @@ export function SecuritySection({
79
72
  </div>
80
73
 
81
74
  <div className="flex flex-col gap-2">
82
- <span className="paragraph-medium-semibold text-gray-950">
83
- {translate('common.account.deleteAccount.title')}
84
- </span>
75
+ <span className="paragraph-medium-semibold text-gray-950">Excluir conta</span>
85
76
  <span className="paragraph-small-regular text-gray-600">
86
- {translate('common.account.security.deleteAccountDescription')}
77
+ Esta ação é permanente e não pode ser desfeita. Todos os seus dados, projetos e configurações serão removidos definitivamente.
87
78
  </span>
88
79
  </div>
89
80
 
@@ -93,7 +84,7 @@ export function SecuritySection({
93
84
  className="paragraph-small-semibold text-red-600 bg-red-50 rounded-lg px-3 py-2 cursor-pointer hover:bg-red-100 transition-colors w-fit"
94
85
  onClick={onDeleteAccount}
95
86
  >
96
- {translate('common.account.security.deleteMyAccount')}
87
+ Excluir minha conta
97
88
  </button>
98
89
  )}
99
90
  </div>
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import { IconCheck, IconCopy, IconInfoCircle } from '@tabler/icons-react';
4
- import { useTranslations } from 'next-intl';
5
4
  import { toast } from 'sonner';
6
5
  import { Toast } from '../../ui/feedback/Toast';
7
6
  import { Button } from '../../ui/buttons/Button';
@@ -11,42 +10,31 @@ import { useAccountToken } from '../../../modules/accounts/hooks/use-account-tok
11
10
  import { useIsDefaultWhitelabel } from '../../../providers/whitelabel.provider';
12
11
 
13
12
  export function TokenSection() {
14
- const translate = useTranslations();
15
13
  const { data: token = '', isLoading } = useAccountToken();
16
14
  const isDefaultWl = useIsDefaultWhitelabel();
17
15
 
18
16
  const { isCopied, copy } = useCopyToClipboard({
19
17
  onSuccess: () => {
20
- toast.custom((toastId) => (
21
- <Toast
22
- variant="success"
23
- message={translate('common.account.token.copySuccess')}
24
- toastId={toastId}
25
- />
18
+ toast.custom((t) => (
19
+ <Toast variant="success" message="Token copiado com sucesso" toastId={t} />
26
20
  ));
27
21
  },
28
22
  onError: () => {
29
- toast.custom((toastId) => (
30
- <Toast
31
- variant="error"
32
- message={translate('common.account.token.copyError')}
33
- toastId={toastId}
34
- />
23
+ toast.custom((t) => (
24
+ <Toast variant="error" message="Não foi possível copiar o token" toastId={t} />
35
25
  ));
36
26
  },
37
27
  });
38
28
 
39
29
  return (
40
30
  <div className="h-full overflow-y-auto overscroll-contain px-4 pb-20 lg:p-5 lg:pt-5 flex flex-col gap-5 lg:gap-6 lg:pb-31 lg:overscroll-auto">
41
- <span className="paragraph-medium-semibold text-gray-950">
42
- {translate('common.account.token.title')}
43
- </span>
31
+ <span className="paragraph-medium-semibold text-gray-950">Token da conta</span>
44
32
 
45
33
  <div className="flex flex-col gap-3">
46
34
  <div className="flex items-end gap-3">
47
35
  <FormField
48
- label={translate('common.account.token.label')}
49
- value={isLoading ? translate('common.actions.loading') : token}
36
+ label="Token"
37
+ value={isLoading ? 'Carregando...' : token}
50
38
  disabled
51
39
  readOnly
52
40
  classnameContainer="bg-gray-50 cursor-default opacity-100!"
@@ -60,14 +48,14 @@ export function TokenSection() {
60
48
  disabled={isLoading || !token}
61
49
  >
62
50
  {isCopied ? <IconCheck size={16} /> : <IconCopy size={16} />}
63
- {isCopied ? translate('common.actions.copied') : translate('common.actions.copy')}
51
+ {isCopied ? 'Copiado' : 'Copiar'}
64
52
  </Button>
65
53
  </div>
66
54
 
67
55
  <div className={`flex items-center gap-3 p-4 rounded-lg ${isDefaultWl ? 'bg-cyan-50' : 'bg-zinc-50'}`}>
68
56
  <IconInfoCircle className="size-4 text-zinc-950 shrink-0" />
69
57
  <span className="paragraph-small-regular text-zinc-950 max-w-[420px]">
70
- {translate('common.account.token.info')}
58
+ Este token é exclusivo da sua conta e permite acesso à API. Não compartilhe com terceiros.
71
59
  </span>
72
60
  </div>
73
61
 
@@ -77,7 +65,7 @@ export function TokenSection() {
77
65
  rel="noopener noreferrer"
78
66
  className="paragraph-small-medium text-gray-500 underline hover:text-gray-700 transition-colors w-fit"
79
67
  >
80
- {translate('common.account.token.docsLink')}
68
+ Acessar a documentação
81
69
  </a>
82
70
  </div>
83
71
  </div>
@@ -4,13 +4,20 @@ import { ReactNode } from "react";
4
4
  import Image from "next/image";
5
5
  import { IconMenu2, IconX } from "@tabler/icons-react";
6
6
  import { ProfilePopover } from "./ProfilePopover";
7
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
7
8
  import { useMobileNavbarSheet } from "../../store/useMobileNavbarSheet";
8
- import { useIsDefaultWhitelabel } from "../../providers/whitelabel.provider";
9
+ import {
10
+ useWhitelabel,
11
+ useIsDefaultWhitelabel,
12
+ } from "../../providers/whitelabel.provider";
13
+ import { cn } from "../../infra/utils/clsx";
9
14
  import type { ProfileMenuItem } from "./ProfilePopover";
10
15
 
11
16
  export interface AppMobileNavBarProps {
12
17
  /** Which app is currently active — controls which icon gets the indicator */
13
18
  activeApp?: "gapps" | "gpages";
19
+ /** Called when the GreatApps logo is clicked */
20
+ onLogoClick?: () => void;
14
21
  /** Called when the app icon (e.g. GreatPages) is clicked */
15
22
  onAppIconClick?: () => void;
16
23
  /** Extra slot rendered after the app icon (e.g. project selector) */
@@ -21,19 +28,165 @@ export interface AppMobileNavBarProps {
21
28
 
22
29
  export function AppMobileNavBar({
23
30
  activeApp,
31
+ onLogoClick,
24
32
  onAppIconClick,
25
33
  extraLeftSlot,
26
34
  menuItems = [],
27
35
  showMenuToggle = true,
28
36
  }: AppMobileNavBarProps) {
29
37
  const { isOpen, toggle } = useMobileNavbarSheet();
38
+ const { whitelabel } = useWhitelabel();
30
39
  const isDefaultWl = useIsDefaultWhitelabel();
40
+ const primaryColor = whitelabel?.general?.primary_color;
41
+ const wlName = whitelabel?.name || "Great";
31
42
 
43
+ const isGappsActive = activeApp === "gapps";
32
44
  const isGpagesActive = activeApp === "gpages";
33
45
 
46
+ const wlIcon = whitelabel?.secondary_logo ? (
47
+ <Image
48
+ className="size-7 object-contain"
49
+ src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${whitelabel.secondary_logo}`}
50
+ alt={`${wlName} Logo`}
51
+ width={28}
52
+ height={28}
53
+ />
54
+ ) : (
55
+ <div
56
+ className={cn(
57
+ "size-10 rounded-lg flex items-center justify-center transition-opacity duration-300",
58
+ !isGappsActive && "opacity-20",
59
+ )}
60
+ style={{ backgroundColor: primaryColor }}
61
+ >
62
+ <svg
63
+ xmlns="http://www.w3.org/2000/svg"
64
+ width="24"
65
+ height="24"
66
+ viewBox="0 0 24 24"
67
+ fill="none"
68
+ stroke="white"
69
+ strokeWidth="2"
70
+ strokeLinecap="round"
71
+ strokeLinejoin="round"
72
+ >
73
+ <path d="M4 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4" />
74
+ <path d="M14 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4" />
75
+ <path d="M4 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4" />
76
+ <path d="M14 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4" />
77
+ </svg>
78
+ </div>
79
+ );
80
+
34
81
  return (
35
82
  <div className="fixed top-0 left-0 right-0 flex md:hidden items-center justify-between p-4 bg-white z-50 border-b border-gray-200">
36
83
  <div className="flex items-center gap-1.5">
84
+ {/* GreatApps logo */}
85
+ <div className="relative">
86
+ <Tooltip>
87
+ <TooltipTrigger asChild>
88
+ <div
89
+ className={cn(
90
+ "flex items-center justify-center",
91
+ onLogoClick ? "cursor-pointer" : "",
92
+ )}
93
+ onClick={onLogoClick}
94
+ >
95
+ {isDefaultWl ? (
96
+ <div className="size-10 flex items-center justify-center rounded-lg">
97
+ <Image
98
+ src="/icons/great-icon.svg"
99
+ alt="Great Icon"
100
+ width={28}
101
+ height={28}
102
+ />
103
+ </div>
104
+ ) : (
105
+ wlIcon
106
+ )}
107
+ </div>
108
+ </TooltipTrigger>
109
+ <TooltipContent side="bottom">{wlName}</TooltipContent>
110
+ </Tooltip>
111
+ <div
112
+ className={cn(
113
+ "absolute -bottom-[17px] left-1/2 -translate-x-1/2 w-5 h-[3px] rounded-t-xl transition-opacity duration-300",
114
+ isDefaultWl ? "bg-gray-950" : "",
115
+ isGappsActive ? "opacity-100" : "opacity-0",
116
+ )}
117
+ style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}
118
+ />
119
+ </div>
120
+
121
+ {/* GreatPages icon */}
122
+ <div className="relative">
123
+ <Tooltip>
124
+ <TooltipTrigger asChild>
125
+ <div
126
+ className={cn(
127
+ "size-10 rounded-lg flex items-center justify-center border-2 ring-2 transition-colors duration-300",
128
+ isGpagesActive
129
+ ? isDefaultWl
130
+ ? "bg-cyan-100 border-white ring-cyan-300"
131
+ : "border-white ring-transparent"
132
+ : isDefaultWl
133
+ ? "hover:bg-gray-100 border-transparent ring-transparent"
134
+ : "border-transparent ring-transparent",
135
+ onAppIconClick ? "cursor-pointer" : "",
136
+ )}
137
+ style={
138
+ !isDefaultWl
139
+ ? {
140
+ backgroundColor: primaryColor,
141
+ boxShadow: isGpagesActive
142
+ ? `0 0 0 2px ${primaryColor}40`
143
+ : undefined,
144
+ opacity: !isGpagesActive ? 0.2 : undefined,
145
+ }
146
+ : undefined
147
+ }
148
+ onClick={onAppIconClick}
149
+ >
150
+ {isDefaultWl ? (
151
+ <Image
152
+ src="/icons/icon-navbar.svg"
153
+ alt="GreatPages"
154
+ width={24}
155
+ height={24}
156
+ />
157
+ ) : (
158
+ <svg
159
+ xmlns="http://www.w3.org/2000/svg"
160
+ width="24"
161
+ height="24"
162
+ viewBox="0 0 24 24"
163
+ fill="none"
164
+ stroke="white"
165
+ strokeWidth="2"
166
+ strokeLinecap="round"
167
+ strokeLinejoin="round"
168
+ >
169
+ <path d="M4 8h16" />
170
+ <path d="M4 6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2l0 -12" />
171
+ <path d="M8 4v4" />
172
+ </svg>
173
+ )}
174
+ </div>
175
+ </TooltipTrigger>
176
+ <TooltipContent side="bottom">
177
+ {isDefaultWl ? "GreatPages" : "Páginas"}
178
+ </TooltipContent>
179
+ </Tooltip>
180
+ <div
181
+ className={cn(
182
+ "absolute -bottom-[17px] left-1/2 -translate-x-1/2 w-5 h-[3px] rounded-t-xl transition-opacity duration-300",
183
+ isDefaultWl ? "bg-cyan-300" : "",
184
+ isGpagesActive ? "opacity-100" : "opacity-0",
185
+ )}
186
+ style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}
187
+ />
188
+ </div>
189
+
37
190
  {extraLeftSlot}
38
191
  </div>
39
192
  <div className="flex items-center gap-1.5">
@@ -3,7 +3,6 @@
3
3
  import * as React from "react";
4
4
  import Image from "next/image";
5
5
  import Link from "next/link";
6
- import { useTranslations } from "next-intl";
7
6
  import { IconChevronRight } from "@tabler/icons-react";
8
7
  import { Separator } from "../ui/data-display/Separator";
9
8
  import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
@@ -36,7 +35,6 @@ function NavBar({
36
35
  children,
37
36
  className,
38
37
  }: NavBarProps) {
39
- const translate = useTranslations();
40
38
  const { isExpanded: isDesktopExpanded, toggle: toggleDesktop } =
41
39
  useDesktopSidebarStore();
42
40
  useDesktopSidebarHydration();
@@ -130,7 +128,7 @@ function NavBar({
130
128
  <IconChevronRight size={16} className="text-gray-500" />
131
129
  </button>
132
130
  </TooltipTrigger>
133
- <TooltipContent side="right">{translate('common.layout.navbar.expandMenu')}</TooltipContent>
131
+ <TooltipContent side="right">Expandir menu</TooltipContent>
134
132
  </Tooltip>
135
133
  )}
136
134
  {/* Desktop expand button */}
@@ -144,7 +142,7 @@ function NavBar({
144
142
  <IconChevronRight size={16} className="text-gray-500" />
145
143
  </button>
146
144
  </TooltipTrigger>
147
- <TooltipContent side="right">{translate('common.layout.navbar.expandMenu')}</TooltipContent>
145
+ <TooltipContent side="right">Expandir menu</TooltipContent>
148
146
  </Tooltip>
149
147
  )}
150
148
  </div>
@@ -205,7 +203,7 @@ function NavBar({
205
203
  </Link>
206
204
  </TooltipTrigger>
207
205
  <TooltipContent side="right">
208
- {isDefaultWl ? translate('common.layout.navbar.greatPages') : translate('common.layout.navbar.pages')}
206
+ {isDefaultWl ? "GreatPages" : "Páginas"}
209
207
  </TooltipContent>
210
208
  </Tooltip>
211
209
  <div
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import { useState } from "react";
4
- import { useTranslations } from "next-intl";
5
4
  import { IconBell } from '@tabler/icons-react';
6
5
  import * as PopoverPrimitive from "@radix-ui/react-popover";
7
6
  import { Popover } from "../ui/overlay/Popover";
@@ -28,7 +27,6 @@ function NotificationsPopover({
28
27
  contentClassName,
29
28
  badgeClassName,
30
29
  }: NotificationsPopoverProps) {
31
- const translate = useTranslations();
32
30
  const isDefaultWl = useIsDefaultWhitelabel();
33
31
  const resolvedBadgeClassName = badgeClassName ?? (isDefaultWl ? "bg-cyan-300" : "bg-zinc-300");
34
32
  const [open, setOpen] = useState(false);
@@ -73,7 +71,7 @@ function NotificationsPopover({
73
71
  sideOffset={8}
74
72
  >
75
73
  <span className="paragraph-small-semibold text-gray-950 px-4">
76
- {translate('common.notifications.popover.title')}
74
+ Últimas notificações
77
75
  </span>
78
76
 
79
77
  {messages.length > 0 ? (
@@ -97,7 +95,7 @@ function NotificationsPopover({
97
95
  <IconBell size={20} color="var(--color-gray-950)" />
98
96
  </div>
99
97
  <span className="paragraph-small-medium text-gray-950">
100
- {translate('common.notifications.popover.empty')}
98
+ Sem notificações por enquanto
101
99
  </span>
102
100
  </div>
103
101
  )}
@@ -108,7 +106,7 @@ function NotificationsPopover({
108
106
  className="h-8! mt-2 mb-4 mx-4 paragraph-small-semibold"
109
107
  onClick={onViewAll}
110
108
  >
111
- {translate('common.notifications.popover.viewAll')}
109
+ Todas as notificações
112
110
  </Button>
113
111
  )}
114
112
  </PopoverPrimitive.Content>
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import { useState } from "react";
4
- import { useTranslations } from "next-intl";
5
4
  import { useRouter } from "next/navigation";
6
5
  import * as PopoverPrimitive from "@radix-ui/react-popover";
7
6
  import { Popover } from "../ui/overlay/Popover";
@@ -37,7 +36,6 @@ function ProfilePopover({
37
36
  contentClassName = "absolute bottom-2 left-[26px]",
38
37
  menuItems = [],
39
38
  }: ProfilePopoverProps) {
40
- const translate = useTranslations();
41
39
  const { user, logout } = useAuth();
42
40
  const [isLoggingOut, setIsLoggingOut] = useState(false);
43
41
  const [popoverOpen, setPopoverOpen] = useState(false);
@@ -70,7 +68,7 @@ function ProfilePopover({
70
68
  <>
71
69
  <LoadingOverlay
72
70
  isLoading={isLoggingOut}
73
- message={translate('common.layout.profile.loggingOut')}
71
+ message="Saindo da sua conta..."
74
72
  />
75
73
  <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
76
74
  <PopoverPrimitive.Trigger className="cursor-pointer">
@@ -126,7 +124,7 @@ function ProfilePopover({
126
124
  }
127
125
  }}
128
126
  >
129
- {translate('common.actions.edit')}
127
+ Editar
130
128
  </Button>
131
129
  </div>
132
130
 
@@ -148,7 +146,7 @@ function ProfilePopover({
148
146
  >
149
147
  <div className="flex items-center justify-between gap-2">
150
148
  <span className="paragraph-xsmall-semibold text-white truncate">
151
- {translate('common.layout.profile.usedCredits')}
149
+ Créditos usados
152
150
  </span>
153
151
  <span className="paragraph-xsmall-medium text-white/50">
154
152
  {summary.usedCredits.toLocaleString("pt-BR")}/
@@ -175,7 +173,7 @@ function ProfilePopover({
175
173
  ))}
176
174
  </div>
177
175
  <Separator />
178
- <NavBarItem label={translate('common.layout.profile.logout')} onClick={handleLogout} />
176
+ <NavBarItem label="Sair" onClick={handleLogout} />
179
177
  </div>
180
178
  </div>
181
179
  </PopoverPrimitive.Content>