@greatapps/common 1.1.675 → 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.
Files changed (240) 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/constants.mjs +4 -4
  16. package/dist/components/account/constants.mjs.map +1 -1
  17. package/dist/components/account/hooks/useChangeEmailForm.mjs +5 -3
  18. package/dist/components/account/hooks/useChangeEmailForm.mjs.map +1 -1
  19. package/dist/components/account/hooks/useChangePasswordForm.mjs +26 -3
  20. package/dist/components/account/hooks/useChangePasswordForm.mjs.map +1 -1
  21. package/dist/components/account/hooks/useChangePhoneForm.mjs +18 -9
  22. package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
  23. package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs +26 -3
  24. package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs.map +1 -1
  25. package/dist/components/account/hooks/useOtpVerification.mjs +19 -3
  26. package/dist/components/account/hooks/useOtpVerification.mjs.map +1 -1
  27. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs +27 -4
  28. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
  29. package/dist/components/account/sections/ChangeEmailModal.mjs +25 -28
  30. package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
  31. package/dist/components/account/sections/ChangePasswordSection.mjs +8 -6
  32. package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
  33. package/dist/components/account/sections/ChangePhoneModal.mjs +24 -27
  34. package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
  35. package/dist/components/account/sections/MyProfileSection.mjs +37 -22
  36. package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
  37. package/dist/components/account/sections/PreferencesSection.mjs +48 -24
  38. package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
  39. package/dist/components/account/sections/SecuritySection.mjs +11 -9
  40. package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
  41. package/dist/components/account/sections/TokenSection.mjs +24 -8
  42. package/dist/components/account/sections/TokenSection.mjs.map +1 -1
  43. package/dist/components/layouts/AppMobileNavBar.mjs +2 -148
  44. package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
  45. package/dist/components/layouts/NavBar.mjs +5 -3
  46. package/dist/components/layouts/NavBar.mjs.map +1 -1
  47. package/dist/components/layouts/NotificationsPopover.mjs +5 -3
  48. package/dist/components/layouts/NotificationsPopover.mjs.map +1 -1
  49. package/dist/components/layouts/ProfilePopover.mjs +6 -4
  50. package/dist/components/layouts/ProfilePopover.mjs.map +1 -1
  51. package/dist/components/layouts/UsersSelectorPopover.mjs +9 -7
  52. package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
  53. package/dist/components/modals/BuyCreditsModal.mjs +17 -18
  54. package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
  55. package/dist/components/modals/CreditsDisabledModal.mjs +6 -4
  56. package/dist/components/modals/CreditsDisabledModal.mjs.map +1 -1
  57. package/dist/components/modals/PaidPlanRequiredModal.mjs +5 -3
  58. package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
  59. package/dist/components/modals/cards/AddCardModal.mjs +64 -46
  60. package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
  61. package/dist/components/modals/cards/CannotDeleteCardModal.mjs +9 -7
  62. package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
  63. package/dist/components/modals/cards/CardFormFields.mjs +65 -51
  64. package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
  65. package/dist/components/modals/cards/DeleteCardModal.mjs +10 -8
  66. package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
  67. package/dist/components/navigation/CancelledSubscriptionBanner.mjs +4 -2
  68. package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
  69. package/dist/components/navigation/OverdueInvoiceBanner.mjs +4 -2
  70. package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
  71. package/dist/components/navigation/PendingCancellationBanner.mjs +4 -6
  72. package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
  73. package/dist/components/navigation/ProjectSelectorPopover.mjs +8 -6
  74. package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
  75. package/dist/components/navigation/UpcomingInvoiceBanner.mjs +4 -6
  76. package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
  77. package/dist/components/navigation/subcomponents/BottomLinks.mjs +5 -3
  78. package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
  79. package/dist/components/navigation/subcomponents/CreditsCard.mjs +3 -1
  80. package/dist/components/navigation/subcomponents/CreditsCard.mjs.map +1 -1
  81. package/dist/components/navigation/subcomponents/PlanCard.mjs +3 -1
  82. package/dist/components/navigation/subcomponents/PlanCard.mjs.map +1 -1
  83. package/dist/components/navigation/subcomponents/ProjectSelector.mjs +5 -3
  84. package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
  85. package/dist/components/pages/NotFoundPage.mjs +5 -3
  86. package/dist/components/pages/NotFoundPage.mjs.map +1 -1
  87. package/dist/components/pages/notifications/Notifications.mjs +13 -10
  88. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  89. package/dist/components/ui/buttons/CopyButton.mjs +9 -5
  90. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  91. package/dist/components/ui/data-display/CardItem.mjs +7 -5
  92. package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
  93. package/dist/components/ui/data-display/PaymentInfoCard.mjs +10 -8
  94. package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
  95. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
  96. package/dist/components/ui/feedback/DefaultCircularProgress.mjs +3 -1
  97. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  98. package/dist/components/ui/form/ComboboxField.mjs +11 -6
  99. package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
  100. package/dist/components/ui/form/DatePicker.mjs +5 -2
  101. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  102. package/dist/components/ui/form/DateRangePicker.mjs +5 -2
  103. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  104. package/dist/components/ui/form/PhoneInput.mjs +5 -3
  105. package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
  106. package/dist/components/ui/form/SelectField.mjs +6 -3
  107. package/dist/components/ui/form/SelectField.mjs.map +1 -1
  108. package/dist/components/widgets/ImageUpload/ImageCropModal.mjs +11 -18
  109. package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
  110. package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs +6 -15
  111. package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
  112. package/dist/i18n/config.mjs +13 -0
  113. package/dist/i18n/config.mjs.map +1 -0
  114. package/dist/i18n/country-language.mjs +74 -0
  115. package/dist/i18n/country-language.mjs.map +1 -0
  116. package/dist/i18n/messages/en-us.mjs +494 -0
  117. package/dist/i18n/messages/en-us.mjs.map +1 -0
  118. package/dist/i18n/messages/es-es.mjs +494 -0
  119. package/dist/i18n/messages/es-es.mjs.map +1 -0
  120. package/dist/i18n/messages/index.mjs +16 -0
  121. package/dist/i18n/messages/index.mjs.map +1 -0
  122. package/dist/i18n/messages/pt-br.mjs +507 -0
  123. package/dist/i18n/messages/pt-br.mjs.map +1 -0
  124. package/dist/i18n/normalize.mjs +12 -0
  125. package/dist/i18n/normalize.mjs.map +1 -0
  126. package/dist/i18n/resolve-locale.mjs +42 -0
  127. package/dist/i18n/resolve-locale.mjs.map +1 -0
  128. package/dist/i18n.mjs +14 -0
  129. package/dist/i18n.mjs.map +1 -0
  130. package/dist/index.mjs +19 -3
  131. package/dist/index.mjs.map +1 -1
  132. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs +20 -0
  133. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -0
  134. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs +2 -1
  135. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
  136. package/dist/modules/images/utils/validate-image.mjs +8 -8
  137. package/dist/modules/images/utils/validate-image.mjs.map +1 -1
  138. package/dist/modules/plans/hooks/list-plans.hook.mjs +2 -2
  139. package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
  140. package/dist/modules/plans/types/plan.type.mjs +5 -1
  141. package/dist/modules/plans/types/plan.type.mjs.map +1 -1
  142. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs +61 -35
  143. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
  144. package/dist/modules/projects/services/projects.service.mjs +9 -0
  145. package/dist/modules/projects/services/projects.service.mjs.map +1 -1
  146. package/dist/modules/subscriptions/utils/periodicity.mjs +20 -14
  147. package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
  148. package/dist/providers/auth.provider.mjs +9 -1
  149. package/dist/providers/auth.provider.mjs.map +1 -1
  150. package/dist/server.mjs +2 -0
  151. package/dist/server.mjs.map +1 -1
  152. package/dist/utils/format/currency.mjs +32 -4
  153. package/dist/utils/format/currency.mjs.map +1 -1
  154. package/dist/utils/intl/cookie-domain.mjs +17 -0
  155. package/dist/utils/intl/cookie-domain.mjs.map +1 -0
  156. package/dist/utils/intl/locale-cookie.mjs +13 -0
  157. package/dist/utils/intl/locale-cookie.mjs.map +1 -0
  158. package/dist/utils/intl/locales.mjs +3 -2
  159. package/dist/utils/intl/locales.mjs.map +1 -1
  160. package/package.json +7 -1
  161. package/src/components/account/ConfigurationsMyAccountModal.tsx +10 -6
  162. package/src/components/account/ConfirmDeleteAccountModal.tsx +22 -13
  163. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +12 -10
  164. package/src/components/account/DeleteAccountModal.tsx +34 -24
  165. package/src/components/account/DisableTwoFactorAuthModal.tsx +11 -6
  166. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +8 -6
  167. package/src/components/account/TwoFactorAuthModal.tsx +33 -29
  168. package/src/components/account/constants.ts +8 -5
  169. package/src/components/account/hooks/useChangeEmailForm.tsx +5 -3
  170. package/src/components/account/hooks/useChangePasswordForm.tsx +20 -6
  171. package/src/components/account/hooks/useChangePhoneForm.tsx +16 -10
  172. package/src/components/account/hooks/useDisableTwoFactorAuthForm.tsx +20 -6
  173. package/src/components/account/hooks/useOtpVerification.tsx +16 -4
  174. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +21 -7
  175. package/src/components/account/sections/ChangeEmailModal.tsx +35 -21
  176. package/src/components/account/sections/ChangePasswordSection.tsx +10 -6
  177. package/src/components/account/sections/ChangePhoneModal.tsx +50 -22
  178. package/src/components/account/sections/MyProfileSection.tsx +37 -23
  179. package/src/components/account/sections/PreferencesSection.tsx +52 -25
  180. package/src/components/account/sections/SecuritySection.tsx +19 -10
  181. package/src/components/account/sections/TokenSection.tsx +22 -10
  182. package/src/components/layouts/AppMobileNavBar.tsx +1 -154
  183. package/src/components/layouts/NavBar.tsx +5 -3
  184. package/src/components/layouts/NotificationsPopover.tsx +5 -3
  185. package/src/components/layouts/ProfilePopover.tsx +6 -4
  186. package/src/components/layouts/UsersSelectorPopover.tsx +9 -7
  187. package/src/components/modals/BuyCreditsModal.tsx +18 -16
  188. package/src/components/modals/CreditsDisabledModal.tsx +6 -6
  189. package/src/components/modals/PaidPlanRequiredModal.tsx +5 -3
  190. package/src/components/modals/cards/AddCardModal.tsx +89 -62
  191. package/src/components/modals/cards/CannotDeleteCardModal.tsx +9 -8
  192. package/src/components/modals/cards/CardFormFields.tsx +93 -75
  193. package/src/components/modals/cards/DeleteCardModal.tsx +10 -8
  194. package/src/components/navigation/CancelledSubscriptionBanner.tsx +4 -2
  195. package/src/components/navigation/OverdueInvoiceBanner.tsx +4 -2
  196. package/src/components/navigation/PendingCancellationBanner.tsx +4 -2
  197. package/src/components/navigation/ProjectSelectorPopover.tsx +8 -6
  198. package/src/components/navigation/UpcomingInvoiceBanner.tsx +4 -2
  199. package/src/components/navigation/subcomponents/BottomLinks.tsx +5 -3
  200. package/src/components/navigation/subcomponents/CreditsCard.tsx +3 -1
  201. package/src/components/navigation/subcomponents/PlanCard.tsx +3 -1
  202. package/src/components/navigation/subcomponents/ProjectSelector.tsx +5 -3
  203. package/src/components/pages/NotFoundPage.tsx +5 -3
  204. package/src/components/pages/notifications/Notifications.tsx +13 -10
  205. package/src/components/ui/buttons/CopyButton.tsx +10 -5
  206. package/src/components/ui/data-display/CardItem.tsx +7 -5
  207. package/src/components/ui/data-display/PaymentInfoCard.tsx +10 -8
  208. package/src/components/ui/feedback/CircularProgress.tsx +4 -0
  209. package/src/components/ui/feedback/DefaultCircularProgress.tsx +3 -1
  210. package/src/components/ui/form/ComboboxField.tsx +11 -6
  211. package/src/components/ui/form/DatePicker.tsx +5 -2
  212. package/src/components/ui/form/DateRangePicker.tsx +5 -2
  213. package/src/components/ui/form/PhoneInput.tsx +5 -3
  214. package/src/components/ui/form/SelectField.tsx +6 -3
  215. package/src/components/widgets/ImageUpload/ImageCropModal.tsx +19 -11
  216. package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +6 -5
  217. package/src/i18n/config.ts +17 -0
  218. package/src/i18n/country-language.ts +60 -0
  219. package/src/i18n/messages/en-us.ts +514 -0
  220. package/src/i18n/messages/es-es.ts +515 -0
  221. package/src/i18n/messages/index.ts +24 -0
  222. package/src/i18n/messages/pt-br.ts +538 -0
  223. package/src/i18n/normalize.ts +15 -0
  224. package/src/i18n/resolve-locale.ts +77 -0
  225. package/src/i18n.ts +10 -0
  226. package/src/index.ts +13 -2
  227. package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -0
  228. package/src/modules/cards/hooks/handle-delete-card.hook.ts +8 -3
  229. package/src/modules/images/utils/validate-image.ts +23 -8
  230. package/src/modules/plans/hooks/list-plans.hook.ts +2 -2
  231. package/src/modules/plans/types/plan.type.ts +4 -0
  232. package/src/modules/plans/utils/map-api-plan-to-ui.ts +109 -47
  233. package/src/modules/projects/services/projects.service.ts +12 -0
  234. package/src/modules/subscriptions/utils/periodicity.ts +29 -12
  235. package/src/providers/auth.provider.tsx +13 -1
  236. package/src/server.ts +2 -0
  237. package/src/utils/format/currency.ts +62 -7
  238. package/src/utils/intl/cookie-domain.ts +29 -0
  239. package/src/utils/intl/locale-cookie.ts +18 -0
  240. package/src/utils/intl/locales.ts +3 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/pages/notifications/Notifications.tsx"],"sourcesContent":["'use client';\n\nimport { IconBell, IconCheck, IconLoader2 } from '@tabler/icons-react';\nimport { Button } from \"../../ui/buttons/Button\";\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"../../ui/data-display/Tabs\";\nimport { useInfiniteMessages, useMarkAllMessagesAsRead } from \"../../../modules/users/hooks/messages.hook\";\nimport NotificationCard from \"../../widgets/notifications/NotificationCard\";\nimport { Toast } from \"../../ui/feedback/Toast\";\nimport { formatDistanceToNow } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { toast } from \"sonner\";\nimport React from \"react\";\nimport Link from \"next/link\";\n\nfunction parseNotificationUrl(raw: string): string | null {\n if (!raw) return null;\n const match = raw.match(/href=\"([^\"]+)\"/);\n return match ? match[1] : raw.startsWith('/') ? raw : null;\n}\n\nfunction NotificationsList({\n pages,\n isFetchingNextPage,\n hasNextPage,\n fetchNextPage,\n}: {\n pages: ReturnType<typeof useInfiniteMessages>[\"data\"];\n isFetchingNextPage: boolean;\n hasNextPage: boolean;\n fetchNextPage: () => void;\n}) {\n const notifications = pages?.pages.flatMap((p) => p.data) ?? [];\n\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\n const target = e.currentTarget;\n const nearBottom =\n target.scrollTop + target.clientHeight >= target.scrollHeight - 50;\n if (!nearBottom) return;\n if (hasNextPage && !isFetchingNextPage) {\n fetchNextPage();\n }\n };\n\n if (notifications.length === 0 && !isFetchingNextPage) {\n return (\n <div className=\"rounded-lg border border-zinc-200 bg-white\">\n <div className=\"flex flex-col items-center justify-center py-16 gap-2\">\n <span className=\"paragraph-medium-regular text-zinc-500\">Nenhuma notificação encontrada.</span>\n </div>\n </div>\n );\n }\n\n return (\n <div\n className=\"flex flex-col border border-gray-200 rounded-lg w-full bg-white max-h-[70vh] overflow-y-auto custom-scrollbar\"\n onScroll={handleScroll}\n >\n {notifications.map((notification, index) => {\n const detailsUrl = parseNotificationUrl(notification.url);\n return (\n <NotificationCard\n key={notification.id}\n icon={<IconBell size={20} className=\"text-pages-600\" />}\n iconBgColor=\"bg-zinc-50\"\n title={notification.subject}\n description={notification.message}\n gapPx={8}\n time={formatDistanceToNow(new Date(notification.datetime_add), {\n addSuffix: true,\n locale: ptBR,\n })}\n isUnread={notification.status === 1}\n showBorder={index < notifications.length - 1}\n actions={\n detailsUrl ? (\n <Button asChild variant=\"secondary\" className=\"h-8! px-3! paragraph-small-semibold\">\n <Link href={detailsUrl}>Detalhes</Link>\n </Button>\n ) : undefined\n }\n />\n );\n })}\n {isFetchingNextPage && (\n <div className=\"flex items-center justify-center py-4\">\n <IconLoader2 size={20} className=\"animate-spin text-gray-400\" />\n </div>\n )}\n </div>\n );\n}\n\nexport function NotificationPageContent() {\n const unreadNotifications = useInfiniteMessages({\n readed: false,\n type: \"notification\",\n order: \"desc\",\n });\n const allNotifications = useInfiniteMessages({\n type: \"notification\",\n order: \"desc\",\n });\n\n const totalAll = allNotifications.data?.pages[0]?.total ?? 0;\n const totalUnread = unreadNotifications.data?.pages[0]?.total ?? 0;\n\n const { mutate: markAllAsRead, isPending: isMarkingAll } = useMarkAllMessagesAsRead();\n\n const handleMarkAllAsRead = () => {\n markAllAsRead(undefined, {\n onSuccess: () => {\n toast.custom((t) => (\n <Toast variant=\"success\" message=\"Todas as notificações foram marcadas como lidas\" toastId={t} />\n ));\n },\n onError: () => {\n toast.custom((t) => (\n <Toast variant=\"error\" message=\"Erro ao marcar notificações como lidas\" toastId={t} />\n ));\n },\n });\n };\n\n return (\n <div className=\"flex flex-col gap-6 lg:gap-8\">\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"flex flex-col gap-2\">\n <h1 className=\"title-large-semibold text-gray-950\">\n Notificações\n </h1>\n <p className=\"paragraph-small-regular text-gray-600 hidden lg:block\">\n Tenha controle total sobre páginas, experiências e conversões.\n </p>\n </div>\n <Button\n variant={\"secondary\"}\n className=\"h-10! lg:h-12! shrink-0\"\n onClick={handleMarkAllAsRead}\n disabled={isMarkingAll || totalUnread === 0}\n >\n {isMarkingAll ? <IconLoader2 size={20} className=\"animate-spin\" /> : <IconCheck size={20} />}\n <span className=\"lg:block hidden\">Marcar todos como lidos</span>\n <span className=\"lg:hidden\">Marcar como lidos</span>\n </Button>\n </div>\n <Tabs\n defaultValue=\"all\"\n className=\"flex flex-col w-full bg-transparent gap-6 lg:gap-8\"\n >\n <TabsList className=\"h-auto pb-0 bg-transparent\">\n <TabsTrigger className=\"gap-2\" value=\"all\">\n Todas as notificações{\" \"}\n <span className=\"text-gray-500\">({totalAll})</span>\n </TabsTrigger>\n <TabsTrigger className=\"gap-2\" value=\"unreads\" disabled={totalUnread === 0}>\n Não lidas{\" \"}\n <span className=\"text-gray-500\">({totalUnread})</span>\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"all\">\n <NotificationsList\n pages={allNotifications.data}\n isFetchingNextPage={allNotifications.isFetchingNextPage}\n hasNextPage={allNotifications.hasNextPage}\n fetchNextPage={allNotifications.fetchNextPage}\n />\n </TabsContent>\n\n <TabsContent value=\"unreads\">\n <NotificationsList\n pages={unreadNotifications.data}\n isFetchingNextPage={unreadNotifications.isFetchingNextPage}\n hasNextPage={unreadNotifications.hasNextPage}\n fetchNextPage={unreadNotifications.fetchNextPage}\n />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/pages/notifications/Notifications.tsx"],"sourcesContent":["'use client';\n\nimport { IconBell, IconCheck, IconLoader2 } from '@tabler/icons-react';\nimport { useTranslations } from 'next-intl';\nimport { Button } from \"../../ui/buttons/Button\";\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"../../ui/data-display/Tabs\";\nimport { useInfiniteMessages, useMarkAllMessagesAsRead } from \"../../../modules/users/hooks/messages.hook\";\nimport NotificationCard from \"../../widgets/notifications/NotificationCard\";\nimport { Toast } from \"../../ui/feedback/Toast\";\nimport { formatDistanceToNow } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { toast } from \"sonner\";\nimport React from \"react\";\nimport Link from \"next/link\";\n\nfunction parseNotificationUrl(raw: string): string | null {\n if (!raw) return null;\n const match = raw.match(/href=\"([^\"]+)\"/);\n return match ? match[1] : raw.startsWith('/') ? raw : null;\n}\n\nfunction NotificationsList({\n pages,\n isFetchingNextPage,\n hasNextPage,\n fetchNextPage,\n}: {\n pages: ReturnType<typeof useInfiniteMessages>[\"data\"];\n isFetchingNextPage: boolean;\n hasNextPage: boolean;\n fetchNextPage: () => void;\n}) {\n const translate = useTranslations();\n const notifications = pages?.pages.flatMap((p) => p.data) ?? [];\n\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\n const target = e.currentTarget;\n const nearBottom =\n target.scrollTop + target.clientHeight >= target.scrollHeight - 50;\n if (!nearBottom) return;\n if (hasNextPage && !isFetchingNextPage) {\n fetchNextPage();\n }\n };\n\n if (notifications.length === 0 && !isFetchingNextPage) {\n return (\n <div className=\"rounded-lg border border-zinc-200 bg-white\">\n <div className=\"flex flex-col items-center justify-center py-16 gap-2\">\n <span className=\"paragraph-medium-regular text-zinc-500\">{translate('common.notifications.page.empty')}</span>\n </div>\n </div>\n );\n }\n\n return (\n <div\n className=\"flex flex-col border border-gray-200 rounded-lg w-full bg-white max-h-[70vh] overflow-y-auto custom-scrollbar\"\n onScroll={handleScroll}\n >\n {notifications.map((notification, index) => {\n const detailsUrl = parseNotificationUrl(notification.url);\n return (\n <NotificationCard\n key={notification.id}\n icon={<IconBell size={20} className=\"text-pages-600\" />}\n iconBgColor=\"bg-zinc-50\"\n title={notification.subject}\n description={notification.message}\n gapPx={8}\n time={formatDistanceToNow(new Date(notification.datetime_add), {\n addSuffix: true,\n locale: ptBR,\n })}\n isUnread={notification.status === 1}\n showBorder={index < notifications.length - 1}\n actions={\n detailsUrl ? (\n <Button asChild variant=\"secondary\" className=\"h-8! px-3! paragraph-small-semibold\">\n <Link href={detailsUrl}>{translate('common.notifications.page.details')}</Link>\n </Button>\n ) : undefined\n }\n />\n );\n })}\n {isFetchingNextPage && (\n <div className=\"flex items-center justify-center py-4\">\n <IconLoader2 size={20} className=\"animate-spin text-gray-400\" />\n </div>\n )}\n </div>\n );\n}\n\nexport function NotificationPageContent() {\n const translate = useTranslations();\n const unreadNotifications = useInfiniteMessages({\n readed: false,\n type: \"notification\",\n order: \"desc\",\n });\n const allNotifications = useInfiniteMessages({\n type: \"notification\",\n order: \"desc\",\n });\n\n const totalAll = allNotifications.data?.pages[0]?.total ?? 0;\n const totalUnread = unreadNotifications.data?.pages[0]?.total ?? 0;\n\n const { mutate: markAllAsRead, isPending: isMarkingAll } = useMarkAllMessagesAsRead();\n\n const handleMarkAllAsRead = () => {\n markAllAsRead(undefined, {\n onSuccess: () => {\n toast.custom((t) => (\n <Toast variant=\"success\" message={translate('common.notifications.page.markAllSuccess')} toastId={t} />\n ));\n },\n onError: () => {\n toast.custom((t) => (\n <Toast variant=\"error\" message={translate('common.notifications.page.markAllError')} toastId={t} />\n ));\n },\n });\n };\n\n return (\n <div className=\"flex flex-col gap-6 lg:gap-8\">\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"flex flex-col gap-2\">\n <h1 className=\"title-large-semibold text-gray-950\">\n {translate('common.notifications.page.title')}\n </h1>\n <p className=\"paragraph-small-regular text-gray-600 hidden lg:block\">\n {translate('common.notifications.page.subtitle')}\n </p>\n </div>\n <Button\n variant={\"secondary\"}\n className=\"h-10! lg:h-12! shrink-0\"\n onClick={handleMarkAllAsRead}\n disabled={isMarkingAll || totalUnread === 0}\n >\n {isMarkingAll ? <IconLoader2 size={20} className=\"animate-spin\" /> : <IconCheck size={20} />}\n <span className=\"lg:block hidden\">{translate('common.notifications.page.markAllReadDesktop')}</span>\n <span className=\"lg:hidden\">{translate('common.notifications.page.markAllReadMobile')}</span>\n </Button>\n </div>\n <Tabs\n defaultValue=\"all\"\n className=\"flex flex-col w-full bg-transparent gap-6 lg:gap-8\"\n >\n <TabsList className=\"h-auto pb-0 bg-transparent\">\n <TabsTrigger className=\"gap-2\" value=\"all\">\n {translate('common.notifications.page.tabAll')}{\" \"}\n <span className=\"text-gray-500\">({totalAll})</span>\n </TabsTrigger>\n <TabsTrigger className=\"gap-2\" value=\"unreads\" disabled={totalUnread === 0}>\n {translate('common.notifications.page.tabUnread')}{\" \"}\n <span className=\"text-gray-500\">({totalUnread})</span>\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"all\">\n <NotificationsList\n pages={allNotifications.data}\n isFetchingNextPage={allNotifications.isFetchingNextPage}\n hasNextPage={allNotifications.hasNextPage}\n fetchNextPage={allNotifications.fetchNextPage}\n />\n </TabsContent>\n\n <TabsContent value=\"unreads\">\n <NotificationsList\n pages={unreadNotifications.data}\n isFetchingNextPage={unreadNotifications.isFetchingNextPage}\n hasNextPage={unreadNotifications.hasNextPage}\n fetchNextPage={unreadNotifications.fetchNextPage}\n />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useTranslations } from "next-intl";
3
4
  import { IconCheck, IconCopy } from "@tabler/icons-react";
4
5
  import { toast } from "sonner";
5
6
  import { Toast } from "../feedback/Toast";
@@ -10,15 +11,18 @@ function CopyButton({
10
11
  textToCopy,
11
12
  size = 14,
12
13
  className,
13
- tooltipText = "Copiar link",
14
- successMessage = "Link copiado"
14
+ tooltipText,
15
+ successMessage
15
16
  }) {
17
+ const translate = useTranslations();
18
+ const resolvedTooltipText = tooltipText ?? translate("common.forms.copyButton.tooltipDefault");
19
+ const resolvedSuccessMessage = successMessage ?? translate("common.forms.copyButton.successDefault");
16
20
  const { isCopied, copy } = useCopyToClipboard({
17
21
  onSuccess: () => {
18
- toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: successMessage, toastId: t }));
22
+ toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: resolvedSuccessMessage, toastId: t }));
19
23
  },
20
24
  onError: () => {
21
- toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: "N\xE3o foi poss\xEDvel copiar o link", toastId: t }));
25
+ toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: translate("common.forms.copyButton.errorMessage"), toastId: t }));
22
26
  }
23
27
  });
24
28
  return /* @__PURE__ */ jsxs(Tooltip, { children: [
@@ -33,7 +37,7 @@ function CopyButton({
33
37
  children: /* @__PURE__ */ jsx("span", { className: cn("cursor-pointer text-gray-500", className), children: isCopied ? /* @__PURE__ */ jsx(IconCheck, { size }) : /* @__PURE__ */ jsx(IconCopy, { size }) })
34
38
  }
35
39
  ),
36
- /* @__PURE__ */ jsx(TooltipContent, { children: isCopied ? "Copiado!" : tooltipText })
40
+ /* @__PURE__ */ jsx(TooltipContent, { children: isCopied ? translate("common.actions.copied") : resolvedTooltipText })
37
41
  ] });
38
42
  }
39
43
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/buttons/CopyButton.tsx"],"sourcesContent":["'use client';\n\nimport { IconCheck, IconCopy } from '@tabler/icons-react';\nimport { toast } from \"sonner\";\nimport { Toast } from \"../feedback/Toast\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../overlay/Tooltip\";\nimport useCopyToClipboard from \"../../../hooks/copy-to-clipboard.hook\";\nimport { cn } from \"../../../infra/utils/clsx\";\n\ninterface CopyButtonProps {\n textToCopy: string;\n size?: number;\n className?: string;\n tooltipText?: string;\n successMessage?: string;\n}\n\nexport function CopyButton({\n textToCopy,\n size = 14,\n className,\n tooltipText = \"Copiar link\",\n successMessage = \"Link copiado\",\n}: CopyButtonProps) {\n const { isCopied, copy } = useCopyToClipboard({\n onSuccess: () => {\n toast.custom((t) => (\n <Toast variant=\"success\" message={successMessage} toastId={t} />\n ));\n },\n onError: () => {\n toast.custom((t) => (\n <Toast variant=\"error\" message=\"Não foi possível copiar o link\" toastId={t} />\n ));\n },\n });\n\n return (\n <Tooltip>\n <TooltipTrigger\n asChild\n onClick={(e: React.MouseEvent) => {\n e.stopPropagation();\n copy(textToCopy);\n }}\n >\n <span className={cn(\"cursor-pointer text-gray-500\", className)}>\n {isCopied ? <IconCheck size={size} /> : <IconCopy size={size} />}\n </span>\n </TooltipTrigger>\n <TooltipContent>{isCopied ? \"Copiado!\" : tooltipText}</TooltipContent>\n </Tooltip>\n );\n}\n"],"mappings":";AA2BQ,cAWJ,YAXI;AAzBR,SAAS,WAAW,gBAAgB;AACpC,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,OAAO,wBAAwB;AAC/B,SAAS,UAAU;AAUZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,cAAc;AAAA,EACd,iBAAiB;AACnB,GAAoB;AAClB,QAAM,EAAE,UAAU,KAAK,IAAI,mBAAmB;AAAA,IAC5C,WAAW,MAAM;AACf,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAS,gBAAgB,SAAS,GAAG,CAC/D;AAAA,IACH;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,wCAAiC,SAAS,GAAG,CAC7E;AAAA,IACH;AAAA,EACF,CAAC;AAED,SACE,qBAAC,WACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAO;AAAA,QACP,SAAS,CAAC,MAAwB;AAChC,YAAE,gBAAgB;AAClB,eAAK,UAAU;AAAA,QACjB;AAAA,QAEA,8BAAC,UAAK,WAAW,GAAG,gCAAgC,SAAS,GAC1D,qBAAW,oBAAC,aAAU,MAAY,IAAK,oBAAC,YAAS,MAAY,GAChE;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,kBAAgB,qBAAW,aAAa,aAAY;AAAA,KACvD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/buttons/CopyButton.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport { IconCheck, IconCopy } from '@tabler/icons-react';\nimport { toast } from \"sonner\";\nimport { Toast } from \"../feedback/Toast\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../overlay/Tooltip\";\nimport useCopyToClipboard from \"../../../hooks/copy-to-clipboard.hook\";\nimport { cn } from \"../../../infra/utils/clsx\";\n\ninterface CopyButtonProps {\n textToCopy: string;\n size?: number;\n className?: string;\n tooltipText?: string;\n successMessage?: string;\n}\n\nexport function CopyButton({\n textToCopy,\n size = 14,\n className,\n tooltipText,\n successMessage,\n}: CopyButtonProps) {\n const translate = useTranslations();\n const resolvedTooltipText = tooltipText ?? translate('common.forms.copyButton.tooltipDefault');\n const resolvedSuccessMessage = successMessage ?? translate('common.forms.copyButton.successDefault');\n\n const { isCopied, copy } = useCopyToClipboard({\n onSuccess: () => {\n toast.custom((t) => (\n <Toast variant=\"success\" message={resolvedSuccessMessage} toastId={t} />\n ));\n },\n onError: () => {\n toast.custom((t) => (\n <Toast variant=\"error\" message={translate('common.forms.copyButton.errorMessage')} toastId={t} />\n ));\n },\n });\n\n return (\n <Tooltip>\n <TooltipTrigger\n asChild\n onClick={(e: React.MouseEvent) => {\n e.stopPropagation();\n copy(textToCopy);\n }}\n >\n <span className={cn(\"cursor-pointer text-gray-500\", className)}>\n {isCopied ? <IconCheck size={size} /> : <IconCopy size={size} />}\n </span>\n </TooltipTrigger>\n <TooltipContent>{isCopied ? translate('common.actions.copied') : resolvedTooltipText}</TooltipContent>\n </Tooltip>\n );\n}\n"],"mappings":";AAgCQ,cAWJ,YAXI;AA9BR,SAAS,uBAAuB;AAChC,SAAS,WAAW,gBAAgB;AACpC,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,OAAO,wBAAwB;AAC/B,SAAS,UAAU;AAUZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,YAAY,gBAAgB;AAClC,QAAM,sBAAsB,eAAe,UAAU,wCAAwC;AAC7F,QAAM,yBAAyB,kBAAkB,UAAU,wCAAwC;AAEnG,QAAM,EAAE,UAAU,KAAK,IAAI,mBAAmB;AAAA,IAC5C,WAAW,MAAM;AACf,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAS,wBAAwB,SAAS,GAAG,CACvE;AAAA,IACH;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAS,UAAU,sCAAsC,GAAG,SAAS,GAAG,CAChG;AAAA,IACH;AAAA,EACF,CAAC;AAED,SACE,qBAAC,WACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAO;AAAA,QACP,SAAS,CAAC,MAAwB;AAChC,YAAE,gBAAgB;AAClB,eAAK,UAAU;AAAA,QACjB;AAAA,QAEA,8BAAC,UAAK,WAAW,GAAG,gCAAgC,SAAS,GAC1D,qBAAW,oBAAC,aAAU,MAAY,IAAK,oBAAC,YAAS,MAAY,GAChE;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,kBAAgB,qBAAW,UAAU,uBAAuB,IAAI,qBAAoB;AAAA,KACvF;AAEJ;","names":[]}
@@ -9,6 +9,7 @@ import { Toast } from "../feedback/Toast";
9
9
  import { CardBrandIcon } from "./CardBrandIcons";
10
10
  import { useSetDefaultCard } from "../../../modules/cards/hooks/set-default-card.hook";
11
11
  import { useHandleDeleteCard } from "../../../modules/cards/hooks/handle-delete-card.hook";
12
+ import { useTranslations } from "next-intl";
12
13
  function CardItem({
13
14
  card,
14
15
  isSelected,
@@ -19,6 +20,7 @@ function CardItem({
19
20
  onAfterDelete,
20
21
  onAfterSetDefault
21
22
  }) {
23
+ const translate = useTranslations();
22
24
  const [popoverOpen, setPopoverOpen] = useState(false);
23
25
  const setDefaultCardMutation = useSetDefaultCard();
24
26
  const handleDeleteCard = useHandleDeleteCard({ onAfterDelete });
@@ -29,7 +31,7 @@ function CardItem({
29
31
  Toast,
30
32
  {
31
33
  variant: "success",
32
- message: "Cart\xE3o definido como padr\xE3o",
34
+ message: translate("common.cards.item.setDefaultSuccess"),
33
35
  toastId: t
34
36
  }
35
37
  ));
@@ -40,7 +42,7 @@ function CardItem({
40
42
  Toast,
41
43
  {
42
44
  variant: "error",
43
- message: "Erro ao definir cart\xE3o padr\xE3o",
45
+ message: translate("common.cards.item.setDefaultError"),
44
46
  toastId: t
45
47
  }
46
48
  ));
@@ -64,7 +66,7 @@ function CardItem({
64
66
  (card.number ?? "").replaceAll(/\D/g, "").slice(-4)
65
67
  ] })
66
68
  ] }),
67
- card.is_default && /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-semibold text-zinc-600 bg-zinc-100 px-2 py-0.5 rounded-lg whitespace-nowrap", children: "Padr\xE3o" }),
69
+ card.is_default && /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-semibold text-zinc-600 bg-zinc-100 px-2 py-0.5 rounded-lg whitespace-nowrap", children: translate("common.cards.item.defaultBadge") }),
68
70
  /* @__PURE__ */ jsx(CardBrandIcon, { brand: card.brand }),
69
71
  renderMenu && /* @__PURE__ */ jsxs(Popover, { open: popoverOpen, onOpenChange: setPopoverOpen, children: [
70
72
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
@@ -86,7 +88,7 @@ function CardItem({
86
88
  NavBarItem,
87
89
  {
88
90
  icon: /* @__PURE__ */ jsx(IconStar, { size: 18, className: "text-zinc-400" }),
89
- label: "Tornar padr\xE3o",
91
+ label: translate("common.cards.item.makeDefault"),
90
92
  onClick: () => {
91
93
  setPopoverOpen(false);
92
94
  handleSetDefault();
@@ -97,7 +99,7 @@ function CardItem({
97
99
  NavBarItem,
98
100
  {
99
101
  icon: /* @__PURE__ */ jsx(IconTrash, { size: 18, className: "text-zinc-400" }),
100
- label: "Excluir",
102
+ label: translate("common.actions.delete"),
101
103
  onClick: () => {
102
104
  setPopoverOpen(false);
103
105
  handleDeleteCard(card);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/data-display/CardItem.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport { IconDotsVertical, IconStar, IconTrash } from '@tabler/icons-react';\nimport { Popover, PopoverContent, PopoverTrigger } from '../overlay/Popover';\nimport { NavBarItem } from '../../layouts/NavBarItem';\nimport { Toast } from '../feedback/Toast';\nimport { CardBrandIcon } from './CardBrandIcons';\nimport { useSetDefaultCard } from '../../../modules/cards/hooks/set-default-card.hook';\nimport { useHandleDeleteCard } from '../../../modules/cards/hooks/handle-delete-card.hook';\nimport type { Card } from '../../../modules/cards/types';\n\ntype CardItemProps = {\n card: Card;\n isSelected?: boolean;\n onSelect?: () => void;\n showMenu?: boolean;\n hideDelete?: boolean;\n hideSetDefault?: boolean;\n onAfterDelete?: (card: Card) => void;\n onAfterSetDefault?: (card: Card) => void;\n};\n\nexport function CardItem({\n card,\n isSelected,\n onSelect,\n showMenu = true,\n hideDelete = false,\n hideSetDefault = false,\n onAfterDelete,\n onAfterSetDefault,\n}: CardItemProps) {\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const setDefaultCardMutation = useSetDefaultCard();\n\n const handleDeleteCard = useHandleDeleteCard({ onAfterDelete });\n\n const handleSetDefault = () => {\n setDefaultCardMutation.mutate(card.id.toString(), {\n onSuccess: () => {\n toast.custom((t) => (\n <Toast\n variant=\"success\"\n message=\"Cartão definido como padrão\"\n toastId={t}\n />\n ));\n onAfterSetDefault?.(card);\n },\n onError: () => {\n toast.custom((t) => (\n <Toast\n variant=\"error\"\n message=\"Erro ao definir cartão padrão\"\n toastId={t}\n />\n ));\n },\n });\n };\n\n const menuHasSetDefault = !hideSetDefault && !card.is_default;\n const menuHasDelete = !hideDelete;\n const hasMenuItems = menuHasSetDefault || menuHasDelete;\n const renderMenu = showMenu && hasMenuItems;\n\n return (\n <div\n className={`flex items-center p-4 cursor-pointer transition-colors gap-3 rounded-lg border ${\n isSelected\n ? 'bg-zinc-50 border-zinc-950'\n : 'bg-white border-zinc-200 hover:bg-zinc-50'\n }`}\n onClick={onSelect}\n >\n <div className=\"flex flex-col gap-0.5 flex-1 min-w-0\">\n <span className=\"paragraph-small-semibold text-zinc-950 truncate\">\n {card.name}\n </span>\n <span className=\"paragraph-small-medium text-zinc-950\">\n •••• {(card.number ?? '').replaceAll(/\\D/g, '').slice(-4)}\n </span>\n </div>\n {card.is_default && (\n <span className=\"paragraph-xsmall-semibold text-zinc-600 bg-zinc-100 px-2 py-0.5 rounded-lg whitespace-nowrap\">\n Padrão\n </span>\n )}\n <CardBrandIcon brand={card.brand} />\n {renderMenu && (\n <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>\n <PopoverTrigger asChild>\n <button\n className=\"size-10 flex items-center justify-center rounded-lg hover:bg-zinc-100 cursor-pointer\"\n onClick={(e) => e.stopPropagation()}\n >\n <IconDotsVertical className=\"size-5 text-zinc-500\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n className=\"w-[180px] p-2 bg-white rounded-2xl border border-zinc-200\"\n onClick={(e) => e.stopPropagation()}\n >\n {menuHasSetDefault && (\n <NavBarItem\n icon={<IconStar size={18} className=\"text-zinc-400\" />}\n label=\"Tornar padrão\"\n onClick={() => {\n setPopoverOpen(false);\n handleSetDefault();\n }}\n />\n )}\n {menuHasDelete && (\n <NavBarItem\n icon={<IconTrash size={18} className=\"text-zinc-400\" />}\n label=\"Excluir\"\n onClick={() => {\n setPopoverOpen(false);\n handleDeleteCard(card);\n }}\n />\n )}\n </PopoverContent>\n </Popover>\n )}\n </div>\n );\n}\n"],"mappings":";AA4CU,cAsCF,YAtCE;AA1CV,SAAS,gBAAgB;AACzB,SAAS,aAAa;AACtB,SAAS,kBAAkB,UAAU,iBAAiB;AACtD,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AAc7B,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AAEpD,QAAM,yBAAyB,kBAAkB;AAEjD,QAAM,mBAAmB,oBAAoB,EAAE,cAAc,CAAC;AAE9D,QAAM,mBAAmB,MAAM;AAC7B,2BAAuB,OAAO,KAAK,GAAG,SAAS,GAAG;AAAA,MAChD,WAAW,MAAM;AACf,cAAM,OAAO,CAAC,MACZ;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,SAAQ;AAAA,YACR,SAAS;AAAA;AAAA,QACX,CACD;AACD,4BAAoB,IAAI;AAAA,MAC1B;AAAA,MACA,SAAS,MAAM;AACb,cAAM,OAAO,CAAC,MACZ;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,SAAQ;AAAA,YACR,SAAS;AAAA;AAAA,QACX,CACD;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,oBAAoB,CAAC,kBAAkB,CAAC,KAAK;AACnD,QAAM,gBAAgB,CAAC;AACvB,QAAM,eAAe,qBAAqB;AAC1C,QAAM,aAAa,YAAY;AAE/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,kFACT,aACI,+BACA,2CACN;AAAA,MACA,SAAS;AAAA,MAET;AAAA,6BAAC,SAAI,WAAU,wCACb;AAAA,8BAAC,UAAK,WAAU,mDACb,eAAK,MACR;AAAA,UACA,qBAAC,UAAK,WAAU,wCAAuC;AAAA;AAAA,aAC9C,KAAK,UAAU,IAAI,WAAW,OAAO,EAAE,EAAE,MAAM,EAAE;AAAA,aAC1D;AAAA,WACF;AAAA,QACC,KAAK,cACJ,oBAAC,UAAK,WAAU,gGAA+F,uBAE/G;AAAA,QAEF,oBAAC,iBAAc,OAAO,KAAK,OAAO;AAAA,QACjC,cACC,qBAAC,WAAQ,MAAM,aAAa,cAAc,gBACxC;AAAA,8BAAC,kBAAe,SAAO,MACrB;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,cAElC,8BAAC,oBAAiB,WAAU,wBAAuB;AAAA;AAAA,UACrD,GACF;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,WAAU;AAAA,cACV,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,cAEjC;AAAA,qCACC;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAM,oBAAC,YAAS,MAAM,IAAI,WAAU,iBAAgB;AAAA,oBACpD,OAAM;AAAA,oBACN,SAAS,MAAM;AACb,qCAAe,KAAK;AACpB,uCAAiB;AAAA,oBACnB;AAAA;AAAA,gBACF;AAAA,gBAED,iBACC;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAM,oBAAC,aAAU,MAAM,IAAI,WAAU,iBAAgB;AAAA,oBACrD,OAAM;AAAA,oBACN,SAAS,MAAM;AACb,qCAAe,KAAK;AACpB,uCAAiB,IAAI;AAAA,oBACvB;AAAA;AAAA,gBACF;AAAA;AAAA;AAAA,UAEJ;AAAA,WACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/data-display/CardItem.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport { IconDotsVertical, IconStar, IconTrash } from '@tabler/icons-react';\nimport { Popover, PopoverContent, PopoverTrigger } from '../overlay/Popover';\nimport { NavBarItem } from '../../layouts/NavBarItem';\nimport { Toast } from '../feedback/Toast';\nimport { CardBrandIcon } from './CardBrandIcons';\nimport { useSetDefaultCard } from '../../../modules/cards/hooks/set-default-card.hook';\nimport { useHandleDeleteCard } from '../../../modules/cards/hooks/handle-delete-card.hook';\nimport type { Card } from '../../../modules/cards/types';\nimport { useTranslations } from 'next-intl';\n\ntype CardItemProps = {\n card: Card;\n isSelected?: boolean;\n onSelect?: () => void;\n showMenu?: boolean;\n hideDelete?: boolean;\n hideSetDefault?: boolean;\n onAfterDelete?: (card: Card) => void;\n onAfterSetDefault?: (card: Card) => void;\n};\n\nexport function CardItem({\n card,\n isSelected,\n onSelect,\n showMenu = true,\n hideDelete = false,\n hideSetDefault = false,\n onAfterDelete,\n onAfterSetDefault,\n}: CardItemProps) {\n const translate = useTranslations();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const setDefaultCardMutation = useSetDefaultCard();\n\n const handleDeleteCard = useHandleDeleteCard({ onAfterDelete });\n\n const handleSetDefault = () => {\n setDefaultCardMutation.mutate(card.id.toString(), {\n onSuccess: () => {\n toast.custom((t) => (\n <Toast\n variant=\"success\"\n message={translate('common.cards.item.setDefaultSuccess')}\n toastId={t}\n />\n ));\n onAfterSetDefault?.(card);\n },\n onError: () => {\n toast.custom((t) => (\n <Toast\n variant=\"error\"\n message={translate('common.cards.item.setDefaultError')}\n toastId={t}\n />\n ));\n },\n });\n };\n\n const menuHasSetDefault = !hideSetDefault && !card.is_default;\n const menuHasDelete = !hideDelete;\n const hasMenuItems = menuHasSetDefault || menuHasDelete;\n const renderMenu = showMenu && hasMenuItems;\n\n return (\n <div\n className={`flex items-center p-4 cursor-pointer transition-colors gap-3 rounded-lg border ${\n isSelected\n ? 'bg-zinc-50 border-zinc-950'\n : 'bg-white border-zinc-200 hover:bg-zinc-50'\n }`}\n onClick={onSelect}\n >\n <div className=\"flex flex-col gap-0.5 flex-1 min-w-0\">\n <span className=\"paragraph-small-semibold text-zinc-950 truncate\">\n {card.name}\n </span>\n <span className=\"paragraph-small-medium text-zinc-950\">\n •••• {(card.number ?? '').replaceAll(/\\D/g, '').slice(-4)}\n </span>\n </div>\n {card.is_default && (\n <span className=\"paragraph-xsmall-semibold text-zinc-600 bg-zinc-100 px-2 py-0.5 rounded-lg whitespace-nowrap\">\n {translate('common.cards.item.defaultBadge')}\n </span>\n )}\n <CardBrandIcon brand={card.brand} />\n {renderMenu && (\n <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>\n <PopoverTrigger asChild>\n <button\n className=\"size-10 flex items-center justify-center rounded-lg hover:bg-zinc-100 cursor-pointer\"\n onClick={(e) => e.stopPropagation()}\n >\n <IconDotsVertical className=\"size-5 text-zinc-500\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n className=\"w-[180px] p-2 bg-white rounded-2xl border border-zinc-200\"\n onClick={(e) => e.stopPropagation()}\n >\n {menuHasSetDefault && (\n <NavBarItem\n icon={<IconStar size={18} className=\"text-zinc-400\" />}\n label={translate('common.cards.item.makeDefault')}\n onClick={() => {\n setPopoverOpen(false);\n handleSetDefault();\n }}\n />\n )}\n {menuHasDelete && (\n <NavBarItem\n icon={<IconTrash size={18} className=\"text-zinc-400\" />}\n label={translate('common.actions.delete')}\n onClick={() => {\n setPopoverOpen(false);\n handleDeleteCard(card);\n }}\n />\n )}\n </PopoverContent>\n </Popover>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -8,6 +8,7 @@ import useIsMobile from "../../../hooks/useIsMobile";
8
8
  import { useCards } from "../../../modules/cards/hooks/cards.hook";
9
9
  import { useModalManager } from "../../../store/useModalManager";
10
10
  import { useIsDefaultWhitelabel } from "../../../providers/whitelabel.provider";
11
+ import { useTranslations } from "next-intl";
11
12
  function PaymentInfoCard({
12
13
  email,
13
14
  selectedCardId,
@@ -17,6 +18,7 @@ function PaymentInfoCard({
17
18
  hideDelete,
18
19
  hideSetDefault
19
20
  }) {
21
+ const translate = useTranslations();
20
22
  const isMobile = useIsMobile();
21
23
  const { openModal } = useModalManager();
22
24
  const isDefaultWl = useIsDefaultWhitelabel();
@@ -60,11 +62,11 @@ function PaymentInfoCard({
60
62
  if (!hasCards) {
61
63
  return /* @__PURE__ */ jsxs("div", { className: "border border-zinc-200 rounded-lg overflow-hidden", children: [
62
64
  email && /* @__PURE__ */ jsxs("div", { className: "flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3", children: [
63
- /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: "E-mail" }),
65
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: translate("common.cards.paymentInfo.email") }),
64
66
  /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-950 flex-1", children: email })
65
67
  ] }),
66
68
  /* @__PURE__ */ jsxs("div", { className: "flex items-center h-[60px] px-4 gap-3", children: [
67
- /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: "Pagamento" }),
69
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: translate("common.cards.paymentInfo.payment") }),
68
70
  /* @__PURE__ */ jsxs(
69
71
  "button",
70
72
  {
@@ -73,7 +75,7 @@ function PaymentInfoCard({
73
75
  className: "flex items-center h-8 px-2 paragraph-small-semibold text-zinc-950 border border-zinc-200 rounded-md hover:border-zinc-400 transition-colors cursor-pointer w-fit",
74
76
  children: [
75
77
  /* @__PURE__ */ jsx(IconPlus, { className: "size-[18px]" }),
76
- /* @__PURE__ */ jsx("span", { className: "px-1.5", children: "Adicionar cart\xE3o" })
78
+ /* @__PURE__ */ jsx("span", { className: "px-1.5", children: translate("common.cards.paymentInfo.addCard") })
77
79
  ]
78
80
  }
79
81
  )
@@ -83,7 +85,7 @@ function PaymentInfoCard({
83
85
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
84
86
  /* @__PURE__ */ jsxs("div", { className: "border border-zinc-200 rounded-lg overflow-hidden", children: [
85
87
  email && /* @__PURE__ */ jsxs("div", { className: "flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3", children: [
86
- /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: "E-mail" }),
88
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: translate("common.cards.paymentInfo.email") }),
87
89
  /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-950 flex-1", children: email })
88
90
  ] }),
89
91
  /* @__PURE__ */ jsx(
@@ -92,7 +94,7 @@ function PaymentInfoCard({
92
94
  className: "flex items-center px-4 py-4 cursor-pointer gap-3",
93
95
  onClick: () => setIsExpanded((prev) => !prev),
94
96
  children: !isExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
95
- /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: "Pagamento" }),
97
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-zinc-500 w-[100px]", children: translate("common.cards.paymentInfo.payment") }),
96
98
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
97
99
  /* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-zinc-950 truncate", children: selectedCard?.name }),
98
100
  /* @__PURE__ */ jsxs("span", { className: "paragraph-small-medium text-zinc-950", children: [
@@ -103,7 +105,7 @@ function PaymentInfoCard({
103
105
  selectedCard && /* @__PURE__ */ jsx(CardBrandIcon, { brand: selectedCard.brand }),
104
106
  /* @__PURE__ */ jsx("div", { className: "size-8 flex items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx(IconChevronDown, { className: "size-[18px] text-zinc-500" }) })
105
107
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
106
- /* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-zinc-950 flex-1", children: "Selecione a forma de pagamento" }),
108
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-zinc-950 flex-1", children: translate("common.cards.paymentInfo.selectPaymentMethod") }),
107
109
  /* @__PURE__ */ jsx("div", { className: "size-8 flex items-center justify-center rounded-lg", children: /* @__PURE__ */ jsx(IconChevronDown, { className: "size-[18px] text-zinc-500 rotate-180" }) })
108
110
  ] })
109
111
  }
@@ -131,7 +133,7 @@ function PaymentInfoCard({
131
133
  type: "button",
132
134
  onClick: onManageCards,
133
135
  className: `flex items-center justify-center h-10 px-4 paragraph-small-semibold rounded-lg transition-colors cursor-pointer mt-2 ${isDefaultWl ? "text-cyan-600 border border-cyan-200 hover:bg-cyan-50" : "text-zinc-600 border border-zinc-200 hover:bg-zinc-50"}`,
134
- children: "Gerenciar cart\xF5es"
136
+ children: translate("common.cards.paymentInfo.manageCards")
135
137
  }
136
138
  )
137
139
  ]
@@ -146,7 +148,7 @@ function PaymentInfoCard({
146
148
  className: "flex items-center h-8 px-2 paragraph-small-semibold text-zinc-950 border border-zinc-200 rounded-md hover:border-zinc-400 transition-colors cursor-pointer w-fit",
147
149
  children: [
148
150
  /* @__PURE__ */ jsx(IconPlus, { className: "size-[18px]" }),
149
- /* @__PURE__ */ jsx("span", { className: "px-1.5", children: isExpanded ? "Adicionar cart\xE3o" : "Nova forma de pagamento" })
151
+ /* @__PURE__ */ jsx("span", { className: "px-1.5", children: isExpanded ? translate("common.cards.paymentInfo.addCard") : translate("common.cards.paymentInfo.newPaymentMethod") })
150
152
  ]
151
153
  }
152
154
  )
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/data-display/PaymentInfoCard.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useState } from 'react';\nimport { IconChevronDown, IconPlus } from '@tabler/icons-react';\nimport { CardBrandIcon } from './CardBrandIcons';\nimport { CardItem } from './CardItem';\nimport useIsMobile from '../../../hooks/useIsMobile';\nimport { useCards } from '../../../modules/cards/hooks/cards.hook';\nimport { useModalManager } from '../../../store/useModalManager';\nimport { useIsDefaultWhitelabel } from '../../../providers/whitelabel.provider';\nimport type { Card } from '../../../modules/cards/types';\n\ntype PaymentInfoCardProps = {\n email?: string;\n selectedCardId: string;\n onCardSelect: (cardId: string) => void;\n onManageCards?: () => void;\n onOpenAddCard?: () => void;\n hideDelete?: boolean;\n hideSetDefault?: boolean;\n};\n\nexport function PaymentInfoCard({\n email,\n selectedCardId,\n onCardSelect,\n onManageCards,\n onOpenAddCard,\n hideDelete,\n hideSetDefault,\n}: PaymentInfoCardProps) {\n const isMobile = useIsMobile();\n const { openModal } = useModalManager();\n const isDefaultWl = useIsDefaultWhitelabel();\n\n const [isExpanded, setIsExpanded] = useState(false);\n\n const { data: cardsData } = useCards();\n const cards = cardsData?.data ?? [];\n\n const selectedCard = cards.find(\n (card) => card.id.toString() === selectedCardId.toString(),\n );\n\n const hasCards = cards.length > 0;\n\n const hasMoreThan3Cards = cards.length > 3;\n const shouldShowManageButton = isMobile && hasMoreThan3Cards;\n const displayedCards = shouldShowManageButton ? cards.slice(0, 3) : cards;\n\n const handleOpenAddCardModal = useCallback(() => {\n if (onOpenAddCard) {\n onOpenAddCard();\n return;\n }\n openModal('addCardModal', {\n onCardAdded: (cardId: string) => onCardSelect(cardId),\n });\n }, [openModal, onOpenAddCard, onCardSelect]);\n\n const handleSelectCard = useCallback(\n (cardId: string) => {\n onCardSelect(cardId);\n setIsExpanded(false);\n },\n [onCardSelect],\n );\n\n const handleAfterDelete = useCallback(\n (card: Card) => {\n if (card.id.toString() === selectedCardId.toString()) {\n const remaining = cards.filter((c) => c.id !== card.id);\n if (remaining.length > 0) {\n onCardSelect(remaining[0].id.toString());\n }\n }\n },\n [cards, selectedCardId, onCardSelect],\n );\n\n if (!hasCards) {\n return (\n <div className=\"border border-zinc-200 rounded-lg overflow-hidden\">\n {email && (\n <div className=\"flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3\">\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">E-mail</span>\n <span className=\"paragraph-small-medium text-zinc-950 flex-1\">{email}</span>\n </div>\n )}\n <div className=\"flex items-center h-[60px] px-4 gap-3\">\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">Pagamento</span>\n <button\n type=\"button\"\n onClick={handleOpenAddCardModal}\n className=\"flex items-center h-8 px-2 paragraph-small-semibold text-zinc-950 border border-zinc-200 rounded-md hover:border-zinc-400 transition-colors cursor-pointer w-fit\"\n >\n <IconPlus className=\"size-[18px]\" />\n <span className=\"px-1.5\">Adicionar cartão</span>\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"border border-zinc-200 rounded-lg overflow-hidden\">\n {email && (\n <div className=\"flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3\">\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">E-mail</span>\n <span className=\"paragraph-small-medium text-zinc-950 flex-1\">{email}</span>\n </div>\n )}\n\n <div\n className=\"flex items-center px-4 py-4 cursor-pointer gap-3\"\n onClick={() => setIsExpanded((prev) => !prev)}\n >\n {!isExpanded ? (\n <>\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">Pagamento</span>\n <div className=\"flex flex-col gap-0.5 flex-1 min-w-0\">\n <span className=\"paragraph-small-semibold text-zinc-950 truncate\">\n {selectedCard?.name}\n </span>\n <span className=\"paragraph-small-medium text-zinc-950\">\n •••• {selectedCard?.number?.replaceAll(/\\D/g, '')?.slice(-4)}\n </span>\n </div>\n {selectedCard && <CardBrandIcon brand={selectedCard.brand} />}\n <div className=\"size-8 flex items-center justify-center rounded-lg\">\n <IconChevronDown className=\"size-[18px] text-zinc-500\" />\n </div>\n </>\n ) : (\n <>\n <span className=\"paragraph-small-semibold text-zinc-950 flex-1\">\n Selecione a forma de pagamento\n </span>\n <div className=\"size-8 flex items-center justify-center rounded-lg\">\n <IconChevronDown className=\"size-[18px] text-zinc-500 rotate-180\" />\n </div>\n </>\n )}\n </div>\n\n <div\n className={`flex flex-col gap-2 px-4 overflow-hidden transition-all duration-300 ease-in-out ${\n isExpanded ? 'max-h-[500px] pb-4 opacity-100' : 'max-h-0 pb-0 opacity-0'\n }`}\n >\n {displayedCards.map((card) => (\n <CardItem\n key={card.id}\n card={card}\n isSelected={card.id.toString() === selectedCardId.toString()}\n onSelect={() => handleSelectCard(card.id.toString())}\n hideDelete={hideDelete}\n hideSetDefault={hideSetDefault}\n onAfterDelete={handleAfterDelete}\n />\n ))}\n {shouldShowManageButton && onManageCards && (\n <button\n type=\"button\"\n onClick={onManageCards}\n className={`flex items-center justify-center h-10 px-4 paragraph-small-semibold rounded-lg transition-colors cursor-pointer mt-2 ${\n isDefaultWl\n ? 'text-cyan-600 border border-cyan-200 hover:bg-cyan-50'\n : 'text-zinc-600 border border-zinc-200 hover:bg-zinc-50'\n }`}\n >\n Gerenciar cartões\n </button>\n )}\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={handleOpenAddCardModal}\n className=\"flex items-center h-8 px-2 paragraph-small-semibold text-zinc-950 border border-zinc-200 rounded-md hover:border-zinc-400 transition-colors cursor-pointer w-fit\"\n >\n <IconPlus className=\"size-[18px]\" />\n <span className=\"px-1.5\">\n {isExpanded ? 'Adicionar cartão' : 'Nova forma de pagamento'}\n </span>\n </button>\n </div>\n );\n}\n"],"mappings":";AAoFU,SAmCE,UAlCA,KADF;AAlFV,SAAS,aAAa,gBAAgB;AACtC,SAAS,iBAAiB,gBAAgB;AAC1C,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,OAAO,iBAAiB;AACxB,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,8BAA8B;AAahC,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,UAAU,IAAI,gBAAgB;AACtC,QAAM,cAAc,uBAAuB;AAE3C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAElD,QAAM,EAAE,MAAM,UAAU,IAAI,SAAS;AACrC,QAAM,QAAQ,WAAW,QAAQ,CAAC;AAElC,QAAM,eAAe,MAAM;AAAA,IACzB,CAAC,SAAS,KAAK,GAAG,SAAS,MAAM,eAAe,SAAS;AAAA,EAC3D;AAEA,QAAM,WAAW,MAAM,SAAS;AAEhC,QAAM,oBAAoB,MAAM,SAAS;AACzC,QAAM,yBAAyB,YAAY;AAC3C,QAAM,iBAAiB,yBAAyB,MAAM,MAAM,GAAG,CAAC,IAAI;AAEpE,QAAM,yBAAyB,YAAY,MAAM;AAC/C,QAAI,eAAe;AACjB,oBAAc;AACd;AAAA,IACF;AACA,cAAU,gBAAgB;AAAA,MACxB,aAAa,CAAC,WAAmB,aAAa,MAAM;AAAA,IACtD,CAAC;AAAA,EACH,GAAG,CAAC,WAAW,eAAe,YAAY,CAAC;AAE3C,QAAM,mBAAmB;AAAA,IACvB,CAAC,WAAmB;AAClB,mBAAa,MAAM;AACnB,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,QAAM,oBAAoB;AAAA,IACxB,CAAC,SAAe;AACd,UAAI,KAAK,GAAG,SAAS,MAAM,eAAe,SAAS,GAAG;AACpD,cAAM,YAAY,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE;AACtD,YAAI,UAAU,SAAS,GAAG;AACxB,uBAAa,UAAU,CAAC,EAAE,GAAG,SAAS,CAAC;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,OAAO,gBAAgB,YAAY;AAAA,EACtC;AAEA,MAAI,CAAC,UAAU;AACb,WACE,qBAAC,SAAI,WAAU,qDACZ;AAAA,eACC,qBAAC,SAAI,WAAU,kEACb;AAAA,4BAAC,UAAK,WAAU,kDAAiD,oBAAM;AAAA,QACvE,oBAAC,UAAK,WAAU,+CAA+C,iBAAM;AAAA,SACvE;AAAA,MAEF,qBAAC,SAAI,WAAU,yCACb;AAAA,4BAAC,UAAK,WAAU,kDAAiD,uBAAS;AAAA,QAC1E;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT,WAAU;AAAA,YAEV;AAAA,kCAAC,YAAS,WAAU,eAAc;AAAA,cAClC,oBAAC,UAAK,WAAU,UAAS,iCAAgB;AAAA;AAAA;AAAA,QAC3C;AAAA,SACF;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,uBACb;AAAA,yBAAC,SAAI,WAAU,qDACZ;AAAA,eACC,qBAAC,SAAI,WAAU,kEACb;AAAA,4BAAC,UAAK,WAAU,kDAAiD,oBAAM;AAAA,QACvE,oBAAC,UAAK,WAAU,+CAA+C,iBAAM;AAAA,SACvE;AAAA,MAGF;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS,MAAM,cAAc,CAAC,SAAS,CAAC,IAAI;AAAA,UAE3C,WAAC,aACA,iCACE;AAAA,gCAAC,UAAK,WAAU,kDAAiD,uBAAS;AAAA,YAC1E,qBAAC,SAAI,WAAU,wCACb;AAAA,kCAAC,UAAK,WAAU,mDACb,wBAAc,MACjB;AAAA,cACA,qBAAC,UAAK,WAAU,wCAAuC;AAAA;AAAA,gBAC/C,cAAc,QAAQ,WAAW,OAAO,EAAE,GAAG,MAAM,EAAE;AAAA,iBAC7D;AAAA,eACF;AAAA,YACC,gBAAgB,oBAAC,iBAAc,OAAO,aAAa,OAAO;AAAA,YAC3D,oBAAC,SAAI,WAAU,sDACb,8BAAC,mBAAgB,WAAU,6BAA4B,GACzD;AAAA,aACF,IAEA,iCACE;AAAA,gCAAC,UAAK,WAAU,iDAAgD,4CAEhE;AAAA,YACA,oBAAC,SAAI,WAAU,sDACb,8BAAC,mBAAgB,WAAU,wCAAuC,GACpE;AAAA,aACF;AAAA;AAAA,MAEJ;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,oFACT,aAAa,mCAAmC,wBAClD;AAAA,UAEC;AAAA,2BAAe,IAAI,CAAC,SACnB;AAAA,cAAC;AAAA;AAAA,gBAEC;AAAA,gBACA,YAAY,KAAK,GAAG,SAAS,MAAM,eAAe,SAAS;AAAA,gBAC3D,UAAU,MAAM,iBAAiB,KAAK,GAAG,SAAS,CAAC;AAAA,gBACnD;AAAA,gBACA;AAAA,gBACA,eAAe;AAAA;AAAA,cANV,KAAK;AAAA,YAOZ,CACD;AAAA,YACA,0BAA0B,iBACzB;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,WAAW,wHACT,cACI,0DACA,uDACN;AAAA,gBACD;AAAA;AAAA,YAED;AAAA;AAAA;AAAA,MAEJ;AAAA,OACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS;AAAA,QACT,WAAU;AAAA,QAEV;AAAA,8BAAC,YAAS,WAAU,eAAc;AAAA,UAClC,oBAAC,UAAK,WAAU,UACb,uBAAa,wBAAqB,2BACrC;AAAA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/data-display/PaymentInfoCard.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useState } from 'react';\nimport { IconChevronDown, IconPlus } from '@tabler/icons-react';\nimport { CardBrandIcon } from './CardBrandIcons';\nimport { CardItem } from './CardItem';\nimport useIsMobile from '../../../hooks/useIsMobile';\nimport { useCards } from '../../../modules/cards/hooks/cards.hook';\nimport { useModalManager } from '../../../store/useModalManager';\nimport { useIsDefaultWhitelabel } from '../../../providers/whitelabel.provider';\nimport type { Card } from '../../../modules/cards/types';\nimport { useTranslations } from 'next-intl';\n\ntype PaymentInfoCardProps = {\n email?: string;\n selectedCardId: string;\n onCardSelect: (cardId: string) => void;\n onManageCards?: () => void;\n onOpenAddCard?: () => void;\n hideDelete?: boolean;\n hideSetDefault?: boolean;\n};\n\nexport function PaymentInfoCard({\n email,\n selectedCardId,\n onCardSelect,\n onManageCards,\n onOpenAddCard,\n hideDelete,\n hideSetDefault,\n}: PaymentInfoCardProps) {\n const translate = useTranslations();\n const isMobile = useIsMobile();\n const { openModal } = useModalManager();\n const isDefaultWl = useIsDefaultWhitelabel();\n\n const [isExpanded, setIsExpanded] = useState(false);\n\n const { data: cardsData } = useCards();\n const cards = cardsData?.data ?? [];\n\n const selectedCard = cards.find(\n (card) => card.id.toString() === selectedCardId.toString(),\n );\n\n const hasCards = cards.length > 0;\n\n const hasMoreThan3Cards = cards.length > 3;\n const shouldShowManageButton = isMobile && hasMoreThan3Cards;\n const displayedCards = shouldShowManageButton ? cards.slice(0, 3) : cards;\n\n const handleOpenAddCardModal = useCallback(() => {\n if (onOpenAddCard) {\n onOpenAddCard();\n return;\n }\n openModal('addCardModal', {\n onCardAdded: (cardId: string) => onCardSelect(cardId),\n });\n }, [openModal, onOpenAddCard, onCardSelect]);\n\n const handleSelectCard = useCallback(\n (cardId: string) => {\n onCardSelect(cardId);\n setIsExpanded(false);\n },\n [onCardSelect],\n );\n\n const handleAfterDelete = useCallback(\n (card: Card) => {\n if (card.id.toString() === selectedCardId.toString()) {\n const remaining = cards.filter((c) => c.id !== card.id);\n if (remaining.length > 0) {\n onCardSelect(remaining[0].id.toString());\n }\n }\n },\n [cards, selectedCardId, onCardSelect],\n );\n\n if (!hasCards) {\n return (\n <div className=\"border border-zinc-200 rounded-lg overflow-hidden\">\n {email && (\n <div className=\"flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3\">\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">{translate('common.cards.paymentInfo.email')}</span>\n <span className=\"paragraph-small-medium text-zinc-950 flex-1\">{email}</span>\n </div>\n )}\n <div className=\"flex items-center h-[60px] px-4 gap-3\">\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">{translate('common.cards.paymentInfo.payment')}</span>\n <button\n type=\"button\"\n onClick={handleOpenAddCardModal}\n className=\"flex items-center h-8 px-2 paragraph-small-semibold text-zinc-950 border border-zinc-200 rounded-md hover:border-zinc-400 transition-colors cursor-pointer w-fit\"\n >\n <IconPlus className=\"size-[18px]\" />\n <span className=\"px-1.5\">{translate('common.cards.paymentInfo.addCard')}</span>\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"border border-zinc-200 rounded-lg overflow-hidden\">\n {email && (\n <div className=\"flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3\">\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">{translate('common.cards.paymentInfo.email')}</span>\n <span className=\"paragraph-small-medium text-zinc-950 flex-1\">{email}</span>\n </div>\n )}\n\n <div\n className=\"flex items-center px-4 py-4 cursor-pointer gap-3\"\n onClick={() => setIsExpanded((prev) => !prev)}\n >\n {!isExpanded ? (\n <>\n <span className=\"paragraph-small-medium text-zinc-500 w-[100px]\">{translate('common.cards.paymentInfo.payment')}</span>\n <div className=\"flex flex-col gap-0.5 flex-1 min-w-0\">\n <span className=\"paragraph-small-semibold text-zinc-950 truncate\">\n {selectedCard?.name}\n </span>\n <span className=\"paragraph-small-medium text-zinc-950\">\n •••• {selectedCard?.number?.replaceAll(/\\D/g, '')?.slice(-4)}\n </span>\n </div>\n {selectedCard && <CardBrandIcon brand={selectedCard.brand} />}\n <div className=\"size-8 flex items-center justify-center rounded-lg\">\n <IconChevronDown className=\"size-[18px] text-zinc-500\" />\n </div>\n </>\n ) : (\n <>\n <span className=\"paragraph-small-semibold text-zinc-950 flex-1\">\n {translate('common.cards.paymentInfo.selectPaymentMethod')}\n </span>\n <div className=\"size-8 flex items-center justify-center rounded-lg\">\n <IconChevronDown className=\"size-[18px] text-zinc-500 rotate-180\" />\n </div>\n </>\n )}\n </div>\n\n <div\n className={`flex flex-col gap-2 px-4 overflow-hidden transition-all duration-300 ease-in-out ${\n isExpanded ? 'max-h-[500px] pb-4 opacity-100' : 'max-h-0 pb-0 opacity-0'\n }`}\n >\n {displayedCards.map((card) => (\n <CardItem\n key={card.id}\n card={card}\n isSelected={card.id.toString() === selectedCardId.toString()}\n onSelect={() => handleSelectCard(card.id.toString())}\n hideDelete={hideDelete}\n hideSetDefault={hideSetDefault}\n onAfterDelete={handleAfterDelete}\n />\n ))}\n {shouldShowManageButton && onManageCards && (\n <button\n type=\"button\"\n onClick={onManageCards}\n className={`flex items-center justify-center h-10 px-4 paragraph-small-semibold rounded-lg transition-colors cursor-pointer mt-2 ${\n isDefaultWl\n ? 'text-cyan-600 border border-cyan-200 hover:bg-cyan-50'\n : 'text-zinc-600 border border-zinc-200 hover:bg-zinc-50'\n }`}\n >\n {translate('common.cards.paymentInfo.manageCards')}\n </button>\n )}\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={handleOpenAddCardModal}\n className=\"flex items-center h-8 px-2 paragraph-small-semibold text-zinc-950 border border-zinc-200 rounded-md hover:border-zinc-400 transition-colors cursor-pointer w-fit\"\n >\n <IconPlus className=\"size-[18px]\" />\n <span className=\"px-1.5\">\n {isExpanded ? translate('common.cards.paymentInfo.addCard') : translate('common.cards.paymentInfo.newPaymentMethod')}\n </span>\n </button>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/feedback/CircularProgress.tsx"],"sourcesContent":["import { ReactNode } from \"react\";\nimport {\n calculateRadius,\n calculateCircumference,\n calculatePercentage,\n calculateCircularProgressOffset,\n} from \"../../../infra/utils/percentage\";\n\ninterface CircularProgressProps {\n current: number;\n total: number;\n size?: number;\n strokeWidth?: number;\n children?: ReactNode;\n}\n\nexport default function CircularProgress({\n current,\n total,\n size = 62,\n strokeWidth = 3,\n children,\n}: CircularProgressProps) {\n const radius = calculateRadius(size, strokeWidth);\n const circumference = calculateCircumference(radius);\n const percentage = calculatePercentage(current, total);\n const offset = calculateCircularProgressOffset(percentage, circumference);\n\n return (\n <div\n className=\"relative flex items-center justify-center\"\n style={{ width: size, height: size }}\n role=\"progressbar\"\n aria-valuenow={current}\n aria-valuemin={0}\n aria-valuemax={total}\n aria-label=\"Progresso\"\n >\n <svg width={size} height={size} className=\"absolute\">\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke=\"var(--color-gray-50)\"\n strokeWidth={strokeWidth}\n fill=\"white\"\n />\n\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke=\"var(--color-gray-950)\"\n strokeWidth={strokeWidth}\n fill=\"none\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n transform={`rotate(-90 ${size / 2} ${size / 2})`}\n className=\"transition-all duration-300 ease-in-out\"\n />\n </svg>\n\n <div className=\"relative z-10 flex items-center justify-center w-[50px] h-[50px] rounded-full bg-gray-50 paragraph-small-semibold\">\n {children ?? (\n <>\n <span className=\"text-gray-600\">{current}</span>\n <span className=\"text-gray-500\">/</span>\n <span className=\"text-gray-600\">{total}</span>\n </>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"AAsCM,SA2BI,UA1BF,KADF;AArCN;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUQ,SAAR,iBAAkC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,cAAc;AAAA,EACd;AACF,GAA0B;AACxB,QAAM,SAAS,gBAAgB,MAAM,WAAW;AAChD,QAAM,gBAAgB,uBAAuB,MAAM;AACnD,QAAM,aAAa,oBAAoB,SAAS,KAAK;AACrD,QAAM,SAAS,gCAAgC,YAAY,aAAa;AAExE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACnC,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,cAAW;AAAA,MAEX;AAAA,6BAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,WAAU,YACxC;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI,OAAO;AAAA,cACX,IAAI,OAAO;AAAA,cACX,GAAG;AAAA,cACH,QAAO;AAAA,cACP;AAAA,cACA,MAAK;AAAA;AAAA,UACP;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI,OAAO;AAAA,cACX,IAAI,OAAO;AAAA,cACX,GAAG;AAAA,cACH,QAAO;AAAA,cACP;AAAA,cACA,MAAK;AAAA,cACL,iBAAiB;AAAA,cACjB,kBAAkB;AAAA,cAClB,eAAc;AAAA,cACd,WAAW,cAAc,OAAO,CAAC,IAAI,OAAO,CAAC;AAAA,cAC7C,WAAU;AAAA;AAAA,UACZ;AAAA,WACF;AAAA,QAEA,oBAAC,SAAI,WAAU,qHACZ,sBACC,iCACE;AAAA,8BAAC,UAAK,WAAU,iBAAiB,mBAAQ;AAAA,UACzC,oBAAC,UAAK,WAAU,iBAAgB,eAAC;AAAA,UACjC,oBAAC,UAAK,WAAU,iBAAiB,iBAAM;AAAA,WACzC,GAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/feedback/CircularProgress.tsx"],"sourcesContent":["import { ReactNode } from \"react\";\nimport {\n calculateRadius,\n calculateCircumference,\n calculatePercentage,\n calculateCircularProgressOffset,\n} from \"../../../infra/utils/percentage\";\n\ninterface CircularProgressProps {\n current: number;\n total: number;\n size?: number;\n strokeWidth?: number;\n children?: ReactNode;\n}\n\nexport default function CircularProgress({\n current,\n total,\n size = 62,\n strokeWidth = 3,\n children,\n}: CircularProgressProps) {\n const radius = calculateRadius(size, strokeWidth);\n const circumference = calculateCircumference(radius);\n const percentage = calculatePercentage(current, total);\n const offset = calculateCircularProgressOffset(percentage, circumference);\n\n return (\n <div\n className=\"relative flex items-center justify-center\"\n style={{ width: size, height: size }}\n role=\"progressbar\"\n aria-valuenow={current}\n aria-valuemin={0}\n aria-valuemax={total}\n // i18n-TODO: aria-label hardcoded — CircularProgress has no 'use client' directive and\n // receives no translate prop, so useTranslations() cannot be called here without\n // converting it to a client component. Key to use: common.forms.progressAriaLabel ('Progresso').\n // Either add 'use client' + useTranslations(), or accept a translate prop from the caller.\n aria-label=\"Progresso\"\n >\n <svg width={size} height={size} className=\"absolute\">\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke=\"var(--color-gray-50)\"\n strokeWidth={strokeWidth}\n fill=\"white\"\n />\n\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke=\"var(--color-gray-950)\"\n strokeWidth={strokeWidth}\n fill=\"none\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n transform={`rotate(-90 ${size / 2} ${size / 2})`}\n className=\"transition-all duration-300 ease-in-out\"\n />\n </svg>\n\n <div className=\"relative z-10 flex items-center justify-center w-[50px] h-[50px] rounded-full bg-gray-50 paragraph-small-semibold\">\n {children ?? (\n <>\n <span className=\"text-gray-600\">{current}</span>\n <span className=\"text-gray-500\">/</span>\n <span className=\"text-gray-600\">{total}</span>\n </>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"AA0CM,SA2BI,UA1BF,KADF;AAzCN;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUQ,SAAR,iBAAkC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,cAAc;AAAA,EACd;AACF,GAA0B;AACxB,QAAM,SAAS,gBAAgB,MAAM,WAAW;AAChD,QAAM,gBAAgB,uBAAuB,MAAM;AACnD,QAAM,aAAa,oBAAoB,SAAS,KAAK;AACrD,QAAM,SAAS,gCAAgC,YAAY,aAAa;AAExE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACnC,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe;AAAA,MAKf,cAAW;AAAA,MAEX;AAAA,6BAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,WAAU,YACxC;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI,OAAO;AAAA,cACX,IAAI,OAAO;AAAA,cACX,GAAG;AAAA,cACH,QAAO;AAAA,cACP;AAAA,cACA,MAAK;AAAA;AAAA,UACP;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI,OAAO;AAAA,cACX,IAAI,OAAO;AAAA,cACX,GAAG;AAAA,cACH,QAAO;AAAA,cACP;AAAA,cACA,MAAK;AAAA,cACL,iBAAiB;AAAA,cACjB,kBAAkB;AAAA,cAClB,eAAc;AAAA,cACd,WAAW,cAAc,OAAO,CAAC,IAAI,OAAO,CAAC;AAAA,cAC7C,WAAU;AAAA;AAAA,UACZ;AAAA,WACF;AAAA,QAEA,oBAAC,SAAI,WAAU,qHACZ,sBACC,iCACE;AAAA,8BAAC,UAAK,WAAU,iBAAiB,mBAAQ;AAAA,UACzC,oBAAC,UAAK,WAAU,iBAAgB,eAAC;AAAA,UACjC,oBAAC,UAAK,WAAU,iBAAiB,iBAAM;AAAA,WACzC,GAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useTranslations } from "next-intl";
3
4
  import {
4
5
  calculateRadius,
5
6
  calculateCircumference,
@@ -13,6 +14,7 @@ function DefaultCircularProgress({
13
14
  size = 62,
14
15
  strokeWidth = 3
15
16
  }) {
17
+ const translate = useTranslations();
16
18
  const isDefaultWl = useIsDefaultWhitelabel();
17
19
  const radius = calculateRadius(size, strokeWidth);
18
20
  const circumference = calculateCircumference(radius);
@@ -27,7 +29,7 @@ function DefaultCircularProgress({
27
29
  "aria-valuenow": current,
28
30
  "aria-valuemin": 0,
29
31
  "aria-valuemax": total,
30
- "aria-label": "Progresso de exporta\xE7\xE3o",
32
+ "aria-label": translate("common.forms.circularProgress.ariaLabel"),
31
33
  children: /* @__PURE__ */ jsxs("svg", { width: size, height: size, className: "absolute", children: [
32
34
  /* @__PURE__ */ jsx(
33
35
  "circle",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/feedback/DefaultCircularProgress.tsx"],"sourcesContent":["'use client';\n\nimport {\n calculateRadius,\n calculateCircumference,\n calculatePercentage,\n calculateCircularProgressOffset,\n} from \"../../../infra/utils/percentage\";\nimport { useIsDefaultWhitelabel } from \"../../../providers/whitelabel.provider\";\n\ninterface CircularProgressProps {\n current: number;\n total: number;\n size?: number;\n strokeWidth?: number;\n}\n\nexport default function DefaultCircularProgress({\n current,\n total,\n size = 62,\n strokeWidth = 3,\n}: CircularProgressProps) {\n const isDefaultWl = useIsDefaultWhitelabel();\n const radius = calculateRadius(size, strokeWidth);\n const circumference = calculateCircumference(radius);\n const percentage = calculatePercentage(current, total);\n const offset = calculateCircularProgressOffset(percentage, circumference);\n\n return (\n <div\n className=\"relative flex items-center justify-center\"\n style={{ width: size, height: size }}\n role=\"progressbar\"\n aria-valuenow={current}\n aria-valuemin={0}\n aria-valuemax={total}\n aria-label=\"Progresso de exportação\"\n >\n <svg width={size} height={size} className=\"absolute\">\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke=\"var(--color-zinc-200)\"\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke={isDefaultWl ? \"var(--color-cyan-300)\" : \"var(--color-zinc-300)\"}\n strokeWidth={strokeWidth}\n fill=\"none\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n transform={`rotate(-90 ${size / 2} ${size / 2})`}\n className=\"transition-all duration-300 ease-in-out\"\n />\n </svg>\n </div>\n );\n}\n"],"mappings":";AAuCM,SACE,KADF;AArCN;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,8BAA8B;AASxB,SAAR,wBAAyC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,cAAc;AAChB,GAA0B;AACxB,QAAM,cAAc,uBAAuB;AAC3C,QAAM,SAAS,gBAAgB,MAAM,WAAW;AAChD,QAAM,gBAAgB,uBAAuB,MAAM;AACnD,QAAM,aAAa,oBAAoB,SAAS,KAAK;AACrD,QAAM,SAAS,gCAAgC,YAAY,aAAa;AAExE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACnC,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,cAAW;AAAA,MAEX,+BAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,WAAU,YACxC;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YACX,IAAI,OAAO;AAAA,YACX,GAAG;AAAA,YACH,QAAO;AAAA,YACP;AAAA,YACA,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YACX,IAAI,OAAO;AAAA,YACX,GAAG;AAAA,YACH,QAAQ,cAAc,0BAA0B;AAAA,YAChD;AAAA,YACA,MAAK;AAAA,YACL,iBAAiB;AAAA,YACjB,kBAAkB;AAAA,YAClB,eAAc;AAAA,YACd,WAAW,cAAc,OAAO,CAAC,IAAI,OAAO,CAAC;AAAA,YAC7C,WAAU;AAAA;AAAA,QACZ;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/feedback/DefaultCircularProgress.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport {\n calculateRadius,\n calculateCircumference,\n calculatePercentage,\n calculateCircularProgressOffset,\n} from \"../../../infra/utils/percentage\";\nimport { useIsDefaultWhitelabel } from \"../../../providers/whitelabel.provider\";\n\ninterface CircularProgressProps {\n current: number;\n total: number;\n size?: number;\n strokeWidth?: number;\n}\n\nexport default function DefaultCircularProgress({\n current,\n total,\n size = 62,\n strokeWidth = 3,\n}: CircularProgressProps) {\n const translate = useTranslations();\n const isDefaultWl = useIsDefaultWhitelabel();\n const radius = calculateRadius(size, strokeWidth);\n const circumference = calculateCircumference(radius);\n const percentage = calculatePercentage(current, total);\n const offset = calculateCircularProgressOffset(percentage, circumference);\n\n return (\n <div\n className=\"relative flex items-center justify-center\"\n style={{ width: size, height: size }}\n role=\"progressbar\"\n aria-valuenow={current}\n aria-valuemin={0}\n aria-valuemax={total}\n aria-label={translate('common.forms.circularProgress.ariaLabel')}\n >\n <svg width={size} height={size} className=\"absolute\">\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke=\"var(--color-zinc-200)\"\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke={isDefaultWl ? \"var(--color-cyan-300)\" : \"var(--color-zinc-300)\"}\n strokeWidth={strokeWidth}\n fill=\"none\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n transform={`rotate(-90 ${size / 2} ${size / 2})`}\n className=\"transition-all duration-300 ease-in-out\"\n />\n </svg>\n </div>\n );\n}\n"],"mappings":";AAyCM,SACE,KADF;AAvCN,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,8BAA8B;AASxB,SAAR,wBAAyC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,cAAc;AAChB,GAA0B;AACxB,QAAM,YAAY,gBAAgB;AAClC,QAAM,cAAc,uBAAuB;AAC3C,QAAM,SAAS,gBAAgB,MAAM,WAAW;AAChD,QAAM,gBAAgB,uBAAuB,MAAM;AACnD,QAAM,aAAa,oBAAoB,SAAS,KAAK;AACrD,QAAM,SAAS,gCAAgC,YAAY,aAAa;AAExE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MACnC,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,cAAY,UAAU,yCAAyC;AAAA,MAE/D,+BAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,WAAU,YACxC;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YACX,IAAI,OAAO;AAAA,YACX,GAAG;AAAA,YACH,QAAO;AAAA,YACP;AAAA,YACA,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YACX,IAAI,OAAO;AAAA,YACX,GAAG;AAAA,YACH,QAAQ,cAAc,0BAA0B;AAAA,YAChD;AAAA,YACA,MAAK;AAAA,YACL,iBAAiB;AAAA,YACjB,kBAAkB;AAAA,YAClB,eAAc;AAAA,YACd,WAAW,cAAc,OAAO,CAAC,IAAI,OAAO,CAAC;AAAA,YAC7C,WAAU;AAAA;AAAA,QACZ;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1,15 +1,16 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState, useMemo } from "react";
4
+ import { useTranslations } from "next-intl";
4
5
  import { IconCheck, IconChevronDown, IconSearch } from "@tabler/icons-react";
5
6
  import { Popover, PopoverContent, PopoverTrigger } from "../overlay/Popover";
6
7
  import { cn } from "../../../infra/utils/clsx";
7
8
  function ComboboxField({
8
9
  options,
9
10
  label,
10
- placeholder = "Selecione uma op\xE7\xE3o",
11
- searchPlaceholder = "Buscar...",
12
- emptyMessage = "Nenhuma op\xE7\xE3o encontrada.",
11
+ placeholder,
12
+ searchPlaceholder,
13
+ emptyMessage,
13
14
  value,
14
15
  onChange,
15
16
  disabled = false,
@@ -17,6 +18,10 @@ function ComboboxField({
17
18
  className,
18
19
  containerClassName
19
20
  }) {
21
+ const translate = useTranslations();
22
+ const resolvedPlaceholder = placeholder ?? translate("common.forms.combobox.placeholder");
23
+ const resolvedSearchPlaceholder = searchPlaceholder ?? translate("common.forms.combobox.searchPlaceholder");
24
+ const resolvedEmptyMessage = emptyMessage ?? translate("common.forms.combobox.emptyMessage");
20
25
  const [open, setOpen] = useState(false);
21
26
  const [search, setSearch] = useState("");
22
27
  const selectedOption = useMemo(
@@ -59,7 +64,7 @@ function ComboboxField({
59
64
  className
60
65
  ),
61
66
  children: [
62
- /* @__PURE__ */ jsx("span", { className: cn("truncate text-left", !selectedOption && "text-gray-400"), children: selectedOption ? selectedOption.displayValue ?? selectedOption.label : placeholder }),
67
+ /* @__PURE__ */ jsx("span", { className: cn("truncate text-left", !selectedOption && "text-gray-400"), children: selectedOption ? selectedOption.displayValue ?? selectedOption.label : resolvedPlaceholder }),
63
68
  icon ?? /* @__PURE__ */ jsx(
64
69
  IconChevronDown,
65
70
  {
@@ -87,14 +92,14 @@ function ComboboxField({
87
92
  "input",
88
93
  {
89
94
  autoFocus: true,
90
- placeholder: searchPlaceholder,
95
+ placeholder: resolvedSearchPlaceholder,
91
96
  value: search,
92
97
  onChange: (e) => setSearch(e.target.value),
93
98
  className: "flex h-full w-full bg-transparent text-sm outline-none placeholder:text-gray-400 paragraph-small-medium text-gray-950"
94
99
  }
95
100
  )
96
101
  ] }),
97
- /* @__PURE__ */ jsx("div", { className: "overflow-y-auto max-h-[280px] p-1", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("p", { className: "py-6 text-center paragraph-small-medium text-gray-500", children: emptyMessage }) : filteredOptions.map((option) => {
102
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto max-h-[280px] p-1", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("p", { className: "py-6 text-center paragraph-small-medium text-gray-500", children: resolvedEmptyMessage }) : filteredOptions.map((option) => {
98
103
  const isSelected = value === option.value;
99
104
  return /* @__PURE__ */ jsxs(
100
105
  "div",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/form/ComboboxField.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useMemo } from 'react';\nimport { IconCheck, IconChevronDown, IconSearch } from '@tabler/icons-react';\nimport { Popover, PopoverContent, PopoverTrigger } from '../overlay/Popover';\nimport { cn } from '../../../infra/utils/clsx';\n\nexport type ComboboxOption = {\n value: string;\n label: string;\n displayValue?: string;\n};\n\ninterface ComboboxFieldProps {\n options: ComboboxOption[];\n label?: string;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyMessage?: string;\n value?: string;\n onChange?: (value: string) => void;\n disabled?: boolean;\n icon?: React.ReactNode;\n className?: string;\n containerClassName?: string;\n}\n\nexport function ComboboxField({\n options,\n label,\n placeholder = 'Selecione uma opção',\n searchPlaceholder = 'Buscar...',\n emptyMessage = 'Nenhuma opção encontrada.',\n value,\n onChange,\n disabled = false,\n icon,\n className,\n containerClassName,\n}: ComboboxFieldProps) {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n\n const selectedOption = useMemo(\n () => options.find((o) => o.value === value),\n [options, value]\n );\n\n const filteredOptions = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return options;\n return options.filter((o) => o.label.toLowerCase().includes(q));\n }, [options, search]);\n\n const handleSelect = (optionValue: string) => {\n onChange?.(optionValue);\n setOpen(false);\n setSearch('');\n };\n\n return (\n <div className={cn('flex flex-col gap-1.5', containerClassName)}>\n {label && (\n <div className=\"flex items-center gap-1 paragraph-xsmall-semibold\">\n <span className=\"text-gray-600\">{label}</span>\n </div>\n )}\n\n <Popover\n open={open}\n onOpenChange={(v) => {\n if (!disabled) {\n setOpen(v);\n if (!v) setSearch('');\n }\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'paragraph-small-medium w-full h-10 text-gray-950 px-4 transition-colors',\n 'flex items-center justify-between gap-2 rounded-md border bg-transparent',\n 'border-gray-200 hover:border-gray-400 focus:border-gray-950 focus:outline-none',\n disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer',\n className\n )}\n >\n <span className={cn('truncate text-left', !selectedOption && 'text-gray-400')}>\n {selectedOption\n ? (selectedOption.displayValue ?? selectedOption.label)\n : placeholder}\n </span>\n {icon ?? (\n <IconChevronDown\n className={cn(\n 'size-4 opacity-50 shrink-0 transition-all duration-200',\n open && 'rotate-180 opacity-100 text-gray-950'\n )}\n />\n )}\n </button>\n </PopoverTrigger>\n\n <PopoverContent\n className=\"p-0 overflow-hidden rounded-md border shadow-md\"\n align=\"start\"\n sideOffset={4}\n style={{ width: 'var(--radix-popover-trigger-width)' }}\n onWheel={(e) => e.stopPropagation()}\n >\n <div className=\"flex items-center gap-2 border-b border-gray-100 px-3 h-9\">\n <IconSearch className=\"size-4 shrink-0 opacity-50 text-gray-500\" />\n <input\n autoFocus\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"flex h-full w-full bg-transparent text-sm outline-none placeholder:text-gray-400 paragraph-small-medium text-gray-950\"\n />\n </div>\n\n <div className=\"overflow-y-auto max-h-[280px] p-1\">\n {filteredOptions.length === 0 ? (\n <p className=\"py-6 text-center paragraph-small-medium text-gray-500\">{emptyMessage}</p>\n ) : (\n filteredOptions.map((option) => {\n const isSelected = value === option.value;\n return (\n <div\n key={option.value}\n className={cn(\n 'flex items-center gap-2 rounded-sm px-2 h-9 cursor-pointer select-none',\n 'paragraph-small-medium text-gray-950',\n 'hover:bg-gray-100',\n isSelected && 'bg-gray-50'\n )}\n onClick={() => handleSelect(option.value)}\n >\n <span className=\"flex-1 truncate\">{option.label}</span>\n {isSelected && <IconCheck className=\"size-4 shrink-0 text-pages-600\" />}\n </div>\n );\n })\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n\nexport default ComboboxField;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/form/ComboboxField.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useMemo } from 'react';\nimport { useTranslations } from 'next-intl';\nimport { IconCheck, IconChevronDown, IconSearch } from '@tabler/icons-react';\nimport { Popover, PopoverContent, PopoverTrigger } from '../overlay/Popover';\nimport { cn } from '../../../infra/utils/clsx';\n\nexport type ComboboxOption = {\n value: string;\n label: string;\n displayValue?: string;\n};\n\ninterface ComboboxFieldProps {\n options: ComboboxOption[];\n label?: string;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyMessage?: string;\n value?: string;\n onChange?: (value: string) => void;\n disabled?: boolean;\n icon?: React.ReactNode;\n className?: string;\n containerClassName?: string;\n}\n\nexport function ComboboxField({\n options,\n label,\n placeholder,\n searchPlaceholder,\n emptyMessage,\n value,\n onChange,\n disabled = false,\n icon,\n className,\n containerClassName,\n}: ComboboxFieldProps) {\n const translate = useTranslations();\n const resolvedPlaceholder = placeholder ?? translate('common.forms.combobox.placeholder');\n const resolvedSearchPlaceholder = searchPlaceholder ?? translate('common.forms.combobox.searchPlaceholder');\n const resolvedEmptyMessage = emptyMessage ?? translate('common.forms.combobox.emptyMessage');\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n\n const selectedOption = useMemo(\n () => options.find((o) => o.value === value),\n [options, value]\n );\n\n const filteredOptions = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return options;\n return options.filter((o) => o.label.toLowerCase().includes(q));\n }, [options, search]);\n\n const handleSelect = (optionValue: string) => {\n onChange?.(optionValue);\n setOpen(false);\n setSearch('');\n };\n\n return (\n <div className={cn('flex flex-col gap-1.5', containerClassName)}>\n {label && (\n <div className=\"flex items-center gap-1 paragraph-xsmall-semibold\">\n <span className=\"text-gray-600\">{label}</span>\n </div>\n )}\n\n <Popover\n open={open}\n onOpenChange={(v) => {\n if (!disabled) {\n setOpen(v);\n if (!v) setSearch('');\n }\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'paragraph-small-medium w-full h-10 text-gray-950 px-4 transition-colors',\n 'flex items-center justify-between gap-2 rounded-md border bg-transparent',\n 'border-gray-200 hover:border-gray-400 focus:border-gray-950 focus:outline-none',\n disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer',\n className\n )}\n >\n <span className={cn('truncate text-left', !selectedOption && 'text-gray-400')}>\n {selectedOption\n ? (selectedOption.displayValue ?? selectedOption.label)\n : resolvedPlaceholder}\n </span>\n {icon ?? (\n <IconChevronDown\n className={cn(\n 'size-4 opacity-50 shrink-0 transition-all duration-200',\n open && 'rotate-180 opacity-100 text-gray-950'\n )}\n />\n )}\n </button>\n </PopoverTrigger>\n\n <PopoverContent\n className=\"p-0 overflow-hidden rounded-md border shadow-md\"\n align=\"start\"\n sideOffset={4}\n style={{ width: 'var(--radix-popover-trigger-width)' }}\n onWheel={(e) => e.stopPropagation()}\n >\n <div className=\"flex items-center gap-2 border-b border-gray-100 px-3 h-9\">\n <IconSearch className=\"size-4 shrink-0 opacity-50 text-gray-500\" />\n <input\n autoFocus\n placeholder={resolvedSearchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"flex h-full w-full bg-transparent text-sm outline-none placeholder:text-gray-400 paragraph-small-medium text-gray-950\"\n />\n </div>\n\n <div className=\"overflow-y-auto max-h-[280px] p-1\">\n {filteredOptions.length === 0 ? (\n <p className=\"py-6 text-center paragraph-small-medium text-gray-500\">{resolvedEmptyMessage}</p>\n ) : (\n filteredOptions.map((option) => {\n const isSelected = value === option.value;\n return (\n <div\n key={option.value}\n className={cn(\n 'flex items-center gap-2 rounded-sm px-2 h-9 cursor-pointer select-none',\n 'paragraph-small-medium text-gray-950',\n 'hover:bg-gray-100',\n isSelected && 'bg-gray-50'\n )}\n onClick={() => handleSelect(option.value)}\n >\n <span className=\"flex-1 truncate\">{option.label}</span>\n {isSelected && <IconCheck className=\"size-4 shrink-0 text-pages-600\" />}\n </div>\n );\n })\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n\nexport default ComboboxField;\n"],"mappings":"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","names":[]}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState, forwardRef, useEffect } from "react";
4
+ import { useTranslations } from "next-intl";
4
5
  import { format } from "date-fns";
5
6
  import { Calendar } from "./Calendar";
6
7
  import { Popover, PopoverContent, PopoverTrigger } from "../overlay/Popover";
@@ -10,7 +11,9 @@ const isoParaDataLocal = (iso) => {
10
11
  return new Date(ano, mes - 1, dia);
11
12
  };
12
13
  const DatePicker = forwardRef(
13
- ({ value, onChange, placeholder = "Selecione a data", className, disabled }, ref) => {
14
+ ({ value, onChange, placeholder, className, disabled }, ref) => {
15
+ const translate = useTranslations();
16
+ const resolvedPlaceholder = placeholder ?? translate("common.forms.datePicker.placeholder");
14
17
  const [open, setOpen] = useState(false);
15
18
  const [date, setDate] = useState(() => {
16
19
  return value ? isoParaDataLocal(value) : void 0;
@@ -31,7 +34,7 @@ const DatePicker = forwardRef(
31
34
  onChange?.(void 0);
32
35
  }
33
36
  };
34
- const displayText = date ? format(date, "dd/MM/yyyy") : placeholder;
37
+ const displayText = date ? format(date, "dd/MM/yyyy") : resolvedPlaceholder;
35
38
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
36
39
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
37
40
  "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/form/DatePicker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, forwardRef, useEffect } from \"react\";\nimport { format } from \"date-fns\";\nimport { Calendar } from \"./Calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlay/Popover\";\nimport { cn } from \"../../../infra/utils/clsx\";\n\n// Converte string ISO (yyyy-MM-dd) para Date no fuso horário local\n// Evita bug de timezone onde new Date(\"2025-08-02\") interpreta como UTC\nconst isoParaDataLocal = (iso: string): Date => {\n const [ano, mes, dia] = iso.split(\"-\").map(Number);\n return new Date(ano, mes - 1, dia);\n};\n\ninterface DatePickerProps {\n value?: string;\n onChange?: (date: string | undefined) => void;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n}\n\nexport const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(\n (\n { value, onChange, placeholder = \"Selecione a data\", className, disabled },\n ref,\n ) => {\n const [open, setOpen] = useState(false);\n const [date, setDate] = useState<Date | undefined>(() => {\n return value ? isoParaDataLocal(value) : undefined;\n });\n\n // Sincroniza estado interno quando value mudar externamente\n useEffect(() => {\n if (value) {\n setDate(isoParaDataLocal(value));\n } else {\n setDate(undefined);\n }\n }, [value]);\n\n const handleDateSelect = (selectedDate: Date | undefined) => {\n setDate(selectedDate);\n\n if (selectedDate) {\n onChange?.(format(selectedDate, \"yyyy-MM-dd\"));\n setOpen(false); // Fecha o popover após seleção\n } else {\n onChange?.(undefined);\n }\n };\n\n const displayText = date ? format(date, \"dd/MM/yyyy\") : placeholder;\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n ref={ref}\n disabled={disabled}\n className={cn(\n \"flex items-center gap-2 px-4 h-10 border rounded-lg transition-colors w-full justify-start\",\n \"border-gray-200 hover:border-gray-400 focus-within:border-gray-950\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n className,\n )}\n >\n <span\n className={cn(\n \"paragraph-small-medium\",\n date ? \"text-gray-950\" : \"text-gray-500\",\n )}\n >\n {displayText}\n </span>\n </button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto p-0 bg-white rounded-2xl shadow-md border border-gray-200\"\n align=\"start\"\n sideOffset={8}\n >\n <div className=\"p-3\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={handleDateSelect}\n />\n </div>\n </PopoverContent>\n </Popover>\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"mappings":";AAwDM,SAYM,KAZN;AAtDN,SAAS,UAAU,YAAY,iBAAiB;AAChD,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,UAAU;AAInB,MAAM,mBAAmB,CAAC,QAAsB;AAC9C,QAAM,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM;AACjD,SAAO,IAAI,KAAK,KAAK,MAAM,GAAG,GAAG;AACnC;AAUO,MAAM,aAAa;AAAA,EACxB,CACE,EAAE,OAAO,UAAU,cAAc,oBAAoB,WAAW,SAAS,GACzE,QACG;AACH,UAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,UAAM,CAAC,MAAM,OAAO,IAAI,SAA2B,MAAM;AACvD,aAAO,QAAQ,iBAAiB,KAAK,IAAI;AAAA,IAC3C,CAAC;AAGD,cAAU,MAAM;AACd,UAAI,OAAO;AACT,gBAAQ,iBAAiB,KAAK,CAAC;AAAA,MACjC,OAAO;AACL,gBAAQ,MAAS;AAAA,MACnB;AAAA,IACF,GAAG,CAAC,KAAK,CAAC;AAEV,UAAM,mBAAmB,CAAC,iBAAmC;AAC3D,cAAQ,YAAY;AAEpB,UAAI,cAAc;AAChB,mBAAW,OAAO,cAAc,YAAY,CAAC;AAC7C,gBAAQ,KAAK;AAAA,MACf,OAAO;AACL,mBAAW,MAAS;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,cAAc,OAAO,OAAO,MAAM,YAAY,IAAI;AAExD,WACE,qBAAC,WAAQ,MAAY,cAAc,SACjC;AAAA,0BAAC,kBAAe,SAAO,MACrB;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,OAAO,kBAAkB;AAAA,cAC3B;AAAA,cAEC;AAAA;AAAA,UACH;AAAA;AAAA,MACF,GACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAM;AAAA,UACN,YAAY;AAAA,UAEZ,8BAAC,SAAI,WAAU,OACb;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,UAAU;AAAA,cACV,UAAU;AAAA;AAAA,UACZ,GACF;AAAA;AAAA,MACF;AAAA,OACF;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/form/DatePicker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, forwardRef, useEffect } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport { format } from \"date-fns\";\nimport { Calendar } from \"./Calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlay/Popover\";\nimport { cn } from \"../../../infra/utils/clsx\";\n\n// Converte string ISO (yyyy-MM-dd) para Date no fuso horário local\n// Evita bug de timezone onde new Date(\"2025-08-02\") interpreta como UTC\nconst isoParaDataLocal = (iso: string): Date => {\n const [ano, mes, dia] = iso.split(\"-\").map(Number);\n return new Date(ano, mes - 1, dia);\n};\n\ninterface DatePickerProps {\n value?: string;\n onChange?: (date: string | undefined) => void;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n}\n\nexport const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(\n (\n { value, onChange, placeholder, className, disabled },\n ref,\n ) => {\n const translate = useTranslations();\n const resolvedPlaceholder = placeholder ?? translate('common.forms.datePicker.placeholder');\n const [open, setOpen] = useState(false);\n const [date, setDate] = useState<Date | undefined>(() => {\n return value ? isoParaDataLocal(value) : undefined;\n });\n\n // Sincroniza estado interno quando value mudar externamente\n useEffect(() => {\n if (value) {\n setDate(isoParaDataLocal(value));\n } else {\n setDate(undefined);\n }\n }, [value]);\n\n const handleDateSelect = (selectedDate: Date | undefined) => {\n setDate(selectedDate);\n\n if (selectedDate) {\n onChange?.(format(selectedDate, \"yyyy-MM-dd\"));\n setOpen(false); // Fecha o popover após seleção\n } else {\n onChange?.(undefined);\n }\n };\n\n const displayText = date ? format(date, \"dd/MM/yyyy\") : resolvedPlaceholder;\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n ref={ref}\n disabled={disabled}\n className={cn(\n \"flex items-center gap-2 px-4 h-10 border rounded-lg transition-colors w-full justify-start\",\n \"border-gray-200 hover:border-gray-400 focus-within:border-gray-950\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n className,\n )}\n >\n <span\n className={cn(\n \"paragraph-small-medium\",\n date ? \"text-gray-950\" : \"text-gray-500\",\n )}\n >\n {displayText}\n </span>\n </button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto p-0 bg-white rounded-2xl shadow-md border border-gray-200\"\n align=\"start\"\n sideOffset={8}\n >\n <div className=\"p-3\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={handleDateSelect}\n />\n </div>\n </PopoverContent>\n </Popover>\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"mappings":";AA2DM,SAYM,KAZN;AAzDN,SAAS,UAAU,YAAY,iBAAiB;AAChD,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,UAAU;AAInB,MAAM,mBAAmB,CAAC,QAAsB;AAC9C,QAAM,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM;AACjD,SAAO,IAAI,KAAK,KAAK,MAAM,GAAG,GAAG;AACnC;AAUO,MAAM,aAAa;AAAA,EACxB,CACE,EAAE,OAAO,UAAU,aAAa,WAAW,SAAS,GACpD,QACG;AACH,UAAM,YAAY,gBAAgB;AAClC,UAAM,sBAAsB,eAAe,UAAU,qCAAqC;AAC1F,UAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,UAAM,CAAC,MAAM,OAAO,IAAI,SAA2B,MAAM;AACvD,aAAO,QAAQ,iBAAiB,KAAK,IAAI;AAAA,IAC3C,CAAC;AAGD,cAAU,MAAM;AACd,UAAI,OAAO;AACT,gBAAQ,iBAAiB,KAAK,CAAC;AAAA,MACjC,OAAO;AACL,gBAAQ,MAAS;AAAA,MACnB;AAAA,IACF,GAAG,CAAC,KAAK,CAAC;AAEV,UAAM,mBAAmB,CAAC,iBAAmC;AAC3D,cAAQ,YAAY;AAEpB,UAAI,cAAc;AAChB,mBAAW,OAAO,cAAc,YAAY,CAAC;AAC7C,gBAAQ,KAAK;AAAA,MACf,OAAO;AACL,mBAAW,MAAS;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,cAAc,OAAO,OAAO,MAAM,YAAY,IAAI;AAExD,WACE,qBAAC,WAAQ,MAAY,cAAc,SACjC;AAAA,0BAAC,kBAAe,SAAO,MACrB;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,OAAO,kBAAkB;AAAA,cAC3B;AAAA,cAEC;AAAA;AAAA,UACH;AAAA;AAAA,MACF,GACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAM;AAAA,UACN,YAAY;AAAA,UAEZ,8BAAC,SAAI,WAAU,OACb;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,UAAU;AAAA,cACV,UAAU;AAAA;AAAA,UACZ,GACF;AAAA;AAAA,MACF;AAAA,OACF;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;","names":[]}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState, forwardRef, useEffect } from "react";
4
+ import { useTranslations } from "next-intl";
4
5
  import { format } from "date-fns";
5
6
  import { IconCalendar } from "@tabler/icons-react";
6
7
  import { Calendar } from "./Calendar";
@@ -11,7 +12,9 @@ const isoParaDataLocal = (iso) => {
11
12
  return new Date(ano, mes - 1, dia);
12
13
  };
13
14
  const DateRangePicker = forwardRef(
14
- ({ value, onChange, placeholder = "Selecione o per\xEDodo", className, disabled }, ref) => {
15
+ ({ value, onChange, placeholder, className, disabled }, ref) => {
16
+ const translate = useTranslations();
17
+ const resolvedPlaceholder = placeholder ?? translate("common.forms.dateRangePicker.placeholder");
15
18
  const [open, setOpen] = useState(false);
16
19
  const [range, setRange] = useState(() => {
17
20
  if (value?.from && value?.to) {
@@ -43,7 +46,7 @@ const DateRangePicker = forwardRef(
43
46
  onChange?.(void 0);
44
47
  }
45
48
  };
46
- const displayText = range?.from && range?.to ? `${format(range.from, "dd/MM/yyyy")} - ${format(range.to, "dd/MM/yyyy")}` : placeholder;
49
+ const displayText = range?.from && range?.to ? `${format(range.from, "dd/MM/yyyy")} - ${format(range.to, "dd/MM/yyyy")}` : resolvedPlaceholder;
47
50
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
48
51
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
49
52
  "button",