@greatapps/common 1.1.695 → 1.1.697

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 (555) hide show
  1. package/dist/components/account/ConfigurationsMyAccountModal.mjs +1 -1
  2. package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -1
  3. package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
  4. package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -1
  5. package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
  6. package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
  7. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
  8. package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
  9. package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
  10. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
  11. package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
  12. package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
  13. package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
  14. package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
  15. package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
  16. package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
  17. package/dist/components/account/sections/TokenSection.mjs.map +1 -1
  18. package/dist/components/embeds/ClarityEmbed.mjs.map +1 -1
  19. package/dist/components/embeds/CrispEmbed.mjs.map +1 -1
  20. package/dist/components/embeds/EmbedWidgets.mjs.map +1 -1
  21. package/dist/components/embeds/FrillEmbed.mjs.map +1 -1
  22. package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
  23. package/dist/components/layouts/AppNavBar.mjs.map +1 -1
  24. package/dist/components/layouts/MdSideBarNavigation.mjs.map +1 -1
  25. package/dist/components/layouts/NavBar.mjs.map +1 -1
  26. package/dist/components/layouts/NotificationsPopover.mjs.map +1 -1
  27. package/dist/components/layouts/ProfilePopover.mjs.map +1 -1
  28. package/dist/components/layouts/SideBarNavigation.mjs.map +1 -1
  29. package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
  30. package/dist/components/layouts/WhitelabelCodes.mjs.map +1 -1
  31. package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
  32. package/dist/components/modals/CreditsDisabledModal.mjs.map +1 -1
  33. package/dist/components/modals/Modals.mjs.map +1 -1
  34. package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
  35. package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
  36. package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
  37. package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
  38. package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
  39. package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
  40. package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
  41. package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
  42. package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
  43. package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
  44. package/dist/components/navigation/SubscriptionBanner.mjs.map +1 -1
  45. package/dist/components/navigation/TrialBanner.mjs.map +1 -1
  46. package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
  47. package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
  48. package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
  49. package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
  50. package/dist/components/pages/NotFoundPage.mjs.map +1 -1
  51. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  52. package/dist/components/ui/buttons/Button.mjs.map +1 -1
  53. package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
  54. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  55. package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
  56. package/dist/components/ui/data-display/Badge.mjs.map +1 -1
  57. package/dist/components/ui/data-display/Card.mjs.map +1 -1
  58. package/dist/components/ui/data-display/CardBrandIcons.mjs.map +1 -1
  59. package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
  60. package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
  61. package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
  62. package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
  63. package/dist/components/ui/data-display/Separator.mjs.map +1 -1
  64. package/dist/components/ui/data-display/Table.mjs.map +1 -1
  65. package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
  66. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
  67. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  68. package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
  69. package/dist/components/ui/feedback/Progress.mjs.map +1 -1
  70. package/dist/components/ui/feedback/Skeleton.mjs.map +1 -1
  71. package/dist/components/ui/feedback/Toast.mjs.map +1 -1
  72. package/dist/components/ui/form/Calendar.mjs.map +1 -1
  73. package/dist/components/ui/form/Checkbox.mjs.map +1 -1
  74. package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
  75. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  76. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  77. package/dist/components/ui/form/FormField.mjs.map +1 -1
  78. package/dist/components/ui/form/Input.mjs.map +1 -1
  79. package/dist/components/ui/form/InputOtp.mjs.map +1 -1
  80. package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
  81. package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
  82. package/dist/components/ui/form/Select.mjs +1 -1
  83. package/dist/components/ui/form/Select.mjs.map +1 -1
  84. package/dist/components/ui/form/Switch.mjs.map +1 -1
  85. package/dist/components/ui/form/Textarea.mjs.map +1 -1
  86. package/dist/components/ui/overlay/Command.mjs.map +1 -1
  87. package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
  88. package/dist/components/ui/overlay/Popover.mjs.map +1 -1
  89. package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
  90. package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
  91. package/dist/components/widgets/ImageUpload/ImageCropModal.mjs +10 -0
  92. package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
  93. package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
  94. package/dist/components/widgets/ImageUpload/ImageUpload.mjs.map +1 -1
  95. package/dist/components/widgets/ImageUpload/index.mjs.map +1 -1
  96. package/dist/components/widgets/notifications/NotificationCard.mjs.map +1 -1
  97. package/dist/handlers.mjs.map +1 -1
  98. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
  99. package/dist/hooks/useAuthQueryKey.mjs.map +1 -1
  100. package/dist/hooks/useBrandLoadingIcon.mjs.map +1 -1
  101. package/dist/hooks/useRouter.mjs.map +1 -1
  102. package/dist/http.mjs.map +1 -1
  103. package/dist/i18n/config.mjs.map +1 -1
  104. package/dist/i18n/country-language.mjs.map +1 -1
  105. package/dist/i18n/messages/en-us.mjs.map +1 -1
  106. package/dist/i18n/messages/es-es.mjs.map +1 -1
  107. package/dist/i18n/messages/index.mjs.map +1 -1
  108. package/dist/i18n/messages/pt-br.mjs.map +1 -1
  109. package/dist/i18n/normalize.mjs.map +1 -1
  110. package/dist/i18n/resolve-locale.mjs.map +1 -1
  111. package/dist/i18n.mjs.map +1 -1
  112. package/dist/index.mjs.map +1 -1
  113. package/dist/infra/http/api-fetch.mjs.map +1 -1
  114. package/dist/infra/route/parse-id.mjs.map +1 -1
  115. package/dist/infra/route/parse-numeric.mjs.map +1 -1
  116. package/dist/infra/route/safe-route-handler.mjs.map +1 -1
  117. package/dist/infra/route/search-params.mjs.map +1 -1
  118. package/dist/infra/utils/array.mjs.map +1 -1
  119. package/dist/infra/utils/date.mjs.map +1 -1
  120. package/dist/middleware.mjs.map +1 -1
  121. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  122. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  123. package/dist/modules/accounts/actions/get-account-token.action.mjs.map +1 -1
  124. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  125. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  126. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  127. package/dist/modules/accounts/hooks/use-account-token.hook.mjs.map +1 -1
  128. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -1
  129. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  130. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  131. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  132. package/dist/modules/accounts/hooks/useViaCep.mjs.map +1 -1
  133. package/dist/modules/accounts/services/account-token.service.mjs.map +1 -1
  134. package/dist/modules/accounts/services/account.service.mjs.map +1 -1
  135. package/dist/modules/auth/actions/social-google-login.action.mjs.map +1 -1
  136. package/dist/modules/auth/actions/social-google-onboarding.action.mjs.map +1 -1
  137. package/dist/modules/auth/actions/unlink-google.action.mjs.map +1 -1
  138. package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -1
  139. package/dist/modules/auth/actions/verify-two-factor.action.mjs.map +1 -1
  140. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  141. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  142. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  143. package/dist/modules/auth/hooks/social-google-login.hook.mjs.map +1 -1
  144. package/dist/modules/auth/hooks/social-google-onboarding.hook.mjs.map +1 -1
  145. package/dist/modules/auth/hooks/unlink-google.hook.mjs.map +1 -1
  146. package/dist/modules/auth/hooks/useManagementPermissions.mjs.map +1 -1
  147. package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -1
  148. package/dist/modules/auth/utils/assert-management-permission.mjs.map +1 -1
  149. package/dist/modules/auth/utils/assert-management-subscription.mjs.map +1 -1
  150. package/dist/modules/auth/utils/assert-paid-subscription.mjs.map +1 -1
  151. package/dist/modules/auth/utils/assert-subscription-addon.mjs.map +1 -1
  152. package/dist/modules/auth/utils/build-wl-override.mjs.map +1 -1
  153. package/dist/modules/auth/utils/require-token-not-expired.mjs.map +1 -1
  154. package/dist/modules/auth/utils/require-valid-session.mjs.map +1 -1
  155. package/dist/modules/cards/actions/create-card.action.mjs.map +1 -1
  156. package/dist/modules/cards/actions/create-setup-intent.action.mjs.map +1 -1
  157. package/dist/modules/cards/actions/delete-card.action.mjs.map +1 -1
  158. package/dist/modules/cards/actions/set-default-card.action.mjs.map +1 -1
  159. package/dist/modules/cards/handlers/find-card-by-id.handler.mjs.map +1 -1
  160. package/dist/modules/cards/handlers/list-cards.handler.mjs.map +1 -1
  161. package/dist/modules/cards/hooks/card-by-id.hook.mjs.map +1 -1
  162. package/dist/modules/cards/hooks/cards.hook.mjs.map +1 -1
  163. package/dist/modules/cards/hooks/create-card.hook.mjs.map +1 -1
  164. package/dist/modules/cards/hooks/create-setup-intent.hook.mjs.map +1 -1
  165. package/dist/modules/cards/hooks/delete-card.hook.mjs.map +1 -1
  166. package/dist/modules/cards/hooks/delete-confirmation.hook.mjs.map +1 -1
  167. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
  168. package/dist/modules/cards/hooks/set-default-card.hook.mjs.map +1 -1
  169. package/dist/modules/cards/services/cards.service.mjs.map +1 -1
  170. package/dist/modules/cards/types.mjs.map +1 -1
  171. package/dist/modules/charges/actions/charge-action.action.mjs.map +1 -1
  172. package/dist/modules/charges/handlers/find-charge-by-id.handler.mjs.map +1 -1
  173. package/dist/modules/charges/handlers/list-charges.handler.mjs.map +1 -1
  174. package/dist/modules/charges/hooks/charge-action.hook.mjs.map +1 -1
  175. package/dist/modules/charges/hooks/charge-by-id.hook.mjs.map +1 -1
  176. package/dist/modules/charges/hooks/charges.hook.mjs.map +1 -1
  177. package/dist/modules/charges/services/charges.service.mjs.map +1 -1
  178. package/dist/modules/charges/types/charge.type.mjs.map +1 -1
  179. package/dist/modules/ia-credits/handlers/list-ia-credits.handler.mjs.map +1 -1
  180. package/dist/modules/ia-credits/hooks/ia-credits.hook.mjs.map +1 -1
  181. package/dist/modules/images/actions/process-image.action.mjs.map +1 -1
  182. package/dist/modules/images/constants/image.constants.mjs.map +1 -1
  183. package/dist/modules/images/hooks/use-image-upload.hook.mjs +4 -1
  184. package/dist/modules/images/hooks/use-image-upload.hook.mjs.map +1 -1
  185. package/dist/modules/images/services/image-processing.service.mjs.map +1 -1
  186. package/dist/modules/images/utils/base64.mjs.map +1 -1
  187. package/dist/modules/images/utils/compress-image.mjs.map +1 -1
  188. package/dist/modules/images/utils/crop-image.mjs +6 -2
  189. package/dist/modules/images/utils/crop-image.mjs.map +1 -1
  190. package/dist/modules/images/utils/validate-image.mjs.map +1 -1
  191. package/dist/modules/pages/constants/query-keys.constants.mjs.map +1 -1
  192. package/dist/modules/pages/handlers/count-pages.handler.mjs.map +1 -1
  193. package/dist/modules/pages/hooks/count-pages.hook.mjs.map +1 -1
  194. package/dist/modules/pages/services/pages.service.mjs.map +1 -1
  195. package/dist/modules/plans/handlers/find-plan-by-id.handler.mjs.map +1 -1
  196. package/dist/modules/plans/handlers/list-plans.handler.mjs.map +1 -1
  197. package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
  198. package/dist/modules/plans/hooks/use-has-plan-addon.hook.mjs.map +1 -1
  199. package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
  200. package/dist/modules/plans/services/plans.service.mjs.map +1 -1
  201. package/dist/modules/plans/types/plan.type.mjs.map +1 -1
  202. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
  203. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  204. package/dist/modules/projects/actions/create-project.action.mjs.map +1 -1
  205. package/dist/modules/projects/actions/delete-project.action.mjs.map +1 -1
  206. package/dist/modules/projects/actions/find-project.action.mjs.map +1 -1
  207. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  208. package/dist/modules/projects/actions/list-projects.action.mjs.map +1 -1
  209. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  210. package/dist/modules/projects/actions/update-project.action.mjs.map +1 -1
  211. package/dist/modules/projects/handlers/find-project.handler.mjs.map +1 -1
  212. package/dist/modules/projects/handlers/list-all-account-users.handler.mjs.map +1 -1
  213. package/dist/modules/projects/handlers/list-available-users.handler.mjs.map +1 -1
  214. package/dist/modules/projects/handlers/list-project-users.handler.mjs.map +1 -1
  215. package/dist/modules/projects/handlers/list-projects.handler.mjs.map +1 -1
  216. package/dist/modules/projects/hooks/add-project-user.hook.mjs.map +1 -1
  217. package/dist/modules/projects/hooks/create-project.hook.mjs.map +1 -1
  218. package/dist/modules/projects/hooks/delete-project.hook.mjs.map +1 -1
  219. package/dist/modules/projects/hooks/find-project.hook.mjs.map +1 -1
  220. package/dist/modules/projects/hooks/list-all-account-users.hook.mjs.map +1 -1
  221. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  222. package/dist/modules/projects/hooks/list-infinite-projects.hook.mjs.map +1 -1
  223. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  224. package/dist/modules/projects/hooks/list-projects.hook.mjs.map +1 -1
  225. package/dist/modules/projects/hooks/remove-project-user.hook.mjs.map +1 -1
  226. package/dist/modules/projects/hooks/update-project.hook.mjs.map +1 -1
  227. package/dist/modules/projects/services/projects.service.mjs.map +1 -1
  228. package/dist/modules/subscriptions/actions/calculate-subscription.action.mjs.map +1 -1
  229. package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
  230. package/dist/modules/subscriptions/actions/update-subscription-payment.action.mjs.map +1 -1
  231. package/dist/modules/subscriptions/actions/update-subscription-plan.action.mjs.map +1 -1
  232. package/dist/modules/subscriptions/constants/query-keys.constants.mjs.map +1 -1
  233. package/dist/modules/subscriptions/constants/subscription.constants.mjs.map +1 -1
  234. package/dist/modules/subscriptions/handlers/list-subscriptions.handler.mjs.map +1 -1
  235. package/dist/modules/subscriptions/hooks/calculate-subscription.hook.mjs.map +1 -1
  236. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  237. package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
  238. package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs.map +1 -1
  239. package/dist/modules/subscriptions/hooks/update-subscription-plan.hook.mjs.map +1 -1
  240. package/dist/modules/subscriptions/hooks/use-cancelled-subscription-guard.mjs.map +1 -1
  241. package/dist/modules/subscriptions/types/calculate-subscription.type.mjs.map +1 -1
  242. package/dist/modules/subscriptions/types/pix-pending.type.mjs.map +1 -1
  243. package/dist/modules/subscriptions/utils/build-plan-extras.mjs.map +1 -1
  244. package/dist/modules/subscriptions/utils/get-subscription-cancellation-state.mjs.map +1 -1
  245. package/dist/modules/subscriptions/utils/get-subscription-expiry-date.mjs.map +1 -1
  246. package/dist/modules/subscriptions/utils/has-subscription-expired.mjs.map +1 -1
  247. package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
  248. package/dist/modules/subscriptions/utils/resolve-plan-extras-prices.mjs.map +1 -1
  249. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
  250. package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
  251. package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
  252. package/dist/modules/users/handlers/list-messages.handler.mjs.map +1 -1
  253. package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
  254. package/dist/modules/users/services/messages.service.mjs.map +1 -1
  255. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
  256. package/dist/modules/whitelabel/actions/revalidate-whitelabel.action.mjs.map +1 -1
  257. package/dist/modules/whitelabel/utils/normalize-hostname.mjs.map +1 -1
  258. package/dist/providers/auth.provider.mjs.map +1 -1
  259. package/dist/providers/navigation.provider.mjs.map +1 -1
  260. package/dist/providers/whitelabel.provider.mjs.map +1 -1
  261. package/dist/route.mjs.map +1 -1
  262. package/dist/store/useAccountModals.mjs.map +1 -1
  263. package/dist/store/useBuyCreditsModal.mjs.map +1 -1
  264. package/dist/store/useCreditsDisabledModal.mjs.map +1 -1
  265. package/dist/store/useDesktopSidebarStore.mjs.map +1 -1
  266. package/dist/store/useMdSidebarStore.mjs.map +1 -1
  267. package/dist/store/usePaidPlanRequiredModal.mjs.map +1 -1
  268. package/dist/utils/constants/br-states.mjs.map +1 -1
  269. package/dist/utils/countries.mjs.map +1 -1
  270. package/dist/utils/format/currency.mjs.map +1 -1
  271. package/dist/utils/intl/cookie-domain.mjs.map +1 -1
  272. package/dist/utils/intl/locale-cookie.mjs.map +1 -1
  273. package/dist/utils/next-navigation.mjs.map +1 -1
  274. package/dist/utils/redirect.mjs.map +1 -1
  275. package/dist/utils/safeMutationAction.mjs.map +1 -1
  276. package/dist/utils/safeServerAction.mjs.map +1 -1
  277. package/dist/utils/withAction.mjs.map +1 -1
  278. package/package.json +115 -115
  279. package/src/components/account/ConfigurationsMyAccountModal.tsx +179 -179
  280. package/src/components/account/ConfirmDeleteAccountModal.tsx +110 -110
  281. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +68 -68
  282. package/src/components/account/DeleteAccountModal.tsx +160 -160
  283. package/src/components/account/DisableTwoFactorAuthModal.tsx +92 -92
  284. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +51 -51
  285. package/src/components/account/TwoFactorAuthModal.tsx +220 -220
  286. package/src/components/account/hooks/useChangePhoneForm.tsx +113 -113
  287. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +116 -116
  288. package/src/components/account/sections/ChangeEmailModal.tsx +239 -239
  289. package/src/components/account/sections/ChangePasswordSection.tsx +68 -68
  290. package/src/components/account/sections/ChangePhoneModal.tsx +273 -273
  291. package/src/components/account/sections/MyProfileSection.tsx +276 -276
  292. package/src/components/account/sections/PreferencesSection.tsx +278 -278
  293. package/src/components/account/sections/SecuritySection.tsx +102 -102
  294. package/src/components/account/sections/TokenSection.tsx +85 -85
  295. package/src/components/embeds/ClarityEmbed.tsx +70 -70
  296. package/src/components/embeds/CrispEmbed.tsx +195 -195
  297. package/src/components/embeds/EmbedWidgets.tsx +62 -62
  298. package/src/components/embeds/FrillEmbed.tsx +146 -146
  299. package/src/components/layouts/AppMobileNavBar.tsx +214 -214
  300. package/src/components/layouts/AppNavBar.tsx +40 -40
  301. package/src/components/layouts/MdSideBarNavigation.tsx +56 -56
  302. package/src/components/layouts/NavBar.tsx +228 -228
  303. package/src/components/layouts/NotificationsPopover.tsx +120 -120
  304. package/src/components/layouts/ProfilePopover.tsx +191 -191
  305. package/src/components/layouts/SideBarNavigation.tsx +65 -65
  306. package/src/components/layouts/UsersSelectorPopover.tsx +236 -236
  307. package/src/components/layouts/WhitelabelCodes.tsx +59 -59
  308. package/src/components/modals/BuyCreditsModal.tsx +390 -390
  309. package/src/components/modals/CreditsDisabledModal.tsx +62 -62
  310. package/src/components/modals/Modals.tsx +25 -25
  311. package/src/components/modals/PaidPlanRequiredModal.tsx +60 -60
  312. package/src/components/modals/cards/AddCardModal.tsx +420 -420
  313. package/src/components/modals/cards/CannotDeleteCardModal.tsx +124 -124
  314. package/src/components/modals/cards/CardFormFields.tsx +363 -363
  315. package/src/components/modals/cards/DeleteCardModal.tsx +136 -136
  316. package/src/components/navigation/CancelledSubscriptionBanner.tsx +62 -62
  317. package/src/components/navigation/NavItemsContext.ts +20 -20
  318. package/src/components/navigation/OverdueInvoiceBanner.tsx +51 -51
  319. package/src/components/navigation/PendingCancellationBanner.tsx +60 -60
  320. package/src/components/navigation/ProjectSelectorPopover.tsx +180 -180
  321. package/src/components/navigation/SubscriptionBanner.tsx +94 -94
  322. package/src/components/navigation/TrialBanner.tsx +54 -54
  323. package/src/components/navigation/UpcomingInvoiceBanner.tsx +55 -55
  324. package/src/components/navigation/shells/TabsMobileShell.tsx +74 -74
  325. package/src/components/navigation/subcomponents/BottomLinks.tsx +85 -85
  326. package/src/components/navigation/subcomponents/ProjectSelector.tsx +184 -184
  327. package/src/components/pages/NotFoundPage.tsx +75 -75
  328. package/src/components/pages/notifications/Notifications.tsx +190 -190
  329. package/src/components/ui/buttons/Button.tsx +77 -77
  330. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  331. package/src/components/ui/buttons/CopyButton.tsx +59 -59
  332. package/src/components/ui/data-display/Accordion.tsx +81 -81
  333. package/src/components/ui/data-display/Badge.tsx +47 -47
  334. package/src/components/ui/data-display/Card.tsx +93 -93
  335. package/src/components/ui/data-display/CardBrandIcons.tsx +336 -336
  336. package/src/components/ui/data-display/CardItem.tsx +135 -135
  337. package/src/components/ui/data-display/Pagination.tsx +126 -126
  338. package/src/components/ui/data-display/PaymentInfoCard.tsx +193 -193
  339. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  340. package/src/components/ui/data-display/Separator.tsx +29 -29
  341. package/src/components/ui/data-display/Table.tsx +117 -117
  342. package/src/components/ui/data-display/Tabs.tsx +67 -67
  343. package/src/components/ui/feedback/CircularProgress.tsx +79 -79
  344. package/src/components/ui/feedback/DefaultCircularProgress.tsx +67 -67
  345. package/src/components/ui/feedback/LoadingOverlay.tsx +30 -30
  346. package/src/components/ui/feedback/Progress.tsx +40 -40
  347. package/src/components/ui/feedback/Skeleton.tsx +5 -5
  348. package/src/components/ui/feedback/Toast.tsx +104 -104
  349. package/src/components/ui/form/Calendar.tsx +228 -228
  350. package/src/components/ui/form/Checkbox.tsx +31 -31
  351. package/src/components/ui/form/ComboboxField.tsx +159 -159
  352. package/src/components/ui/form/DatePicker.tsx +100 -100
  353. package/src/components/ui/form/DateRangePicker.tsx +111 -111
  354. package/src/components/ui/form/FormField.tsx +133 -133
  355. package/src/components/ui/form/Input.tsx +20 -20
  356. package/src/components/ui/form/InputOtp.tsx +80 -80
  357. package/src/components/ui/form/PhoneInput.tsx +210 -210
  358. package/src/components/ui/form/RadioGroup.tsx +45 -45
  359. package/src/components/ui/form/Select.tsx +200 -200
  360. package/src/components/ui/form/Switch.tsx +32 -32
  361. package/src/components/ui/form/Textarea.tsx +19 -19
  362. package/src/components/ui/overlay/Command.tsx +185 -185
  363. package/src/components/ui/overlay/Dialog.tsx +153 -153
  364. package/src/components/ui/overlay/Popover.tsx +49 -49
  365. package/src/components/ui/overlay/Sheet.tsx +170 -170
  366. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  367. package/src/components/widgets/ImageUpload/ImageCropModal.tsx +392 -382
  368. package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +62 -62
  369. package/src/components/widgets/ImageUpload/ImageUpload.tsx +131 -131
  370. package/src/components/widgets/ImageUpload/index.ts +3 -3
  371. package/src/components/widgets/notifications/NotificationCard.tsx +73 -73
  372. package/src/handlers.ts +22 -22
  373. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  374. package/src/hooks/useAuthQueryKey.ts +32 -32
  375. package/src/hooks/useBrandLoadingIcon.tsx +18 -18
  376. package/src/hooks/useRouter.ts +38 -38
  377. package/src/http.ts +1 -1
  378. package/src/i18n/config.ts +17 -17
  379. package/src/i18n/country-language.ts +60 -60
  380. package/src/i18n/messages/en-us.ts +519 -519
  381. package/src/i18n/messages/es-es.ts +520 -520
  382. package/src/i18n/messages/index.ts +24 -24
  383. package/src/i18n/messages/pt-br.ts +543 -543
  384. package/src/i18n/normalize.ts +15 -15
  385. package/src/i18n/resolve-locale.ts +77 -77
  386. package/src/i18n.ts +10 -10
  387. package/src/index.ts +584 -584
  388. package/src/infra/http/api-fetch.ts +39 -39
  389. package/src/infra/route/parse-id.ts +9 -9
  390. package/src/infra/route/parse-numeric.ts +16 -16
  391. package/src/infra/route/safe-route-handler.ts +16 -16
  392. package/src/infra/route/search-params.ts +9 -9
  393. package/src/infra/utils/array.ts +167 -167
  394. package/src/infra/utils/date.ts +59 -59
  395. package/src/middleware.ts +4 -4
  396. package/src/modules/accounts/actions/account-management.action.ts +109 -109
  397. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  398. package/src/modules/accounts/actions/get-account-token.action.ts +8 -8
  399. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  400. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  401. package/src/modules/accounts/hooks/current-account.hook.tsx +26 -26
  402. package/src/modules/accounts/hooks/use-account-token.hook.tsx +14 -14
  403. package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -32
  404. package/src/modules/accounts/hooks/useAccountManagement.ts +95 -95
  405. package/src/modules/accounts/hooks/useCurrencies.ts +18 -18
  406. package/src/modules/accounts/hooks/useTimezones.ts +18 -18
  407. package/src/modules/accounts/hooks/useViaCep.ts +25 -25
  408. package/src/modules/accounts/services/account-token.service.ts +52 -52
  409. package/src/modules/accounts/services/account.service.ts +243 -243
  410. package/src/modules/accounts/types.ts +230 -230
  411. package/src/modules/auth/actions/social-google-login.action.ts +12 -12
  412. package/src/modules/auth/actions/social-google-onboarding.action.ts +13 -13
  413. package/src/modules/auth/actions/unlink-google.action.ts +8 -8
  414. package/src/modules/auth/actions/validate-session.action.ts +70 -70
  415. package/src/modules/auth/actions/verify-two-factor.action.ts +19 -19
  416. package/src/modules/auth/hooks/login.hook.tsx +13 -13
  417. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  418. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  419. package/src/modules/auth/hooks/social-google-login.hook.tsx +13 -13
  420. package/src/modules/auth/hooks/social-google-onboarding.hook.tsx +13 -13
  421. package/src/modules/auth/hooks/unlink-google.hook.tsx +13 -13
  422. package/src/modules/auth/hooks/useManagementPermissions.ts +52 -52
  423. package/src/modules/auth/hooks/useUserQuery.ts +103 -103
  424. package/src/modules/auth/types/management-permission.type.ts +14 -14
  425. package/src/modules/auth/utils/assert-management-permission.ts +56 -56
  426. package/src/modules/auth/utils/assert-management-subscription.ts +38 -38
  427. package/src/modules/auth/utils/assert-paid-subscription.ts +47 -47
  428. package/src/modules/auth/utils/assert-subscription-addon.ts +42 -42
  429. package/src/modules/auth/utils/build-wl-override.ts +43 -43
  430. package/src/modules/auth/utils/require-token-not-expired.ts +53 -53
  431. package/src/modules/auth/utils/require-valid-session.ts +35 -35
  432. package/src/modules/cards/actions/create-card.action.ts +9 -9
  433. package/src/modules/cards/actions/create-setup-intent.action.ts +8 -8
  434. package/src/modules/cards/actions/delete-card.action.ts +8 -8
  435. package/src/modules/cards/actions/set-default-card.action.ts +8 -8
  436. package/src/modules/cards/handlers/find-card-by-id.handler.ts +15 -15
  437. package/src/modules/cards/handlers/list-cards.handler.ts +10 -10
  438. package/src/modules/cards/hooks/card-by-id.hook.ts +17 -17
  439. package/src/modules/cards/hooks/cards.hook.ts +22 -22
  440. package/src/modules/cards/hooks/create-card.hook.ts +30 -30
  441. package/src/modules/cards/hooks/create-setup-intent.hook.ts +11 -11
  442. package/src/modules/cards/hooks/delete-card.hook.ts +52 -52
  443. package/src/modules/cards/hooks/delete-confirmation.hook.ts +40 -40
  444. package/src/modules/cards/hooks/handle-delete-card.hook.ts +47 -47
  445. package/src/modules/cards/hooks/set-default-card.hook.ts +55 -55
  446. package/src/modules/cards/services/cards.service.ts +136 -136
  447. package/src/modules/cards/types.ts +52 -52
  448. package/src/modules/charges/actions/charge-action.action.ts +13 -13
  449. package/src/modules/charges/handlers/find-charge-by-id.handler.ts +14 -14
  450. package/src/modules/charges/handlers/list-charges.handler.ts +15 -15
  451. package/src/modules/charges/hooks/charge-action.hook.ts +24 -24
  452. package/src/modules/charges/hooks/charge-by-id.hook.ts +19 -19
  453. package/src/modules/charges/hooks/charges.hook.ts +19 -19
  454. package/src/modules/charges/services/charges.service.ts +63 -63
  455. package/src/modules/charges/types/charge.type.ts +68 -68
  456. package/src/modules/ia-credits/handlers/list-ia-credits.handler.ts +14 -14
  457. package/src/modules/ia-credits/hooks/ia-credits.hook.ts +103 -103
  458. package/src/modules/images/actions/process-image.action.ts +40 -40
  459. package/src/modules/images/constants/image.constants.ts +11 -11
  460. package/src/modules/images/hooks/use-image-upload.hook.ts +153 -145
  461. package/src/modules/images/services/image-processing.service.ts +75 -75
  462. package/src/modules/images/types/image.type.ts +54 -54
  463. package/src/modules/images/utils/base64.ts +26 -26
  464. package/src/modules/images/utils/compress-image.ts +20 -20
  465. package/src/modules/images/utils/crop-image.ts +68 -51
  466. package/src/modules/images/utils/validate-image.ts +86 -86
  467. package/src/modules/pages/constants/query-keys.constants.ts +1 -1
  468. package/src/modules/pages/handlers/count-pages.handler.ts +12 -12
  469. package/src/modules/pages/hooks/count-pages.hook.ts +21 -21
  470. package/src/modules/pages/services/pages.service.ts +27 -27
  471. package/src/modules/plans/handlers/find-plan-by-id.handler.ts +14 -14
  472. package/src/modules/plans/handlers/list-plans.handler.ts +22 -22
  473. package/src/modules/plans/hooks/list-plans.hook.ts +23 -23
  474. package/src/modules/plans/hooks/use-has-plan-addon.hook.ts +14 -14
  475. package/src/modules/plans/hooks/use-plan-by-id.hook.ts +39 -39
  476. package/src/modules/plans/services/plans.service.ts +135 -135
  477. package/src/modules/plans/types/plan.type.ts +75 -75
  478. package/src/modules/plans/utils/map-api-plan-to-ui.ts +167 -167
  479. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  480. package/src/modules/projects/actions/create-project.action.ts +9 -9
  481. package/src/modules/projects/actions/delete-project.action.ts +8 -8
  482. package/src/modules/projects/actions/find-project.action.ts +8 -8
  483. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  484. package/src/modules/projects/actions/list-projects.action.ts +16 -16
  485. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  486. package/src/modules/projects/actions/update-project.action.ts +9 -9
  487. package/src/modules/projects/handlers/find-project.handler.ts +15 -15
  488. package/src/modules/projects/handlers/list-all-account-users.handler.ts +23 -23
  489. package/src/modules/projects/handlers/list-available-users.handler.ts +26 -26
  490. package/src/modules/projects/handlers/list-project-users.handler.ts +26 -26
  491. package/src/modules/projects/handlers/list-projects.handler.ts +23 -23
  492. package/src/modules/projects/hooks/add-project-user.hook.ts +72 -72
  493. package/src/modules/projects/hooks/create-project.hook.ts +120 -120
  494. package/src/modules/projects/hooks/delete-project.hook.ts +58 -58
  495. package/src/modules/projects/hooks/find-project.hook.ts +18 -18
  496. package/src/modules/projects/hooks/list-all-account-users.hook.ts +40 -40
  497. package/src/modules/projects/hooks/list-available-users.hook.ts +39 -39
  498. package/src/modules/projects/hooks/list-infinite-projects.hook.ts +44 -44
  499. package/src/modules/projects/hooks/list-project-users.hook.ts +39 -39
  500. package/src/modules/projects/hooks/list-projects.hook.ts +23 -23
  501. package/src/modules/projects/hooks/remove-project-user.hook.ts +72 -72
  502. package/src/modules/projects/hooks/update-project.hook.ts +86 -86
  503. package/src/modules/projects/services/projects.service.ts +156 -156
  504. package/src/modules/subscriptions/actions/calculate-subscription.action.ts +9 -9
  505. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  506. package/src/modules/subscriptions/actions/update-subscription-payment.action.ts +13 -13
  507. package/src/modules/subscriptions/actions/update-subscription-plan.action.ts +14 -14
  508. package/src/modules/subscriptions/constants/query-keys.constants.ts +3 -3
  509. package/src/modules/subscriptions/constants/subscription.constants.ts +1 -1
  510. package/src/modules/subscriptions/handlers/list-subscriptions.handler.ts +17 -17
  511. package/src/modules/subscriptions/hooks/calculate-subscription.hook.ts +13 -13
  512. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +22 -22
  513. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +22 -22
  514. package/src/modules/subscriptions/hooks/update-subscription-payment.hook.ts +25 -25
  515. package/src/modules/subscriptions/hooks/update-subscription-plan.hook.ts +28 -28
  516. package/src/modules/subscriptions/hooks/use-cancelled-subscription-guard.ts +44 -44
  517. package/src/modules/subscriptions/types/billing-period.type.ts +1 -1
  518. package/src/modules/subscriptions/types/calculate-subscription.type.ts +116 -116
  519. package/src/modules/subscriptions/types/pix-pending.type.ts +38 -38
  520. package/src/modules/subscriptions/utils/build-plan-extras.ts +56 -56
  521. package/src/modules/subscriptions/utils/get-subscription-cancellation-state.ts +37 -37
  522. package/src/modules/subscriptions/utils/get-subscription-expiry-date.ts +33 -33
  523. package/src/modules/subscriptions/utils/has-subscription-expired.ts +11 -11
  524. package/src/modules/subscriptions/utils/periodicity.ts +79 -79
  525. package/src/modules/subscriptions/utils/resolve-plan-extras-prices.ts +23 -23
  526. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  527. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  528. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  529. package/src/modules/users/handlers/list-messages.handler.ts +39 -39
  530. package/src/modules/users/hooks/messages.hook.ts +69 -69
  531. package/src/modules/users/services/messages.service.ts +49 -49
  532. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  533. package/src/modules/whitelabel/actions/revalidate-whitelabel.action.ts +19 -19
  534. package/src/modules/whitelabel/schema.ts +84 -84
  535. package/src/modules/whitelabel/utils/normalize-hostname.ts +26 -26
  536. package/src/providers/auth.provider.tsx +264 -264
  537. package/src/providers/navigation.provider.tsx +99 -99
  538. package/src/providers/whitelabel.provider.tsx +90 -90
  539. package/src/route.ts +4 -4
  540. package/src/store/useAccountModals.ts +85 -85
  541. package/src/store/useBuyCreditsModal.ts +21 -21
  542. package/src/store/useCreditsDisabledModal.ts +11 -11
  543. package/src/store/useDesktopSidebarStore.ts +47 -47
  544. package/src/store/useMdSidebarStore.ts +34 -34
  545. package/src/store/usePaidPlanRequiredModal.ts +19 -19
  546. package/src/utils/constants/br-states.ts +29 -29
  547. package/src/utils/countries.ts +224 -224
  548. package/src/utils/format/currency.ts +70 -70
  549. package/src/utils/intl/cookie-domain.ts +29 -29
  550. package/src/utils/intl/locale-cookie.ts +18 -18
  551. package/src/utils/next-navigation.ts +7 -7
  552. package/src/utils/redirect.ts +78 -78
  553. package/src/utils/safeMutationAction.ts +24 -24
  554. package/src/utils/safeServerAction.ts +21 -21
  555. package/src/utils/withAction.ts +13 -13
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/modals/cards/CardFormFields.tsx"],"sourcesContent":["\"use client\";\n\nimport { UseFormReturn } from \"react-hook-form\";\nimport { useViaCep } from \"../../../modules/accounts/hooks/useViaCep\";\nimport { FormField } from \"../../ui/form/FormField\";\nimport { SelectField } from \"../../ui/form/SelectField\";\nimport { COUNTRIES } from \"../../../utils/countries\";\nimport {\n formatCPF,\n formatCNPJ,\n formatPostalCode,\n} from \"../../../utils/format/masks\";\nimport z from \"zod\";\nimport {\n CardCvcElement,\n CardExpiryElement,\n CardNumberElement,\n} from \"@stripe/react-stripe-js\";\nimport { useTranslations } from \"next-intl\";\n\nconst stripeElementOptions = {\n style: {\n base: {\n fontSize: \"16px\",\n color: \"#030712\",\n fontFamily: \"Inter, sans-serif\",\n \"::placeholder\": {\n color: \"#9ca3af\",\n },\n },\n },\n};\n\nexport function buildCardFormSchema(isInternational: boolean) {\n const base = z.object({\n name: z.string().min(1, \"Nome é obrigatório\"),\n country: z.string().min(1, \"País é obrigatório\"),\n personType: z.enum([\"pf\", \"pj\"]).optional(),\n cpf: z.string().optional(),\n cnpj: z.string().optional(),\n fullName: z.string().min(1, \"Nome completo é obrigatório\"),\n cep: z.string().min(isInternational ? 1 : 9, isInternational ? \"Código postal é obrigatório\" : \"CEP é obrigatório\"),\n street: z.string().min(1, \"Endereço é obrigatório\"),\n streetNumber: isInternational ? z.string().optional() : z.string().min(1, \"Número é obrigatório\"),\n city: z.string().min(1, \"Cidade é obrigatória\"),\n state: z.string().min(1, \"UF é obrigatório\"),\n neighborhood: isInternational ? z.string().optional() : z.string().min(1, \"Bairro é obrigatório\"),\n complement: z.string().optional(),\n });\n if (isInternational) return base;\n return base.refine(\n (data) => {\n if (data.personType === \"pf\") return !!data.cpf && data.cpf.length >= 14;\n return !!data.cnpj && data.cnpj.length >= 18;\n },\n {\n message: \"Documento é obrigatório\",\n path: [\"cpf\"],\n },\n );\n}\n\nexport const cardFormSchema = buildCardFormSchema(false);\n\nexport type CardFormData = z.infer<typeof cardFormSchema>;\n\nexport type StripeElementsStatus = {\n cardNumber: boolean;\n cardExpiry: boolean;\n cardCvc: boolean;\n};\n\nexport const STEP1_FIELDS = [\n \"name\",\n \"country\",\n \"personType\",\n \"cpf\",\n \"cnpj\",\n] as const;\n\ntype CardFormFieldsProps = {\n readonly form: UseFormReturn<CardFormData>;\n readonly onStripeChange: (\n field: keyof StripeElementsStatus,\n complete: boolean,\n ) => void;\n readonly stripeErrors: {\n cardNumber?: string;\n cardExpiry?: string;\n cardCvc?: string;\n };\n readonly isInternational?: boolean;\n};\n\nexport function CardFormFields({\n form,\n onStripeChange,\n stripeErrors,\n isInternational = false,\n}: CardFormFieldsProps) {\n const translate = useTranslations();\n const {\n register,\n watch,\n setValue,\n formState: { errors },\n } = form;\n\n const personType = watch(\"personType\");\n\n return (\n <div className=\"flex flex-col gap-5\">\n <FormField\n label={translate('common.cards.form.nameOnCard')}\n placeholder={translate('common.cards.form.typeHere')}\n {...register(\"name\")}\n error={!!errors.name}\n errorMessage={errors.name?.message}\n />\n\n <div className=\"flex flex-col gap-1.5\">\n <label className=\"paragraph-xsmall-semibold text-zinc-600\">\n {translate('common.cards.form.cardNumber')}\n </label>\n <div className=\"h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400 relative\">\n <div className=\"w-full\">\n <CardNumberElement\n options={{ ...stripeElementOptions, showIcon: true }}\n onChange={(e: { complete: boolean }) =>\n onStripeChange(\"cardNumber\", e.complete)\n }\n />\n </div>\n </div>\n {stripeErrors.cardNumber && (\n <p className=\"paragraph-xsmall-semibold text-red-600\">\n {stripeErrors.cardNumber}\n </p>\n )}\n </div>\n\n <div className=\"flex gap-4\">\n <div className=\"flex-1 flex flex-col gap-1.5\">\n <label className=\"paragraph-xsmall-semibold text-zinc-600\">\n {translate('common.cards.form.cardExpiry')}\n </label>\n <div className=\"h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400\">\n <div className=\"w-full\">\n <CardExpiryElement\n options={stripeElementOptions}\n onChange={(e: { complete: boolean }) =>\n onStripeChange(\"cardExpiry\", e.complete)\n }\n />\n </div>\n </div>\n {stripeErrors.cardExpiry && (\n <p className=\"paragraph-xsmall-semibold text-red-600\">\n {stripeErrors.cardExpiry}\n </p>\n )}\n </div>\n\n <div className=\"flex-1 flex flex-col gap-1.5\">\n <label className=\"paragraph-xsmall-semibold text-zinc-600\">{translate('common.cards.form.cardCvc')}</label>\n <div className=\"h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400\">\n <div className=\"w-full\">\n <CardCvcElement\n options={stripeElementOptions}\n onChange={(e: { complete: boolean }) =>\n onStripeChange(\"cardCvc\", e.complete)\n }\n />\n </div>\n </div>\n {stripeErrors.cardCvc && (\n <p className=\"paragraph-xsmall-semibold text-red-600\">\n {stripeErrors.cardCvc}\n </p>\n )}\n </div>\n </div>\n\n <SelectField\n label={translate('common.cards.form.country')}\n placeholder={translate('common.cards.form.select')}\n value={watch(\"country\")}\n onChange={(value) => setValue(\"country\", value as string)}\n options={COUNTRIES.map((c) => ({ value: c.iso, label: c.name }))}\n />\n\n {!isInternational && (\n <div className=\"flex gap-4\">\n <SelectField\n label={translate('common.cards.form.personType')}\n placeholder={translate('common.cards.form.select')}\n value={personType}\n onChange={(value) => {\n setValue(\"personType\", value as \"pf\" | \"pj\");\n setValue(\"cpf\", \"\");\n setValue(\"cnpj\", \"\");\n }}\n options={[\n { value: \"pf\", label: translate('common.cards.form.personTypePf') },\n { value: \"pj\", label: translate('common.cards.form.personTypePj') },\n ]}\n containerClassName=\"flex-1\"\n />\n <div className=\"flex-1\">\n {personType === \"pj\" ? (\n <FormField\n label={translate('common.cards.form.cnpj')}\n placeholder=\"__.___.___/____-__\"\n {...register(\"cnpj\", {\n onChange: (e) => {\n setValue(\"cnpj\", formatCNPJ(e.target.value));\n },\n })}\n error={!!errors.cpf}\n errorMessage={errors.cpf?.message}\n />\n ) : (\n <FormField\n label={translate('common.cards.form.cpf')}\n placeholder=\"___.___.___-__\"\n {...register(\"cpf\", {\n onChange: (e) => {\n setValue(\"cpf\", formatCPF(e.target.value));\n },\n })}\n error={!!errors.cpf}\n errorMessage={errors.cpf?.message}\n />\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\ntype BillingFormFieldsProps = {\n readonly form: UseFormReturn<CardFormData>;\n readonly isInternational?: boolean;\n};\n\nexport function BillingFormFields({ form, isInternational = false }: BillingFormFieldsProps) {\n const translate = useTranslations();\n const {\n register,\n setValue,\n formState: { errors },\n } = form;\n\n const { mutateAsync: lookupCep } = useViaCep();\n\n const handleCepChange = (rawValue: string) => {\n if (isInternational) {\n setValue(\"cep\", rawValue);\n return;\n }\n const masked = formatPostalCode(rawValue);\n setValue(\"cep\", masked);\n\n const digits = rawValue.replace(/\\D/g, \"\");\n if (digits.length === 8) {\n lookupCep(digits)\n .then((data) => {\n setValue(\"street\", data.logradouro, { shouldValidate: true });\n setValue(\"neighborhood\", data.bairro, { shouldValidate: true });\n setValue(\"city\", data.localidade, { shouldValidate: true });\n setValue(\"state\", data.uf, { shouldValidate: true });\n })\n .catch(() => {\n // silently ignore — user can fill manually\n });\n }\n };\n\n return (\n <div className=\"flex flex-col gap-5\">\n <FormField\n label={translate('common.cards.form.fullName')}\n placeholder={translate('common.cards.form.typeHere')}\n {...register(\"fullName\")}\n error={!!errors.fullName}\n errorMessage={errors.fullName?.message}\n />\n\n <FormField\n label={isInternational ? translate('common.cards.form.postalCode') : translate('common.cards.form.cep')}\n placeholder={isInternational ? \"\" : \"_____-___\"}\n {...register(\"cep\", {\n onChange: (e) => handleCepChange(e.target.value),\n })}\n error={!!errors.cep}\n errorMessage={errors.cep?.message}\n />\n\n <div className=\"flex gap-4\">\n <div className=\"flex-[4]\">\n <FormField\n label={translate('common.cards.form.street')}\n placeholder=\"\"\n {...register(\"street\")}\n error={!!errors.street}\n errorMessage={errors.street?.message}\n />\n </div>\n <div className=\"flex-[1]\">\n <FormField\n label={translate('common.cards.form.streetNumber')}\n placeholder=\"\"\n {...register(\"streetNumber\")}\n error={!!errors.streetNumber}\n errorMessage={errors.streetNumber?.message}\n />\n </div>\n </div>\n\n <div className=\"flex gap-4\">\n <div className=\"flex-1\">\n <FormField\n label={translate('common.cards.form.city')}\n placeholder=\"\"\n {...register(\"city\")}\n error={!!errors.city}\n errorMessage={errors.city?.message}\n />\n </div>\n <div className=\"flex-1\">\n <FormField\n label={isInternational ? translate('common.cards.form.stateProvince') : translate('common.cards.form.state')}\n placeholder=\"\"\n {...register(\"state\")}\n error={!!errors.state}\n errorMessage={errors.state?.message}\n />\n </div>\n </div>\n\n <div className=\"flex gap-4\">\n {!isInternational && (\n <FormField\n label={translate('common.cards.form.neighborhood')}\n placeholder=\"\"\n {...register(\"neighborhood\")}\n error={!!errors.neighborhood}\n errorMessage={errors.neighborhood?.message}\n />\n )}\n <FormField\n label={translate('common.cards.form.complement')}\n optional\n placeholder=\"\"\n {...register(\"complement\")}\n error={!!errors.complement}\n errorMessage={errors.complement?.message}\n />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/modals/cards/CardFormFields.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { UseFormReturn } from \"react-hook-form\";\r\nimport { useViaCep } from \"../../../modules/accounts/hooks/useViaCep\";\r\nimport { FormField } from \"../../ui/form/FormField\";\r\nimport { SelectField } from \"../../ui/form/SelectField\";\r\nimport { COUNTRIES } from \"../../../utils/countries\";\r\nimport {\r\n formatCPF,\r\n formatCNPJ,\r\n formatPostalCode,\r\n} from \"../../../utils/format/masks\";\r\nimport z from \"zod\";\r\nimport {\r\n CardCvcElement,\r\n CardExpiryElement,\r\n CardNumberElement,\r\n} from \"@stripe/react-stripe-js\";\r\nimport { useTranslations } from \"next-intl\";\r\n\r\nconst stripeElementOptions = {\r\n style: {\r\n base: {\r\n fontSize: \"16px\",\r\n color: \"#030712\",\r\n fontFamily: \"Inter, sans-serif\",\r\n \"::placeholder\": {\r\n color: \"#9ca3af\",\r\n },\r\n },\r\n },\r\n};\r\n\r\nexport function buildCardFormSchema(isInternational: boolean) {\r\n const base = z.object({\r\n name: z.string().min(1, \"Nome é obrigatório\"),\r\n country: z.string().min(1, \"País é obrigatório\"),\r\n personType: z.enum([\"pf\", \"pj\"]).optional(),\r\n cpf: z.string().optional(),\r\n cnpj: z.string().optional(),\r\n fullName: z.string().min(1, \"Nome completo é obrigatório\"),\r\n cep: z.string().min(isInternational ? 1 : 9, isInternational ? \"Código postal é obrigatório\" : \"CEP é obrigatório\"),\r\n street: z.string().min(1, \"Endereço é obrigatório\"),\r\n streetNumber: isInternational ? z.string().optional() : z.string().min(1, \"Número é obrigatório\"),\r\n city: z.string().min(1, \"Cidade é obrigatória\"),\r\n state: z.string().min(1, \"UF é obrigatório\"),\r\n neighborhood: isInternational ? z.string().optional() : z.string().min(1, \"Bairro é obrigatório\"),\r\n complement: z.string().optional(),\r\n });\r\n if (isInternational) return base;\r\n return base.refine(\r\n (data) => {\r\n if (data.personType === \"pf\") return !!data.cpf && data.cpf.length >= 14;\r\n return !!data.cnpj && data.cnpj.length >= 18;\r\n },\r\n {\r\n message: \"Documento é obrigatório\",\r\n path: [\"cpf\"],\r\n },\r\n );\r\n}\r\n\r\nexport const cardFormSchema = buildCardFormSchema(false);\r\n\r\nexport type CardFormData = z.infer<typeof cardFormSchema>;\r\n\r\nexport type StripeElementsStatus = {\r\n cardNumber: boolean;\r\n cardExpiry: boolean;\r\n cardCvc: boolean;\r\n};\r\n\r\nexport const STEP1_FIELDS = [\r\n \"name\",\r\n \"country\",\r\n \"personType\",\r\n \"cpf\",\r\n \"cnpj\",\r\n] as const;\r\n\r\ntype CardFormFieldsProps = {\r\n readonly form: UseFormReturn<CardFormData>;\r\n readonly onStripeChange: (\r\n field: keyof StripeElementsStatus,\r\n complete: boolean,\r\n ) => void;\r\n readonly stripeErrors: {\r\n cardNumber?: string;\r\n cardExpiry?: string;\r\n cardCvc?: string;\r\n };\r\n readonly isInternational?: boolean;\r\n};\r\n\r\nexport function CardFormFields({\r\n form,\r\n onStripeChange,\r\n stripeErrors,\r\n isInternational = false,\r\n}: CardFormFieldsProps) {\r\n const translate = useTranslations();\r\n const {\r\n register,\r\n watch,\r\n setValue,\r\n formState: { errors },\r\n } = form;\r\n\r\n const personType = watch(\"personType\");\r\n\r\n return (\r\n <div className=\"flex flex-col gap-5\">\r\n <FormField\r\n label={translate('common.cards.form.nameOnCard')}\r\n placeholder={translate('common.cards.form.typeHere')}\r\n {...register(\"name\")}\r\n error={!!errors.name}\r\n errorMessage={errors.name?.message}\r\n />\r\n\r\n <div className=\"flex flex-col gap-1.5\">\r\n <label className=\"paragraph-xsmall-semibold text-zinc-600\">\r\n {translate('common.cards.form.cardNumber')}\r\n </label>\r\n <div className=\"h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400 relative\">\r\n <div className=\"w-full\">\r\n <CardNumberElement\r\n options={{ ...stripeElementOptions, showIcon: true }}\r\n onChange={(e: { complete: boolean }) =>\r\n onStripeChange(\"cardNumber\", e.complete)\r\n }\r\n />\r\n </div>\r\n </div>\r\n {stripeErrors.cardNumber && (\r\n <p className=\"paragraph-xsmall-semibold text-red-600\">\r\n {stripeErrors.cardNumber}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex gap-4\">\r\n <div className=\"flex-1 flex flex-col gap-1.5\">\r\n <label className=\"paragraph-xsmall-semibold text-zinc-600\">\r\n {translate('common.cards.form.cardExpiry')}\r\n </label>\r\n <div className=\"h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400\">\r\n <div className=\"w-full\">\r\n <CardExpiryElement\r\n options={stripeElementOptions}\r\n onChange={(e: { complete: boolean }) =>\r\n onStripeChange(\"cardExpiry\", e.complete)\r\n }\r\n />\r\n </div>\r\n </div>\r\n {stripeErrors.cardExpiry && (\r\n <p className=\"paragraph-xsmall-semibold text-red-600\">\r\n {stripeErrors.cardExpiry}\r\n </p>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex-1 flex flex-col gap-1.5\">\r\n <label className=\"paragraph-xsmall-semibold text-zinc-600\">{translate('common.cards.form.cardCvc')}</label>\r\n <div className=\"h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400\">\r\n <div className=\"w-full\">\r\n <CardCvcElement\r\n options={stripeElementOptions}\r\n onChange={(e: { complete: boolean }) =>\r\n onStripeChange(\"cardCvc\", e.complete)\r\n }\r\n />\r\n </div>\r\n </div>\r\n {stripeErrors.cardCvc && (\r\n <p className=\"paragraph-xsmall-semibold text-red-600\">\r\n {stripeErrors.cardCvc}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <SelectField\r\n label={translate('common.cards.form.country')}\r\n placeholder={translate('common.cards.form.select')}\r\n value={watch(\"country\")}\r\n onChange={(value) => setValue(\"country\", value as string)}\r\n options={COUNTRIES.map((c) => ({ value: c.iso, label: c.name }))}\r\n />\r\n\r\n {!isInternational && (\r\n <div className=\"flex gap-4\">\r\n <SelectField\r\n label={translate('common.cards.form.personType')}\r\n placeholder={translate('common.cards.form.select')}\r\n value={personType}\r\n onChange={(value) => {\r\n setValue(\"personType\", value as \"pf\" | \"pj\");\r\n setValue(\"cpf\", \"\");\r\n setValue(\"cnpj\", \"\");\r\n }}\r\n options={[\r\n { value: \"pf\", label: translate('common.cards.form.personTypePf') },\r\n { value: \"pj\", label: translate('common.cards.form.personTypePj') },\r\n ]}\r\n containerClassName=\"flex-1\"\r\n />\r\n <div className=\"flex-1\">\r\n {personType === \"pj\" ? (\r\n <FormField\r\n label={translate('common.cards.form.cnpj')}\r\n placeholder=\"__.___.___/____-__\"\r\n {...register(\"cnpj\", {\r\n onChange: (e) => {\r\n setValue(\"cnpj\", formatCNPJ(e.target.value));\r\n },\r\n })}\r\n error={!!errors.cpf}\r\n errorMessage={errors.cpf?.message}\r\n />\r\n ) : (\r\n <FormField\r\n label={translate('common.cards.form.cpf')}\r\n placeholder=\"___.___.___-__\"\r\n {...register(\"cpf\", {\r\n onChange: (e) => {\r\n setValue(\"cpf\", formatCPF(e.target.value));\r\n },\r\n })}\r\n error={!!errors.cpf}\r\n errorMessage={errors.cpf?.message}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\ntype BillingFormFieldsProps = {\r\n readonly form: UseFormReturn<CardFormData>;\r\n readonly isInternational?: boolean;\r\n};\r\n\r\nexport function BillingFormFields({ form, isInternational = false }: BillingFormFieldsProps) {\r\n const translate = useTranslations();\r\n const {\r\n register,\r\n setValue,\r\n formState: { errors },\r\n } = form;\r\n\r\n const { mutateAsync: lookupCep } = useViaCep();\r\n\r\n const handleCepChange = (rawValue: string) => {\r\n if (isInternational) {\r\n setValue(\"cep\", rawValue);\r\n return;\r\n }\r\n const masked = formatPostalCode(rawValue);\r\n setValue(\"cep\", masked);\r\n\r\n const digits = rawValue.replace(/\\D/g, \"\");\r\n if (digits.length === 8) {\r\n lookupCep(digits)\r\n .then((data) => {\r\n setValue(\"street\", data.logradouro, { shouldValidate: true });\r\n setValue(\"neighborhood\", data.bairro, { shouldValidate: true });\r\n setValue(\"city\", data.localidade, { shouldValidate: true });\r\n setValue(\"state\", data.uf, { shouldValidate: true });\r\n })\r\n .catch(() => {\r\n // silently ignore — user can fill manually\r\n });\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"flex flex-col gap-5\">\r\n <FormField\r\n label={translate('common.cards.form.fullName')}\r\n placeholder={translate('common.cards.form.typeHere')}\r\n {...register(\"fullName\")}\r\n error={!!errors.fullName}\r\n errorMessage={errors.fullName?.message}\r\n />\r\n\r\n <FormField\r\n label={isInternational ? translate('common.cards.form.postalCode') : translate('common.cards.form.cep')}\r\n placeholder={isInternational ? \"\" : \"_____-___\"}\r\n {...register(\"cep\", {\r\n onChange: (e) => handleCepChange(e.target.value),\r\n })}\r\n error={!!errors.cep}\r\n errorMessage={errors.cep?.message}\r\n />\r\n\r\n <div className=\"flex gap-4\">\r\n <div className=\"flex-[4]\">\r\n <FormField\r\n label={translate('common.cards.form.street')}\r\n placeholder=\"\"\r\n {...register(\"street\")}\r\n error={!!errors.street}\r\n errorMessage={errors.street?.message}\r\n />\r\n </div>\r\n <div className=\"flex-[1]\">\r\n <FormField\r\n label={translate('common.cards.form.streetNumber')}\r\n placeholder=\"\"\r\n {...register(\"streetNumber\")}\r\n error={!!errors.streetNumber}\r\n errorMessage={errors.streetNumber?.message}\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex gap-4\">\r\n <div className=\"flex-1\">\r\n <FormField\r\n label={translate('common.cards.form.city')}\r\n placeholder=\"\"\r\n {...register(\"city\")}\r\n error={!!errors.city}\r\n errorMessage={errors.city?.message}\r\n />\r\n </div>\r\n <div className=\"flex-1\">\r\n <FormField\r\n label={isInternational ? translate('common.cards.form.stateProvince') : translate('common.cards.form.state')}\r\n placeholder=\"\"\r\n {...register(\"state\")}\r\n error={!!errors.state}\r\n errorMessage={errors.state?.message}\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex gap-4\">\r\n {!isInternational && (\r\n <FormField\r\n label={translate('common.cards.form.neighborhood')}\r\n placeholder=\"\"\r\n {...register(\"neighborhood\")}\r\n error={!!errors.neighborhood}\r\n errorMessage={errors.neighborhood?.message}\r\n />\r\n )}\r\n <FormField\r\n label={translate('common.cards.form.complement')}\r\n optional\r\n placeholder=\"\"\r\n {...register(\"complement\")}\r\n error={!!errors.complement}\r\n errorMessage={errors.complement?.message}\r\n />\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/modals/cards/DeleteCardModal.tsx"],"sourcesContent":["'use client';\n\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n} from '../../ui/overlay/Dialog';\nimport { Button } from '../../ui/buttons/Button';\nimport { Separator } from '../../ui/data-display/Separator';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { FormField } from '../../ui/form/FormField';\nimport { IconTrash } from '@tabler/icons-react';\nimport { toast } from 'sonner';\nimport { useModalManager } from '../../../store/useModalManager';\nimport { useDeleteConfirmation } from '../../../modules/cards/hooks/delete-confirmation.hook';\nimport { useDeleteCard } from '../../../modules/cards/hooks/delete-card.hook';\nimport { useCards } from '../../../modules/cards/hooks/cards.hook';\nimport { useTranslations } from 'next-intl';\n\nexport function DeleteCardModal() {\n const translate = useTranslations();\n const { activeModal, modalData, closeModal } = useModalManager();\n const { form, isValidConfirmation, resetConfirmation } = useDeleteConfirmation({\n confirmWord: translate('common.cards.delete.confirmPlaceholder'),\n });\n const deleteCard = useDeleteCard();\n const { data: cardsData } = useCards();\n\n const isOpen = activeModal === 'deleteCardModal';\n const cardId = modalData.cardId as string | undefined;\n const onSuccess = modalData.onSuccess as (() => void) | undefined;\n\n const card = cardsData?.data?.find((c) => c.id.toString() === cardId);\n const cardLastDigits = (card?.number ?? '').replaceAll(/\\D/g, '').slice(-4);\n\n const handleClose = () => {\n resetConfirmation();\n closeModal();\n };\n\n const onSubmit = async () => {\n if (!cardId) return;\n\n try {\n await deleteCard.mutateAsync(cardId);\n } catch (error) {\n toast.custom(\n (t) => (\n <Toast\n toastId={t}\n variant=\"error\"\n message={\n error instanceof Error\n ? error.message\n : translate('common.cards.delete.errorToast')\n }\n />\n ),\n { duration: 5000 },\n );\n return;\n }\n\n onSuccess?.();\n resetConfirmation();\n closeModal();\n\n toast.custom(\n (t) => (\n <Toast\n variant=\"success\"\n message={translate('common.cards.delete.successToast', { digits: cardLastDigits })}\n toastId={t}\n />\n ),\n { duration: 5000 },\n );\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && handleClose()}>\n <DialogContent className=\"flex flex-col p-0! gap-0! max-w-[calc(100%-2rem)]! w-full sm:max-w-[400px]! lg:max-w-[410px]! rounded-lg border\">\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col\">\n <DialogHeader className=\"gap-4 text-left p-4 lg:p-5 pb-0 lg:pb-0\">\n <div className=\"flex items-center justify-center w-fit bg-red-50 rounded-lg p-2.5\">\n <IconTrash size={20} className=\"text-red-500\" />\n </div>\n <div className=\"flex flex-col gap-2\">\n <DialogTitle className=\"paragraph-medium-semibold text-zinc-950\">\n {translate('common.cards.delete.title')}\n </DialogTitle>\n <DialogDescription className=\"paragraph-small-regular text-zinc-600\">\n {translate('common.cards.delete.description')}{' '}\n <span className=\"font-semibold text-zinc-950\">\n •••• {cardLastDigits}\n </span>\n ?\n </DialogDescription>\n </div>\n </DialogHeader>\n\n <div className=\"px-4 lg:px-5 py-5\">\n <FormField\n label={translate('common.cards.delete.confirmLabel')}\n required\n placeholder={translate('common.cards.delete.confirmPlaceholder')}\n {...form.register('confirmText')}\n />\n </div>\n <Separator />\n <div className=\"flex flex-row items-center gap-2 p-4 lg:p-5\">\n <Button\n type=\"submit\"\n disabled={!isValidConfirmation}\n loading={form.formState.isSubmitting}\n className=\"h-10!\"\n >\n {form.formState.isSubmitting ? translate('common.cards.delete.deleting') : translate('common.actions.delete')}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"h-10!\"\n onClick={handleClose}\n disabled={form.formState.isSubmitting}\n >\n {translate('common.actions.cancel')}\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":";AAkDU,cA6CM,YA7CN;AAhDV;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC,SAAS,6BAA6B;AACtC,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAEzB,SAAS,kBAAkB;AAChC,QAAM,YAAY,gBAAgB;AAClC,QAAM,EAAE,aAAa,WAAW,WAAW,IAAI,gBAAgB;AAC/D,QAAM,EAAE,MAAM,qBAAqB,kBAAkB,IAAI,sBAAsB;AAAA,IAC7E,aAAa,UAAU,wCAAwC;AAAA,EACjE,CAAC;AACD,QAAM,aAAa,cAAc;AACjC,QAAM,EAAE,MAAM,UAAU,IAAI,SAAS;AAErC,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,UAAU;AACzB,QAAM,YAAY,UAAU;AAE5B,QAAM,OAAO,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,GAAG,SAAS,MAAM,MAAM;AACpE,QAAM,kBAAkB,MAAM,UAAU,IAAI,WAAW,OAAO,EAAE,EAAE,MAAM,EAAE;AAE1E,QAAM,cAAc,MAAM;AACxB,sBAAkB;AAClB,eAAW;AAAA,EACb;AAEA,QAAM,WAAW,YAAY;AAC3B,QAAI,CAAC,OAAQ;AAEb,QAAI;AACF,YAAM,WAAW,YAAY,MAAM;AAAA,IACrC,SAAS,OAAO;AACd,YAAM;AAAA,QACJ,CAAC,MACC;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,SAAQ;AAAA,YACR,SACE,iBAAiB,QACb,MAAM,UACN,UAAU,gCAAgC;AAAA;AAAA,QAElD;AAAA,QAEF,EAAE,UAAU,IAAK;AAAA,MACnB;AACA;AAAA,IACF;AAEA,gBAAY;AACZ,sBAAkB;AAClB,eAAW;AAEX,UAAM;AAAA,MACJ,CAAC,MACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,SAAS,UAAU,oCAAoC,EAAE,QAAQ,eAAe,CAAC;AAAA,UACjF,SAAS;AAAA;AAAA,MACX;AAAA,MAEF,EAAE,UAAU,IAAK;AAAA,IACnB;AAAA,EACF;AAEA,SACE,oBAAC,UAAO,MAAM,QAAQ,cAAc,CAAC,SAAS,CAAC,QAAQ,YAAY,GACjE,8BAAC,iBAAc,WAAU,mHACvB,+BAAC,UAAK,UAAU,KAAK,aAAa,QAAQ,GAAG,WAAU,iBACrD;AAAA,yBAAC,gBAAa,WAAU,2CACtB;AAAA,0BAAC,SAAI,WAAU,qEACb,8BAAC,aAAU,MAAM,IAAI,WAAU,gBAAe,GAChD;AAAA,MACA,qBAAC,SAAI,WAAU,uBACb;AAAA,4BAAC,eAAY,WAAU,2CACpB,oBAAU,2BAA2B,GACxC;AAAA,QACA,qBAAC,qBAAkB,WAAU,yCAC1B;AAAA,oBAAU,iCAAiC;AAAA,UAAG;AAAA,UAC/C,qBAAC,UAAK,WAAU,+BAA8B;AAAA;AAAA,YACtC;AAAA,aACR;AAAA,UAAO;AAAA,WAET;AAAA,SACF;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,qBACb;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,UAAU,kCAAkC;AAAA,QACnD,UAAQ;AAAA,QACR,aAAa,UAAU,wCAAwC;AAAA,QAC9D,GAAG,KAAK,SAAS,aAAa;AAAA;AAAA,IACjC,GACF;AAAA,IACA,oBAAC,aAAU;AAAA,IACX,qBAAC,SAAI,WAAU,+CACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU,CAAC;AAAA,UACX,SAAS,KAAK,UAAU;AAAA,UACxB,WAAU;AAAA,UAET,eAAK,UAAU,eAAe,UAAU,8BAA8B,IAAI,UAAU,uBAAuB;AAAA;AAAA,MAC9G;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,WAAU;AAAA,UACV,SAAS;AAAA,UACT,UAAU,KAAK,UAAU;AAAA,UAExB,oBAAU,uBAAuB;AAAA;AAAA,MACpC;AAAA,OACF;AAAA,KACF,GACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/modals/cards/DeleteCardModal.tsx"],"sourcesContent":["'use client';\r\n\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogDescription,\r\n} from '../../ui/overlay/Dialog';\r\nimport { Button } from '../../ui/buttons/Button';\r\nimport { Separator } from '../../ui/data-display/Separator';\r\nimport { Toast } from '../../ui/feedback/Toast';\r\nimport { FormField } from '../../ui/form/FormField';\r\nimport { IconTrash } from '@tabler/icons-react';\r\nimport { toast } from 'sonner';\r\nimport { useModalManager } from '../../../store/useModalManager';\r\nimport { useDeleteConfirmation } from '../../../modules/cards/hooks/delete-confirmation.hook';\r\nimport { useDeleteCard } from '../../../modules/cards/hooks/delete-card.hook';\r\nimport { useCards } from '../../../modules/cards/hooks/cards.hook';\r\nimport { useTranslations } from 'next-intl';\r\n\r\nexport function DeleteCardModal() {\r\n const translate = useTranslations();\r\n const { activeModal, modalData, closeModal } = useModalManager();\r\n const { form, isValidConfirmation, resetConfirmation } = useDeleteConfirmation({\r\n confirmWord: translate('common.cards.delete.confirmPlaceholder'),\r\n });\r\n const deleteCard = useDeleteCard();\r\n const { data: cardsData } = useCards();\r\n\r\n const isOpen = activeModal === 'deleteCardModal';\r\n const cardId = modalData.cardId as string | undefined;\r\n const onSuccess = modalData.onSuccess as (() => void) | undefined;\r\n\r\n const card = cardsData?.data?.find((c) => c.id.toString() === cardId);\r\n const cardLastDigits = (card?.number ?? '').replaceAll(/\\D/g, '').slice(-4);\r\n\r\n const handleClose = () => {\r\n resetConfirmation();\r\n closeModal();\r\n };\r\n\r\n const onSubmit = async () => {\r\n if (!cardId) return;\r\n\r\n try {\r\n await deleteCard.mutateAsync(cardId);\r\n } catch (error) {\r\n toast.custom(\r\n (t) => (\r\n <Toast\r\n toastId={t}\r\n variant=\"error\"\r\n message={\r\n error instanceof Error\r\n ? error.message\r\n : translate('common.cards.delete.errorToast')\r\n }\r\n />\r\n ),\r\n { duration: 5000 },\r\n );\r\n return;\r\n }\r\n\r\n onSuccess?.();\r\n resetConfirmation();\r\n closeModal();\r\n\r\n toast.custom(\r\n (t) => (\r\n <Toast\r\n variant=\"success\"\r\n message={translate('common.cards.delete.successToast', { digits: cardLastDigits })}\r\n toastId={t}\r\n />\r\n ),\r\n { duration: 5000 },\r\n );\r\n };\r\n\r\n return (\r\n <Dialog open={isOpen} onOpenChange={(open) => !open && handleClose()}>\r\n <DialogContent className=\"flex flex-col p-0! gap-0! max-w-[calc(100%-2rem)]! w-full sm:max-w-[400px]! lg:max-w-[410px]! rounded-lg border\">\r\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col\">\r\n <DialogHeader className=\"gap-4 text-left p-4 lg:p-5 pb-0 lg:pb-0\">\r\n <div className=\"flex items-center justify-center w-fit bg-red-50 rounded-lg p-2.5\">\r\n <IconTrash size={20} className=\"text-red-500\" />\r\n </div>\r\n <div className=\"flex flex-col gap-2\">\r\n <DialogTitle className=\"paragraph-medium-semibold text-zinc-950\">\r\n {translate('common.cards.delete.title')}\r\n </DialogTitle>\r\n <DialogDescription className=\"paragraph-small-regular text-zinc-600\">\r\n {translate('common.cards.delete.description')}{' '}\r\n <span className=\"font-semibold text-zinc-950\">\r\n •••• {cardLastDigits}\r\n </span>\r\n ?\r\n </DialogDescription>\r\n </div>\r\n </DialogHeader>\r\n\r\n <div className=\"px-4 lg:px-5 py-5\">\r\n <FormField\r\n label={translate('common.cards.delete.confirmLabel')}\r\n required\r\n placeholder={translate('common.cards.delete.confirmPlaceholder')}\r\n {...form.register('confirmText')}\r\n />\r\n </div>\r\n <Separator />\r\n <div className=\"flex flex-row items-center gap-2 p-4 lg:p-5\">\r\n <Button\r\n type=\"submit\"\r\n disabled={!isValidConfirmation}\r\n loading={form.formState.isSubmitting}\r\n className=\"h-10!\"\r\n >\r\n {form.formState.isSubmitting ? translate('common.cards.delete.deleting') : translate('common.actions.delete')}\r\n </Button>\r\n <Button\r\n type=\"button\"\r\n variant=\"secondary\"\r\n className=\"h-10!\"\r\n onClick={handleClose}\r\n disabled={form.formState.isSubmitting}\r\n >\r\n {translate('common.actions.cancel')}\r\n </Button>\r\n </div>\r\n </form>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/CancelledSubscriptionBanner.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { IconAlertOctagon, IconX } from '@tabler/icons-react';\nimport { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';\nimport { getSubscriptionCancellationState } from '../../modules/subscriptions/utils/get-subscription-cancellation-state';\nimport { useTranslations } from 'next-intl';\n\ninterface CancelledSubscriptionBannerProps {\n onReactivate?: () => void;\n}\n\nexport function CancelledSubscriptionBanner({ onReactivate }: CancelledSubscriptionBannerProps) {\n const translate = useTranslations();\n const { data: { data: [subscription] = [] } = {} } = useActiveSubscription();\n const [visible, setVisible] = useState(true);\n const [animated, setAnimated] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setAnimated(true), 50);\n return () => clearTimeout(timer);\n }, []);\n\n const dismiss = useCallback(() => setVisible(false), []);\n\n if (!visible) return null;\n if (subscription?.type === 'free' || subscription?.type === 'trial') return null;\n\n // Mesma fonte da verdade do SubscriptionBanner: páginas fora do ar quando a\n // assinatura está inativa (ex.: baixa por falha de pagamento) OU o cancelamento\n // explícito já passou do período (com grace, no caso de client).\n if (getSubscriptionCancellationState(subscription) !== 'cancelled') return null;\n\n return (\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\n <div\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-red-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\n >\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\n <IconAlertOctagon size={16} className=\"text-white shrink-0\" />\n <span className=\"paragraph-xsmall-semibold text-white\">\n {translate('common.navigation.banners.cancelled.message')}\n </span>\n </div>\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\n <button\n type=\"button\"\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\n onClick={onReactivate}\n >\n <span className=\"paragraph-xsmall-semibold text-white underline\">\n {translate('common.navigation.banners.cancelled.choosePlan')}\n </span>\n </button>\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\n <IconX size={18} className=\"text-red-200\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAsCQ,SACE,KADF;AApCR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,kBAAkB,aAAa;AACxC,SAAS,6BAA6B;AACtC,SAAS,wCAAwC;AACjD,SAAS,uBAAuB;AAMzB,SAAS,4BAA4B,EAAE,aAAa,GAAqC;AAC9F,QAAM,YAAY,gBAAgB;AAClC,QAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,sBAAsB;AAC3E,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,cAAc,SAAS,UAAU,cAAc,SAAS,QAAS,QAAO;AAK5E,MAAI,iCAAiC,YAAY,MAAM,YAAa,QAAO;AAE3E,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,8NAA8N,WAAW,mCAAmC,mBAAmB;AAAA,MAE1S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,oBAAiB,MAAM,IAAI,WAAU,uBAAsB;AAAA,UAC5D,oBAAC,UAAK,WAAU,wCACb,oBAAU,6CAA6C,GAC1D;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,kDACb,oBAAU,gDAAgD,GAC7D;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,gBAAe,GAC5C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/CancelledSubscriptionBanner.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { IconAlertOctagon, IconX } from '@tabler/icons-react';\r\nimport { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';\r\nimport { getSubscriptionCancellationState } from '../../modules/subscriptions/utils/get-subscription-cancellation-state';\r\nimport { useTranslations } from 'next-intl';\r\n\r\ninterface CancelledSubscriptionBannerProps {\r\n onReactivate?: () => void;\r\n}\r\n\r\nexport function CancelledSubscriptionBanner({ onReactivate }: CancelledSubscriptionBannerProps) {\r\n const translate = useTranslations();\r\n const { data: { data: [subscription] = [] } = {} } = useActiveSubscription();\r\n const [visible, setVisible] = useState(true);\r\n const [animated, setAnimated] = useState(false);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setAnimated(true), 50);\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n const dismiss = useCallback(() => setVisible(false), []);\r\n\r\n if (!visible) return null;\r\n if (subscription?.type === 'free' || subscription?.type === 'trial') return null;\r\n\r\n // Mesma fonte da verdade do SubscriptionBanner: páginas fora do ar quando a\r\n // assinatura está inativa (ex.: baixa por falha de pagamento) OU o cancelamento\r\n // explícito já passou do período (com grace, no caso de client).\r\n if (getSubscriptionCancellationState(subscription) !== 'cancelled') return null;\r\n\r\n return (\r\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\r\n <div\r\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-red-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\r\n >\r\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\r\n <IconAlertOctagon size={16} className=\"text-white shrink-0\" />\r\n <span className=\"paragraph-xsmall-semibold text-white\">\r\n {translate('common.navigation.banners.cancelled.message')}\r\n </span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\r\n <button\r\n type=\"button\"\r\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\r\n onClick={onReactivate}\r\n >\r\n <span className=\"paragraph-xsmall-semibold text-white underline\">\r\n {translate('common.navigation.banners.cancelled.choosePlan')}\r\n </span>\r\n </button>\r\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\r\n <IconX size={18} className=\"text-red-200\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"mappings":";AAsCQ,SACE,KADF;AApCR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,kBAAkB,aAAa;AACxC,SAAS,6BAA6B;AACtC,SAAS,wCAAwC;AACjD,SAAS,uBAAuB;AAMzB,SAAS,4BAA4B,EAAE,aAAa,GAAqC;AAC9F,QAAM,YAAY,gBAAgB;AAClC,QAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,sBAAsB;AAC3E,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,cAAc,SAAS,UAAU,cAAc,SAAS,QAAS,QAAO;AAK5E,MAAI,iCAAiC,YAAY,MAAM,YAAa,QAAO;AAE3E,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,8NAA8N,WAAW,mCAAmC,mBAAmB;AAAA,MAE1S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,oBAAiB,MAAM,IAAI,WAAU,uBAAsB;AAAA,UAC5D,oBAAC,UAAK,WAAU,wCACb,oBAAU,6CAA6C,GAC1D;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,kDACb,oBAAU,gDAAgD,GAC7D;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,gBAAe,GAC5C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/NavItemsContext.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useContext } from 'react';\nimport type { NavItemConfig } from './subcomponents/NavItems';\n\ninterface NavItemsContextValue {\n navItems: NavItemConfig[];\n setNavItems: (items: NavItemConfig[]) => void;\n mobileVariant: 'sheet' | 'tabs';\n}\n\nexport const NavItemsContext = createContext<NavItemsContextValue>({\n navItems: [],\n setNavItems: () => {},\n mobileVariant: 'sheet',\n});\n\nexport function useNavItemsContext(): NavItemsContextValue {\n return useContext(NavItemsContext);\n}\n"],"mappings":";AAEA,SAAS,eAAe,kBAAkB;AASnC,MAAM,kBAAkB,cAAoC;AAAA,EACjE,UAAU,CAAC;AAAA,EACX,aAAa,MAAM;AAAA,EAAC;AAAA,EACpB,eAAe;AACjB,CAAC;AAEM,SAAS,qBAA2C;AACzD,SAAO,WAAW,eAAe;AACnC;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/NavItemsContext.ts"],"sourcesContent":["'use client';\r\n\r\nimport { createContext, useContext } from 'react';\r\nimport type { NavItemConfig } from './subcomponents/NavItems';\r\n\r\ninterface NavItemsContextValue {\r\n navItems: NavItemConfig[];\r\n setNavItems: (items: NavItemConfig[]) => void;\r\n mobileVariant: 'sheet' | 'tabs';\r\n}\r\n\r\nexport const NavItemsContext = createContext<NavItemsContextValue>({\r\n navItems: [],\r\n setNavItems: () => {},\r\n mobileVariant: 'sheet',\r\n});\r\n\r\nexport function useNavItemsContext(): NavItemsContextValue {\r\n return useContext(NavItemsContext);\r\n}\r\n"],"mappings":";AAEA,SAAS,eAAe,kBAAkB;AASnC,MAAM,kBAAkB,cAAoC;AAAA,EACjE,UAAU,CAAC;AAAA,EACX,aAAa,MAAM;AAAA,EAAC;AAAA,EACpB,eAAe;AACjB,CAAC;AAEM,SAAS,qBAA2C;AACzD,SAAO,WAAW,eAAe;AACnC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/OverdueInvoiceBanner.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { IconAlertTriangle, IconX } from '@tabler/icons-react';\nimport { useTranslations } from 'next-intl';\n\ninterface OverdueInvoiceBannerProps {\n onDetails?: () => void;\n}\n\nexport function OverdueInvoiceBanner({ onDetails }: OverdueInvoiceBannerProps) {\n const translate = useTranslations();\n const [visible, setVisible] = useState(true);\n const [animated, setAnimated] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setAnimated(true), 50);\n return () => clearTimeout(timer);\n }, []);\n\n const dismiss = useCallback(() => setVisible(false), []);\n\n if (!visible) return null;\n\n return (\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\n <div\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-orange-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\n >\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\n <IconAlertTriangle size={16} className=\"text-white shrink-0\" />\n <span className=\"paragraph-xsmall-semibold text-white\">\n {translate('common.navigation.banners.overdue.message')}\n </span>\n </div>\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\n <button\n type=\"button\"\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\n onClick={onDetails}\n >\n <span className=\"paragraph-xsmall-semibold text-white underline\">{translate('common.navigation.banners.overdue.details')}</span>\n </button>\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\n <IconX size={18} className=\"text-orange-200\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AA6BQ,SACE,KADF;AA3BR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,mBAAmB,aAAa;AACzC,SAAS,uBAAuB;AAMzB,SAAS,qBAAqB,EAAE,UAAU,GAA8B;AAC7E,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iOAAiO,WAAW,mCAAmC,mBAAmB;AAAA,MAE7S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,qBAAkB,MAAM,IAAI,WAAU,uBAAsB;AAAA,UAC7D,oBAAC,UAAK,WAAU,wCACb,oBAAU,2CAA2C,GACxD;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,kDAAkD,oBAAU,2CAA2C,GAAE;AAAA;AAAA,UAC3H;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,mBAAkB,GAC/C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/OverdueInvoiceBanner.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { IconAlertTriangle, IconX } from '@tabler/icons-react';\r\nimport { useTranslations } from 'next-intl';\r\n\r\ninterface OverdueInvoiceBannerProps {\r\n onDetails?: () => void;\r\n}\r\n\r\nexport function OverdueInvoiceBanner({ onDetails }: OverdueInvoiceBannerProps) {\r\n const translate = useTranslations();\r\n const [visible, setVisible] = useState(true);\r\n const [animated, setAnimated] = useState(false);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setAnimated(true), 50);\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n const dismiss = useCallback(() => setVisible(false), []);\r\n\r\n if (!visible) return null;\r\n\r\n return (\r\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\r\n <div\r\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-orange-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\r\n >\r\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\r\n <IconAlertTriangle size={16} className=\"text-white shrink-0\" />\r\n <span className=\"paragraph-xsmall-semibold text-white\">\r\n {translate('common.navigation.banners.overdue.message')}\r\n </span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\r\n <button\r\n type=\"button\"\r\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\r\n onClick={onDetails}\r\n >\r\n <span className=\"paragraph-xsmall-semibold text-white underline\">{translate('common.navigation.banners.overdue.details')}</span>\r\n </button>\r\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\r\n <IconX size={18} className=\"text-orange-200\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"mappings":";AA6BQ,SACE,KADF;AA3BR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,mBAAmB,aAAa;AACzC,SAAS,uBAAuB;AAMzB,SAAS,qBAAqB,EAAE,UAAU,GAA8B;AAC7E,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iOAAiO,WAAW,mCAAmC,mBAAmB;AAAA,MAE7S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,qBAAkB,MAAM,IAAI,WAAU,uBAAsB;AAAA,UAC7D,oBAAC,UAAK,WAAU,wCACb,oBAAU,2CAA2C,GACxD;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,kDAAkD,oBAAU,2CAA2C,GAAE;AAAA;AAAA,UAC3H;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,mBAAkB,GAC/C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/PendingCancellationBanner.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { IconAlertTriangle, IconX } from '@tabler/icons-react';\nimport { formatShortDate } from '../../infra/utils/date';\nimport { useTranslations } from 'next-intl';\n\ninterface PendingCancellationBannerProps {\n limitDate?: Date | null;\n onReactivate?: () => void;\n}\n\nexport function PendingCancellationBanner({\n limitDate,\n onReactivate,\n}: PendingCancellationBannerProps) {\n const translate = useTranslations();\n const [visible, setVisible] = useState(true);\n const [animated, setAnimated] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setAnimated(true), 50);\n return () => clearTimeout(timer);\n }, []);\n\n const dismiss = useCallback(() => setVisible(false), []);\n\n if (!visible) return null;\n\n const formattedLimitDate = formatShortDate(limitDate);\n\n return (\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\n <div\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-yellow-400 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\n >\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\n <IconAlertTriangle size={16} className=\"text-zinc-950 shrink-0\" />\n <span className=\"paragraph-xsmall-semibold text-zinc-950\">\n {translate('common.navigation.banners.pending.message', { limitDate: formattedLimitDate ?? '' })}\n </span>\n </div>\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\n <button\n type=\"button\"\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\n onClick={onReactivate}\n >\n <span className=\"paragraph-xsmall-semibold text-zinc-950 underline\">\n {translate('common.navigation.banners.pending.reactivate')}\n </span>\n </button>\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\n <IconX size={18} className=\"text-zinc-700\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAoCQ,SACE,KADF;AAlCR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,mBAAmB,aAAa;AACzC,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAOzB,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,qBAAqB,gBAAgB,SAAS;AAEpD,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iOAAiO,WAAW,mCAAmC,mBAAmB;AAAA,MAE7S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,qBAAkB,MAAM,IAAI,WAAU,0BAAyB;AAAA,UAChE,oBAAC,UAAK,WAAU,2CACb,oBAAU,6CAA6C,EAAE,WAAW,sBAAsB,GAAG,CAAC,GACjG;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,qDACb,oBAAU,8CAA8C,GAC3D;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB,GAC7C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/PendingCancellationBanner.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { IconAlertTriangle, IconX } from '@tabler/icons-react';\r\nimport { formatShortDate } from '../../infra/utils/date';\r\nimport { useTranslations } from 'next-intl';\r\n\r\ninterface PendingCancellationBannerProps {\r\n limitDate?: Date | null;\r\n onReactivate?: () => void;\r\n}\r\n\r\nexport function PendingCancellationBanner({\r\n limitDate,\r\n onReactivate,\r\n}: PendingCancellationBannerProps) {\r\n const translate = useTranslations();\r\n const [visible, setVisible] = useState(true);\r\n const [animated, setAnimated] = useState(false);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setAnimated(true), 50);\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n const dismiss = useCallback(() => setVisible(false), []);\r\n\r\n if (!visible) return null;\r\n\r\n const formattedLimitDate = formatShortDate(limitDate);\r\n\r\n return (\r\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\r\n <div\r\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-yellow-400 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\r\n >\r\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\r\n <IconAlertTriangle size={16} className=\"text-zinc-950 shrink-0\" />\r\n <span className=\"paragraph-xsmall-semibold text-zinc-950\">\r\n {translate('common.navigation.banners.pending.message', { limitDate: formattedLimitDate ?? '' })}\r\n </span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\r\n <button\r\n type=\"button\"\r\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\r\n onClick={onReactivate}\r\n >\r\n <span className=\"paragraph-xsmall-semibold text-zinc-950 underline\">\r\n {translate('common.navigation.banners.pending.reactivate')}\r\n </span>\r\n </button>\r\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\r\n <IconX size={18} className=\"text-zinc-700\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"mappings":";AAoCQ,SACE,KADF;AAlCR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,mBAAmB,aAAa;AACzC,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAOzB,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,qBAAqB,gBAAgB,SAAS;AAEpD,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iOAAiO,WAAW,mCAAmC,mBAAmB;AAAA,MAE7S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,qBAAkB,MAAM,IAAI,WAAU,0BAAyB;AAAA,UAChE,oBAAC,UAAK,WAAU,2CACb,oBAAU,6CAA6C,EAAE,WAAW,sBAAsB,GAAG,CAAC,GACjG;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,qDACb,oBAAU,8CAA8C,GAC3D;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB,GAC7C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/ProjectSelectorPopover.tsx"],"sourcesContent":["'use client';\n\nimport { Dispatch, RefObject, SetStateAction, UIEvent, useCallback } from 'react';\nimport { useTranslations } from 'next-intl';\nimport {\n Button,\n Command,\n CommandEmpty,\n CommandInput,\n CommandItem,\n CommandList,\n Popover,\n PopoverContent,\n PopoverTrigger,\n UserAvatar,\n} from '../../index';\nimport { IconCheck, IconChevronDown, IconFolderOpen } from '@tabler/icons-react';\nimport type { Project } from '../../modules/projects/types';\n\nexport interface ProjectSelectorPopoverProps {\n open: boolean;\n setOpen: Dispatch<SetStateAction<boolean>>;\n titleRef?: RefObject<HTMLSpanElement | null>;\n projects: Project[];\n selectedProject: Project | null;\n isLoading?: boolean;\n isFetchingNextPage?: boolean;\n hasNextPage?: boolean;\n onLoadMore?: () => void | Promise<unknown>;\n onSelectProject: (project: Project) => void;\n onManageProjects?: () => void;\n search?: string;\n onSearchChange?: (value: string) => void;\n children?: React.ReactNode;\n}\n\nfunction ProjectItemSkeleton() {\n return (\n <div className=\"flex items-center justify-between px-2 py-2 gap-2\">\n <div className=\"flex items-center gap-2 flex-1\">\n <div className=\"skeleton size-9 rounded-lg shrink-0\" />\n <div className=\"skeleton h-4 w-36 rounded\" />\n </div>\n <div className=\"skeleton size-4 rounded-full shrink-0\" />\n </div>\n );\n}\n\nexport function ProjectSelectorPopover({\n open,\n setOpen,\n titleRef,\n projects,\n selectedProject,\n isLoading,\n isFetchingNextPage,\n hasNextPage,\n onLoadMore,\n onSelectProject,\n onManageProjects,\n search,\n onSearchChange,\n children,\n}: ProjectSelectorPopoverProps) {\n const translate = useTranslations();\n const handleListScroll = useCallback((event: UIEvent<HTMLDivElement>) => {\n if (!hasNextPage || isFetchingNextPage || !onLoadMore) return;\n\n const target = event.currentTarget;\n const distanceToBottom = target.scrollHeight - target.scrollTop - target.clientHeight;\n\n if (distanceToBottom <= 80) {\n onLoadMore();\n }\n }, [hasNextPage, isFetchingNextPage, onLoadMore]);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n {children ?? (\n <button className=\"cursor-pointer\">\n <IconChevronDown\n size={20}\n className={`transition-transform duration-200 ${open ? 'rotate-180 text-gray-950' : 'text-gray-400'}`}\n />\n </button>\n )}\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[296px] max-h-[380px] p-0 bg-white rounded-2xl shadow-md border border-gray-200\"\n align=\"start\"\n sideOffset={8}\n onInteractOutside={(event: Event) => {\n if (titleRef?.current?.contains(event.target as Node)) {\n event.preventDefault();\n }\n }}\n >\n <div className=\"flex flex-col p-3 gap-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"paragraph-small-semibold\">{translate('common.navigation.projectSelector.title')}</span>\n </div>\n <Command className=\"gap-2\" defaultValue=\" \" shouldFilter={!onSearchChange} value=\" \" onValueChange={() => {}}>\n <CommandInput placeholder={translate('common.navigation.projectSelector.searchPlaceholder')} value={search} onValueChange={onSearchChange} />\n <CommandList\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 max-h-[227px]\"\n onScroll={handleListScroll}\n >\n {isLoading ? (\n <>\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n </>\n ) : projects.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center gap-2 h-full text-gray-400 py-4\">\n <IconFolderOpen size={28} className=\"text-gray-300\" />\n <span className=\"paragraph-small-medium text-center text-gray-500\">\n {translate('common.navigation.projectSelector.emptyLine1')}\n <br />\n {translate('common.navigation.projectSelector.emptyLine2')}\n </span>\n </div>\n ) : (\n <>\n <CommandEmpty>{translate('common.navigation.projectSelector.noResults')}</CommandEmpty>\n {projects.map((project) => {\n const isSelected = selectedProject?.id === project.id;\n return (\n <CommandItem\n key={project.id}\n value={`${project.title}-${project.id}`}\n keywords={[project.title]}\n className={isSelected ? 'bg-gray-50 min-h-[39px]' : 'min-h-[39px]'}\n onSelect={() => onSelectProject(project)}\n >\n <div className=\"flex items-center justify-between w-full cursor-pointer\">\n <div className=\"flex items-center gap-2 w-full\">\n <UserAvatar\n photo={project.photo}\n name={project.title}\n size={36}\n />\n {project.title}\n </div>\n {isSelected && (\n <IconCheck className=\"size-4 text-gray-950\" />\n )}\n </div>\n </CommandItem>\n );\n })}\n {isFetchingNextPage && (\n <>\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n </>\n )}\n </>\n )}\n </CommandList>\n </Command>\n {onManageProjects && (\n <>\n <div className=\"border-t border-gray-200\" />\n <Button\n variant=\"ghost\"\n className=\"h-10! paragraph-small-medium text-gray-600 hover:text-gray-950 hover:bg-zinc-50 w-full justify-center\"\n onClick={onManageProjects}\n >\n {translate('common.navigation.projectSelector.manageProjects')}\n </Button>\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/ProjectSelectorPopover.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { Dispatch, RefObject, SetStateAction, UIEvent, useCallback } from 'react';\r\nimport { useTranslations } from 'next-intl';\r\nimport {\r\n Button,\r\n Command,\r\n CommandEmpty,\r\n CommandInput,\r\n CommandItem,\r\n CommandList,\r\n Popover,\r\n PopoverContent,\r\n PopoverTrigger,\r\n UserAvatar,\r\n} from '../../index';\r\nimport { IconCheck, IconChevronDown, IconFolderOpen } from '@tabler/icons-react';\r\nimport type { Project } from '../../modules/projects/types';\r\n\r\nexport interface ProjectSelectorPopoverProps {\r\n open: boolean;\r\n setOpen: Dispatch<SetStateAction<boolean>>;\r\n titleRef?: RefObject<HTMLSpanElement | null>;\r\n projects: Project[];\r\n selectedProject: Project | null;\r\n isLoading?: boolean;\r\n isFetchingNextPage?: boolean;\r\n hasNextPage?: boolean;\r\n onLoadMore?: () => void | Promise<unknown>;\r\n onSelectProject: (project: Project) => void;\r\n onManageProjects?: () => void;\r\n search?: string;\r\n onSearchChange?: (value: string) => void;\r\n children?: React.ReactNode;\r\n}\r\n\r\nfunction ProjectItemSkeleton() {\r\n return (\r\n <div className=\"flex items-center justify-between px-2 py-2 gap-2\">\r\n <div className=\"flex items-center gap-2 flex-1\">\r\n <div className=\"skeleton size-9 rounded-lg shrink-0\" />\r\n <div className=\"skeleton h-4 w-36 rounded\" />\r\n </div>\r\n <div className=\"skeleton size-4 rounded-full shrink-0\" />\r\n </div>\r\n );\r\n}\r\n\r\nexport function ProjectSelectorPopover({\r\n open,\r\n setOpen,\r\n titleRef,\r\n projects,\r\n selectedProject,\r\n isLoading,\r\n isFetchingNextPage,\r\n hasNextPage,\r\n onLoadMore,\r\n onSelectProject,\r\n onManageProjects,\r\n search,\r\n onSearchChange,\r\n children,\r\n}: ProjectSelectorPopoverProps) {\r\n const translate = useTranslations();\r\n const handleListScroll = useCallback((event: UIEvent<HTMLDivElement>) => {\r\n if (!hasNextPage || isFetchingNextPage || !onLoadMore) return;\r\n\r\n const target = event.currentTarget;\r\n const distanceToBottom = target.scrollHeight - target.scrollTop - target.clientHeight;\r\n\r\n if (distanceToBottom <= 80) {\r\n onLoadMore();\r\n }\r\n }, [hasNextPage, isFetchingNextPage, onLoadMore]);\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n {children ?? (\r\n <button className=\"cursor-pointer\">\r\n <IconChevronDown\r\n size={20}\r\n className={`transition-transform duration-200 ${open ? 'rotate-180 text-gray-950' : 'text-gray-400'}`}\r\n />\r\n </button>\r\n )}\r\n </PopoverTrigger>\r\n <PopoverContent\r\n className=\"w-[296px] max-h-[380px] p-0 bg-white rounded-2xl shadow-md border border-gray-200\"\r\n align=\"start\"\r\n sideOffset={8}\r\n onInteractOutside={(event: Event) => {\r\n if (titleRef?.current?.contains(event.target as Node)) {\r\n event.preventDefault();\r\n }\r\n }}\r\n >\r\n <div className=\"flex flex-col p-3 gap-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"paragraph-small-semibold\">{translate('common.navigation.projectSelector.title')}</span>\r\n </div>\r\n <Command className=\"gap-2\" defaultValue=\" \" shouldFilter={!onSearchChange} value=\" \" onValueChange={() => {}}>\r\n <CommandInput placeholder={translate('common.navigation.projectSelector.searchPlaceholder')} value={search} onValueChange={onSearchChange} />\r\n <CommandList\r\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 max-h-[227px]\"\r\n onScroll={handleListScroll}\r\n >\r\n {isLoading ? (\r\n <>\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n </>\r\n ) : projects.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center gap-2 h-full text-gray-400 py-4\">\r\n <IconFolderOpen size={28} className=\"text-gray-300\" />\r\n <span className=\"paragraph-small-medium text-center text-gray-500\">\r\n {translate('common.navigation.projectSelector.emptyLine1')}\r\n <br />\r\n {translate('common.navigation.projectSelector.emptyLine2')}\r\n </span>\r\n </div>\r\n ) : (\r\n <>\r\n <CommandEmpty>{translate('common.navigation.projectSelector.noResults')}</CommandEmpty>\r\n {projects.map((project) => {\r\n const isSelected = selectedProject?.id === project.id;\r\n return (\r\n <CommandItem\r\n key={project.id}\r\n value={`${project.title}-${project.id}`}\r\n keywords={[project.title]}\r\n className={isSelected ? 'bg-gray-50 min-h-[39px]' : 'min-h-[39px]'}\r\n onSelect={() => onSelectProject(project)}\r\n >\r\n <div className=\"flex items-center justify-between w-full cursor-pointer\">\r\n <div className=\"flex items-center gap-2 w-full\">\r\n <UserAvatar\r\n photo={project.photo}\r\n name={project.title}\r\n size={36}\r\n />\r\n {project.title}\r\n </div>\r\n {isSelected && (\r\n <IconCheck className=\"size-4 text-gray-950\" />\r\n )}\r\n </div>\r\n </CommandItem>\r\n );\r\n })}\r\n {isFetchingNextPage && (\r\n <>\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n </>\r\n )}\r\n </>\r\n )}\r\n </CommandList>\r\n </Command>\r\n {onManageProjects && (\r\n <>\r\n <div className=\"border-t border-gray-200\" />\r\n <Button\r\n variant=\"ghost\"\r\n className=\"h-10! paragraph-small-medium text-gray-600 hover:text-gray-950 hover:bg-zinc-50 w-full justify-center\"\r\n onClick={onManageProjects}\r\n >\r\n {translate('common.navigation.projectSelector.manageProjects')}\r\n </Button>\r\n </>\r\n )}\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/SubscriptionBanner.tsx"],"sourcesContent":["\"use client\";\n\nimport { useActiveSubscription } from \"../../modules/subscriptions/hooks/find-active-subscription.hook\";\nimport { useCharges } from \"../../modules/charges/hooks/charges.hook\";\nimport { SUBSCRIPTION_GRACE_PERIOD_DAYS } from \"../../modules/subscriptions/constants/subscription.constants\";\nimport { getSubscriptionExpiryDate } from \"../../modules/subscriptions/utils/get-subscription-expiry-date\";\nimport { getSubscriptionCancellationState } from \"../../modules/subscriptions/utils/get-subscription-cancellation-state\";\nimport { toCalendarDate, daysBetween } from \"../../infra/utils/date\";\nimport { OverdueInvoiceBanner } from \"./OverdueInvoiceBanner\";\nimport { UpcomingInvoiceBanner } from \"./UpcomingInvoiceBanner\";\nimport { CancelledSubscriptionBanner } from \"./CancelledSubscriptionBanner\";\nimport { PendingCancellationBanner } from \"./PendingCancellationBanner\";\nimport { TrialBanner } from \"./TrialBanner\";\n\nconst UPCOMING_WINDOW_DAYS = 7;\nconst PAYMENT_METHOD_BOLETO = 2;\n\ninterface SubscriptionBannerProps {\n onReactivate?: () => void;\n onDetails?: () => void;\n}\n\nexport function SubscriptionBanner({\n onReactivate,\n onDetails,\n}: SubscriptionBannerProps) {\n const { data: { data: [subscription] = [] } = {} } = useActiveSubscription();\n const { data: pendingChargesData, isLoading: isLoadingCharges } = useCharges({\n page: 1,\n limit: 1,\n status: [0],\n });\n\n if (!subscription?.date_due) return null;\n if (subscription.type === \"free\") return null;\n\n const dueDate = toCalendarDate(subscription.date_due);\n const today = toCalendarDate(new Date());\n if (!dueDate || !today) return null;\n\n const daysSinceDue = daysBetween(dueDate, today);\n const daysToDue = daysBetween(today, dueDate);\n const hasPendingCharge = !!pendingChargesData?.data?.[0];\n const isBoleto = subscription.payment_method === PAYMENT_METHOD_BOLETO;\n\n // Estado de cancelamento (fonte da verdade única, compartilhada com o\n // CancelledSubscriptionBanner). `active === false` tem prioridade e cai em\n // \"cancelled\" mesmo com date_due no futuro — é o caso da baixa por falha de\n // pagamento, onde date_due aponta pra uma fatura não paga.\n const expiryDate = getSubscriptionExpiryDate(subscription);\n const cancellationState = getSubscriptionCancellationState(subscription);\n\n // Trial: `date_due` guarda o fim do período de teste (ver auth.service).\n // Mostra a contagem regressiva enquanto o teste está vigente: `active` e não\n // vencido (`daysToDue >= 0`). NÃO usar `cancellationState` aqui — num trial o\n // `date_cancellation` é o agendamento padrão de não-renovação (o Stripe seta\n // = `date_due`), então cairia sempre em \"pending\" e o banner nunca apareceria.\n // Um trial encerrado de verdade vem com `active === false` (date_due placeholder).\n if (subscription.type === \"trial\") {\n if (!subscription.active || daysToDue < 0) return null;\n return <TrialBanner daysRemaining={daysToDue} onReactivate={onReactivate} />;\n }\n\n if (cancellationState === \"cancelled\") {\n return <CancelledSubscriptionBanner onReactivate={onReactivate} />;\n }\n\n if (cancellationState === \"pending\") {\n return (\n <PendingCancellationBanner\n limitDate={expiryDate}\n onReactivate={onReactivate}\n />\n );\n }\n\n if (subscription.type === \"whitelabel\") return null;\n\n if (daysSinceDue > 0 && daysSinceDue <= SUBSCRIPTION_GRACE_PERIOD_DAYS) {\n return <OverdueInvoiceBanner onDetails={onDetails} />;\n }\n\n if (\n isBoleto &&\n !isLoadingCharges &&\n hasPendingCharge &&\n daysToDue >= 0 &&\n daysToDue <= UPCOMING_WINDOW_DAYS\n ) {\n return <UpcomingInvoiceBanner dueDate={dueDate} onDetails={onDetails} />;\n }\n\n return null;\n}\n"],"mappings":";AA4DW;AA1DX,SAAS,6BAA6B;AACtC,SAAS,kBAAkB;AAC3B,SAAS,sCAAsC;AAC/C,SAAS,iCAAiC;AAC1C,SAAS,wCAAwC;AACjD,SAAS,gBAAgB,mBAAmB;AAC5C,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAC5C,SAAS,iCAAiC;AAC1C,SAAS,mBAAmB;AAE5B,MAAM,uBAAuB;AAC7B,MAAM,wBAAwB;AAOvB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,sBAAsB;AAC3E,QAAM,EAAE,MAAM,oBAAoB,WAAW,iBAAiB,IAAI,WAAW;AAAA,IAC3E,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ,CAAC,CAAC;AAAA,EACZ,CAAC;AAED,MAAI,CAAC,cAAc,SAAU,QAAO;AACpC,MAAI,aAAa,SAAS,OAAQ,QAAO;AAEzC,QAAM,UAAU,eAAe,aAAa,QAAQ;AACpD,QAAM,QAAQ,eAAe,oBAAI,KAAK,CAAC;AACvC,MAAI,CAAC,WAAW,CAAC,MAAO,QAAO;AAE/B,QAAM,eAAe,YAAY,SAAS,KAAK;AAC/C,QAAM,YAAY,YAAY,OAAO,OAAO;AAC5C,QAAM,mBAAmB,CAAC,CAAC,oBAAoB,OAAO,CAAC;AACvD,QAAM,WAAW,aAAa,mBAAmB;AAMjD,QAAM,aAAa,0BAA0B,YAAY;AACzD,QAAM,oBAAoB,iCAAiC,YAAY;AAQvE,MAAI,aAAa,SAAS,SAAS;AACjC,QAAI,CAAC,aAAa,UAAU,YAAY,EAAG,QAAO;AAClD,WAAO,oBAAC,eAAY,eAAe,WAAW,cAA4B;AAAA,EAC5E;AAEA,MAAI,sBAAsB,aAAa;AACrC,WAAO,oBAAC,+BAA4B,cAA4B;AAAA,EAClE;AAEA,MAAI,sBAAsB,WAAW;AACnC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,QACX;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,aAAa,SAAS,aAAc,QAAO;AAE/C,MAAI,eAAe,KAAK,gBAAgB,gCAAgC;AACtE,WAAO,oBAAC,wBAAqB,WAAsB;AAAA,EACrD;AAEA,MACE,YACA,CAAC,oBACD,oBACA,aAAa,KACb,aAAa,sBACb;AACA,WAAO,oBAAC,yBAAsB,SAAkB,WAAsB;AAAA,EACxE;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/SubscriptionBanner.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { useActiveSubscription } from \"../../modules/subscriptions/hooks/find-active-subscription.hook\";\r\nimport { useCharges } from \"../../modules/charges/hooks/charges.hook\";\r\nimport { SUBSCRIPTION_GRACE_PERIOD_DAYS } from \"../../modules/subscriptions/constants/subscription.constants\";\r\nimport { getSubscriptionExpiryDate } from \"../../modules/subscriptions/utils/get-subscription-expiry-date\";\r\nimport { getSubscriptionCancellationState } from \"../../modules/subscriptions/utils/get-subscription-cancellation-state\";\r\nimport { toCalendarDate, daysBetween } from \"../../infra/utils/date\";\r\nimport { OverdueInvoiceBanner } from \"./OverdueInvoiceBanner\";\r\nimport { UpcomingInvoiceBanner } from \"./UpcomingInvoiceBanner\";\r\nimport { CancelledSubscriptionBanner } from \"./CancelledSubscriptionBanner\";\r\nimport { PendingCancellationBanner } from \"./PendingCancellationBanner\";\r\nimport { TrialBanner } from \"./TrialBanner\";\r\n\r\nconst UPCOMING_WINDOW_DAYS = 7;\r\nconst PAYMENT_METHOD_BOLETO = 2;\r\n\r\ninterface SubscriptionBannerProps {\r\n onReactivate?: () => void;\r\n onDetails?: () => void;\r\n}\r\n\r\nexport function SubscriptionBanner({\r\n onReactivate,\r\n onDetails,\r\n}: SubscriptionBannerProps) {\r\n const { data: { data: [subscription] = [] } = {} } = useActiveSubscription();\r\n const { data: pendingChargesData, isLoading: isLoadingCharges } = useCharges({\r\n page: 1,\r\n limit: 1,\r\n status: [0],\r\n });\r\n\r\n if (!subscription?.date_due) return null;\r\n if (subscription.type === \"free\") return null;\r\n\r\n const dueDate = toCalendarDate(subscription.date_due);\r\n const today = toCalendarDate(new Date());\r\n if (!dueDate || !today) return null;\r\n\r\n const daysSinceDue = daysBetween(dueDate, today);\r\n const daysToDue = daysBetween(today, dueDate);\r\n const hasPendingCharge = !!pendingChargesData?.data?.[0];\r\n const isBoleto = subscription.payment_method === PAYMENT_METHOD_BOLETO;\r\n\r\n // Estado de cancelamento (fonte da verdade única, compartilhada com o\r\n // CancelledSubscriptionBanner). `active === false` tem prioridade e cai em\r\n // \"cancelled\" mesmo com date_due no futuro — é o caso da baixa por falha de\r\n // pagamento, onde date_due aponta pra uma fatura não paga.\r\n const expiryDate = getSubscriptionExpiryDate(subscription);\r\n const cancellationState = getSubscriptionCancellationState(subscription);\r\n\r\n // Trial: `date_due` guarda o fim do período de teste (ver auth.service).\r\n // Mostra a contagem regressiva enquanto o teste está vigente: `active` e não\r\n // vencido (`daysToDue >= 0`). NÃO usar `cancellationState` aqui — num trial o\r\n // `date_cancellation` é o agendamento padrão de não-renovação (o Stripe seta\r\n // = `date_due`), então cairia sempre em \"pending\" e o banner nunca apareceria.\r\n // Um trial encerrado de verdade vem com `active === false` (date_due placeholder).\r\n if (subscription.type === \"trial\") {\r\n if (!subscription.active || daysToDue < 0) return null;\r\n return <TrialBanner daysRemaining={daysToDue} onReactivate={onReactivate} />;\r\n }\r\n\r\n if (cancellationState === \"cancelled\") {\r\n return <CancelledSubscriptionBanner onReactivate={onReactivate} />;\r\n }\r\n\r\n if (cancellationState === \"pending\") {\r\n return (\r\n <PendingCancellationBanner\r\n limitDate={expiryDate}\r\n onReactivate={onReactivate}\r\n />\r\n );\r\n }\r\n\r\n if (subscription.type === \"whitelabel\") return null;\r\n\r\n if (daysSinceDue > 0 && daysSinceDue <= SUBSCRIPTION_GRACE_PERIOD_DAYS) {\r\n return <OverdueInvoiceBanner onDetails={onDetails} />;\r\n }\r\n\r\n if (\r\n isBoleto &&\r\n !isLoadingCharges &&\r\n hasPendingCharge &&\r\n daysToDue >= 0 &&\r\n daysToDue <= UPCOMING_WINDOW_DAYS\r\n ) {\r\n return <UpcomingInvoiceBanner dueDate={dueDate} onDetails={onDetails} />;\r\n }\r\n\r\n return null;\r\n}\r\n"],"mappings":";AA4DW;AA1DX,SAAS,6BAA6B;AACtC,SAAS,kBAAkB;AAC3B,SAAS,sCAAsC;AAC/C,SAAS,iCAAiC;AAC1C,SAAS,wCAAwC;AACjD,SAAS,gBAAgB,mBAAmB;AAC5C,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAC5C,SAAS,iCAAiC;AAC1C,SAAS,mBAAmB;AAE5B,MAAM,uBAAuB;AAC7B,MAAM,wBAAwB;AAOvB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,sBAAsB;AAC3E,QAAM,EAAE,MAAM,oBAAoB,WAAW,iBAAiB,IAAI,WAAW;AAAA,IAC3E,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ,CAAC,CAAC;AAAA,EACZ,CAAC;AAED,MAAI,CAAC,cAAc,SAAU,QAAO;AACpC,MAAI,aAAa,SAAS,OAAQ,QAAO;AAEzC,QAAM,UAAU,eAAe,aAAa,QAAQ;AACpD,QAAM,QAAQ,eAAe,oBAAI,KAAK,CAAC;AACvC,MAAI,CAAC,WAAW,CAAC,MAAO,QAAO;AAE/B,QAAM,eAAe,YAAY,SAAS,KAAK;AAC/C,QAAM,YAAY,YAAY,OAAO,OAAO;AAC5C,QAAM,mBAAmB,CAAC,CAAC,oBAAoB,OAAO,CAAC;AACvD,QAAM,WAAW,aAAa,mBAAmB;AAMjD,QAAM,aAAa,0BAA0B,YAAY;AACzD,QAAM,oBAAoB,iCAAiC,YAAY;AAQvE,MAAI,aAAa,SAAS,SAAS;AACjC,QAAI,CAAC,aAAa,UAAU,YAAY,EAAG,QAAO;AAClD,WAAO,oBAAC,eAAY,eAAe,WAAW,cAA4B;AAAA,EAC5E;AAEA,MAAI,sBAAsB,aAAa;AACrC,WAAO,oBAAC,+BAA4B,cAA4B;AAAA,EAClE;AAEA,MAAI,sBAAsB,WAAW;AACnC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,QACX;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,aAAa,SAAS,aAAc,QAAO;AAE/C,MAAI,eAAe,KAAK,gBAAgB,gCAAgC;AACtE,WAAO,oBAAC,wBAAqB,WAAsB;AAAA,EACrD;AAEA,MACE,YACA,CAAC,oBACD,oBACA,aAAa,KACb,aAAa,sBACb;AACA,WAAO,oBAAC,yBAAsB,SAAkB,WAAsB;AAAA,EACxE;AAEA,SAAO;AACT;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/TrialBanner.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { IconClock, IconX } from '@tabler/icons-react';\nimport { useTranslations } from 'next-intl';\n\ninterface TrialBannerProps {\n daysRemaining: number;\n onReactivate?: () => void;\n}\n\nexport function TrialBanner({ daysRemaining, onReactivate }: TrialBannerProps) {\n const translate = useTranslations();\n const [visible, setVisible] = useState(true);\n const [animated, setAnimated] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setAnimated(true), 50);\n return () => clearTimeout(timer);\n }, []);\n\n const dismiss = useCallback(() => setVisible(false), []);\n\n if (!visible) return null;\n\n return (\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\n <div\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-cyan-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\n >\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\n <IconClock size={16} className=\"text-white shrink-0\" />\n <span className=\"paragraph-xsmall-semibold text-white\">\n {translate('common.navigation.banners.trial.message', { days: daysRemaining })}\n </span>\n </div>\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\n <button\n type=\"button\"\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\n onClick={onReactivate}\n >\n <span className=\"paragraph-xsmall-semibold text-white underline\">\n {translate('common.navigation.banners.trial.choosePlan')}\n </span>\n </button>\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\n <IconX size={18} className=\"text-cyan-100\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AA8BQ,SACE,KADF;AA5BR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,WAAW,aAAa;AACjC,SAAS,uBAAuB;AAOzB,SAAS,YAAY,EAAE,eAAe,aAAa,GAAqB;AAC7E,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,+NAA+N,WAAW,mCAAmC,mBAAmB;AAAA,MAE3S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,aAAU,MAAM,IAAI,WAAU,uBAAsB;AAAA,UACrD,oBAAC,UAAK,WAAU,wCACb,oBAAU,2CAA2C,EAAE,MAAM,cAAc,CAAC,GAC/E;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,kDACb,oBAAU,4CAA4C,GACzD;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB,GAC7C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/TrialBanner.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { IconClock, IconX } from '@tabler/icons-react';\r\nimport { useTranslations } from 'next-intl';\r\n\r\ninterface TrialBannerProps {\r\n daysRemaining: number;\r\n onReactivate?: () => void;\r\n}\r\n\r\nexport function TrialBanner({ daysRemaining, onReactivate }: TrialBannerProps) {\r\n const translate = useTranslations();\r\n const [visible, setVisible] = useState(true);\r\n const [animated, setAnimated] = useState(false);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setAnimated(true), 50);\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n const dismiss = useCallback(() => setVisible(false), []);\r\n\r\n if (!visible) return null;\r\n\r\n return (\r\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\r\n <div\r\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-cyan-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\r\n >\r\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\r\n <IconClock size={16} className=\"text-white shrink-0\" />\r\n <span className=\"paragraph-xsmall-semibold text-white\">\r\n {translate('common.navigation.banners.trial.message', { days: daysRemaining })}\r\n </span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\r\n <button\r\n type=\"button\"\r\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\r\n onClick={onReactivate}\r\n >\r\n <span className=\"paragraph-xsmall-semibold text-white underline\">\r\n {translate('common.navigation.banners.trial.choosePlan')}\r\n </span>\r\n </button>\r\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\r\n <IconX size={18} className=\"text-cyan-100\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"mappings":";AA8BQ,SACE,KADF;AA5BR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,WAAW,aAAa;AACjC,SAAS,uBAAuB;AAOzB,SAAS,YAAY,EAAE,eAAe,aAAa,GAAqB;AAC7E,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,+NAA+N,WAAW,mCAAmC,mBAAmB;AAAA,MAE3S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,aAAU,MAAM,IAAI,WAAU,uBAAsB;AAAA,UACrD,oBAAC,UAAK,WAAU,wCACb,oBAAU,2CAA2C,EAAE,MAAM,cAAc,CAAC,GAC/E;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,kDACb,oBAAU,4CAA4C,GACzD;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB,GAC7C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/navigation/UpcomingInvoiceBanner.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { IconAlertTriangle, IconX } from '@tabler/icons-react';\nimport { formatShortDate } from '../../infra/utils/date';\nimport { useTranslations } from 'next-intl';\n\ninterface UpcomingInvoiceBannerProps {\n dueDate?: Date | null;\n onDetails?: () => void;\n}\n\nexport function UpcomingInvoiceBanner({ dueDate, onDetails }: UpcomingInvoiceBannerProps) {\n const translate = useTranslations();\n const [visible, setVisible] = useState(true);\n const [animated, setAnimated] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setAnimated(true), 50);\n return () => clearTimeout(timer);\n }, []);\n\n const dismiss = useCallback(() => setVisible(false), []);\n\n if (!visible) return null;\n\n const formattedDueDate = formatShortDate(dueDate);\n\n return (\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\n <div\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-yellow-400 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\n >\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\n <IconAlertTriangle size={16} className=\"text-zinc-950 shrink-0\" />\n <span className=\"paragraph-xsmall-semibold text-zinc-950\">\n {translate('common.navigation.banners.upcoming.message', { dueDate: formattedDueDate ?? '' })}\n </span>\n </div>\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\n <button\n type=\"button\"\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\n onClick={onDetails}\n >\n <span className=\"paragraph-xsmall-semibold text-zinc-950 underline\">{translate('common.navigation.banners.upcoming.details')}</span>\n </button>\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\n <IconX size={18} className=\"text-zinc-700\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAiCQ,SACE,KADF;AA/BR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,mBAAmB,aAAa;AACzC,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAOzB,SAAS,sBAAsB,EAAE,SAAS,UAAU,GAA+B;AACxF,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,mBAAmB,gBAAgB,OAAO;AAEhD,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iOAAiO,WAAW,mCAAmC,mBAAmB;AAAA,MAE7S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,qBAAkB,MAAM,IAAI,WAAU,0BAAyB;AAAA,UAChE,oBAAC,UAAK,WAAU,2CACb,oBAAU,8CAA8C,EAAE,SAAS,oBAAoB,GAAG,CAAC,GAC9F;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,qDAAqD,oBAAU,4CAA4C,GAAE;AAAA;AAAA,UAC/H;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB,GAC7C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/navigation/UpcomingInvoiceBanner.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { IconAlertTriangle, IconX } from '@tabler/icons-react';\r\nimport { formatShortDate } from '../../infra/utils/date';\r\nimport { useTranslations } from 'next-intl';\r\n\r\ninterface UpcomingInvoiceBannerProps {\r\n dueDate?: Date | null;\r\n onDetails?: () => void;\r\n}\r\n\r\nexport function UpcomingInvoiceBanner({ dueDate, onDetails }: UpcomingInvoiceBannerProps) {\r\n const translate = useTranslations();\r\n const [visible, setVisible] = useState(true);\r\n const [animated, setAnimated] = useState(false);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setAnimated(true), 50);\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n const dismiss = useCallback(() => setVisible(false), []);\r\n\r\n if (!visible) return null;\r\n\r\n const formattedDueDate = formatShortDate(dueDate);\r\n\r\n return (\r\n <div className=\"fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\r\n <div\r\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-yellow-400 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\r\n >\r\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\r\n <IconAlertTriangle size={16} className=\"text-zinc-950 shrink-0\" />\r\n <span className=\"paragraph-xsmall-semibold text-zinc-950\">\r\n {translate('common.navigation.banners.upcoming.message', { dueDate: formattedDueDate ?? '' })}\r\n </span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\r\n <button\r\n type=\"button\"\r\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\r\n onClick={onDetails}\r\n >\r\n <span className=\"paragraph-xsmall-semibold text-zinc-950 underline\">{translate('common.navigation.banners.upcoming.details')}</span>\r\n </button>\r\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\r\n <IconX size={18} className=\"text-zinc-700\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"mappings":";AAiCQ,SACE,KADF;AA/BR,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,mBAAmB,aAAa;AACzC,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAOzB,SAAS,sBAAsB,EAAE,SAAS,UAAU,GAA+B;AACxF,QAAM,YAAY,gBAAgB;AAClC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,mBAAmB,gBAAgB,OAAO;AAEhD,SACE,oBAAC,SAAI,WAAU,wGACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iOAAiO,WAAW,mCAAmC,mBAAmB;AAAA,MAE7S;AAAA,6BAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,qBAAkB,MAAM,IAAI,WAAU,0BAAyB;AAAA,UAChE,oBAAC,UAAK,WAAU,2CACb,oBAAU,8CAA8C,EAAE,SAAS,oBAAoB,GAAG,CAAC,GAC9F;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,qDAAqD,oBAAU,4CAA4C,GAAE;AAAA;AAAA,UAC/H;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB,GAC7C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/navigation/shells/TabsMobileShell.tsx"],"sourcesContent":["'use client';\n\nimport { ReactNode, useRef, useEffect } from 'react';\nimport Link from 'next/link';\nimport { AppNavigationContext } from '../AppNavigationContext';\nimport { useNavItemsContext } from '../NavItemsContext';\n\nfunction InternalTabsBar({ topOffset = '72px' }: { topOffset?: string }) {\n const { navItems } = useNavItemsContext();\n const tabsListRef = useRef<HTMLDivElement>(null);\n const activeTabRef = useRef<HTMLAnchorElement>(null);\n\n const activeLabel = navItems.find((i) => i.isActive)?.label;\n\n // Scroll active tab into center when active item changes\n useEffect(() => {\n if (activeTabRef.current && tabsListRef.current) {\n const tabsList = tabsListRef.current;\n const activeTabElement = activeTabRef.current;\n const tabsListRect = tabsList.getBoundingClientRect();\n const activeTabRect = activeTabElement.getBoundingClientRect();\n const scrollLeft =\n activeTabElement.offsetLeft - tabsListRect.width / 2 + activeTabRect.width / 2;\n tabsList.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });\n }\n }, [activeLabel]);\n\n if (!navItems.length) return null;\n\n return (\n <div\n ref={tabsListRef}\n className=\"md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide\"\n style={{ top: topOffset }}\n >\n {navItems.map((item) => (\n <Link\n key={item.label}\n ref={item.isActive ? activeTabRef : undefined}\n href={item.href}\n prefetch\n className={`flex items-center gap-2 px-4 py-3 shrink-0 border-b-2 transition-colors ${\n item.isActive\n ? 'border-gray-950 text-gray-950'\n : 'border-transparent text-gray-500 hover:text-gray-900'\n }`}\n >\n {item.icon && <item.icon size={16} className=\"shrink-0\" />}\n <span\n className={\n item.isActive ? 'paragraph-small-semibold' : 'paragraph-small-medium'\n }\n >\n {item.label}\n </span>\n </Link>\n ))}\n </div>\n );\n}\n\nexport function TabsMobileShell({ children, topOffset }: { children: ReactNode; topOffset?: string }) {\n return (\n <AppNavigationContext.Provider value={{ breakpoint: 'mobile' }}>\n {/*\n Children are hidden visually, but NavItems' useEffect still fires inside\n display:none — React effects are tied to commit phase, not layout visibility.\n This registers navItems in NavItemsContext so InternalTabsBar can read them.\n */}\n <div className=\"hidden\">{children}</div>\n <InternalTabsBar topOffset={topOffset} />\n </AppNavigationContext.Provider>\n );\n}\n"],"mappings":";AAoCQ,SAWgB,KAXhB;AAlCR,SAAoB,QAAQ,iBAAiB;AAC7C,OAAO,UAAU;AACjB,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AAEnC,SAAS,gBAAgB,EAAE,YAAY,OAAO,GAA2B;AACvE,QAAM,EAAE,SAAS,IAAI,mBAAmB;AACxC,QAAM,cAAc,OAAuB,IAAI;AAC/C,QAAM,eAAe,OAA0B,IAAI;AAEnD,QAAM,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAGtD,YAAU,MAAM;AACd,QAAI,aAAa,WAAW,YAAY,SAAS;AAC/C,YAAM,WAAW,YAAY;AAC7B,YAAM,mBAAmB,aAAa;AACtC,YAAM,eAAe,SAAS,sBAAsB;AACpD,YAAM,gBAAgB,iBAAiB,sBAAsB;AAC7D,YAAM,aACJ,iBAAiB,aAAa,aAAa,QAAQ,IAAI,cAAc,QAAQ;AAC/E,eAAS,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,GAAG,UAAU,SAAS,CAAC;AAAA,IACzE;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,MAAI,CAAC,SAAS,OAAQ,QAAO;AAE7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACV,OAAO,EAAE,KAAK,UAAU;AAAA,MAEvB,mBAAS,IAAI,CAAC,SACb;AAAA,QAAC;AAAA;AAAA,UAEC,KAAK,KAAK,WAAW,eAAe;AAAA,UACpC,MAAM,KAAK;AAAA,UACX,UAAQ;AAAA,UACR,WAAW,2EACT,KAAK,WACD,kCACA,sDACN;AAAA,UAEC;AAAA,iBAAK,QAAQ,oBAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,YAAW;AAAA,YACxD;AAAA,cAAC;AAAA;AAAA,gBACC,WACE,KAAK,WAAW,6BAA6B;AAAA,gBAG9C,eAAK;AAAA;AAAA,YACR;AAAA;AAAA;AAAA,QAjBK,KAAK;AAAA,MAkBZ,CACD;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,gBAAgB,EAAE,UAAU,UAAU,GAAgD;AACpG,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAAO,EAAE,YAAY,SAAS,GAM3D;AAAA,wBAAC,SAAI,WAAU,UAAU,UAAS;AAAA,IAClC,oBAAC,mBAAgB,WAAsB;AAAA,KACzC;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/navigation/shells/TabsMobileShell.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { ReactNode, useRef, useEffect } from 'react';\r\nimport Link from 'next/link';\r\nimport { AppNavigationContext } from '../AppNavigationContext';\r\nimport { useNavItemsContext } from '../NavItemsContext';\r\n\r\nfunction InternalTabsBar({ topOffset = '72px' }: { topOffset?: string }) {\r\n const { navItems } = useNavItemsContext();\r\n const tabsListRef = useRef<HTMLDivElement>(null);\r\n const activeTabRef = useRef<HTMLAnchorElement>(null);\r\n\r\n const activeLabel = navItems.find((i) => i.isActive)?.label;\r\n\r\n // Scroll active tab into center when active item changes\r\n useEffect(() => {\r\n if (activeTabRef.current && tabsListRef.current) {\r\n const tabsList = tabsListRef.current;\r\n const activeTabElement = activeTabRef.current;\r\n const tabsListRect = tabsList.getBoundingClientRect();\r\n const activeTabRect = activeTabElement.getBoundingClientRect();\r\n const scrollLeft =\r\n activeTabElement.offsetLeft - tabsListRect.width / 2 + activeTabRect.width / 2;\r\n tabsList.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });\r\n }\r\n }, [activeLabel]);\r\n\r\n if (!navItems.length) return null;\r\n\r\n return (\r\n <div\r\n ref={tabsListRef}\r\n className=\"md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide\"\r\n style={{ top: topOffset }}\r\n >\r\n {navItems.map((item) => (\r\n <Link\r\n key={item.label}\r\n ref={item.isActive ? activeTabRef : undefined}\r\n href={item.href}\r\n prefetch\r\n className={`flex items-center gap-2 px-4 py-3 shrink-0 border-b-2 transition-colors ${\r\n item.isActive\r\n ? 'border-gray-950 text-gray-950'\r\n : 'border-transparent text-gray-500 hover:text-gray-900'\r\n }`}\r\n >\r\n {item.icon && <item.icon size={16} className=\"shrink-0\" />}\r\n <span\r\n className={\r\n item.isActive ? 'paragraph-small-semibold' : 'paragraph-small-medium'\r\n }\r\n >\r\n {item.label}\r\n </span>\r\n </Link>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TabsMobileShell({ children, topOffset }: { children: ReactNode; topOffset?: string }) {\r\n return (\r\n <AppNavigationContext.Provider value={{ breakpoint: 'mobile' }}>\r\n {/*\r\n Children are hidden visually, but NavItems' useEffect still fires inside\r\n display:none — React effects are tied to commit phase, not layout visibility.\r\n This registers navItems in NavItemsContext so InternalTabsBar can read them.\r\n */}\r\n <div className=\"hidden\">{children}</div>\r\n <InternalTabsBar topOffset={topOffset} />\r\n </AppNavigationContext.Provider>\r\n );\r\n}\r\n"],"mappings":";AAoCQ,SAWgB,KAXhB;AAlCR,SAAoB,QAAQ,iBAAiB;AAC7C,OAAO,UAAU;AACjB,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AAEnC,SAAS,gBAAgB,EAAE,YAAY,OAAO,GAA2B;AACvE,QAAM,EAAE,SAAS,IAAI,mBAAmB;AACxC,QAAM,cAAc,OAAuB,IAAI;AAC/C,QAAM,eAAe,OAA0B,IAAI;AAEnD,QAAM,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAGtD,YAAU,MAAM;AACd,QAAI,aAAa,WAAW,YAAY,SAAS;AAC/C,YAAM,WAAW,YAAY;AAC7B,YAAM,mBAAmB,aAAa;AACtC,YAAM,eAAe,SAAS,sBAAsB;AACpD,YAAM,gBAAgB,iBAAiB,sBAAsB;AAC7D,YAAM,aACJ,iBAAiB,aAAa,aAAa,QAAQ,IAAI,cAAc,QAAQ;AAC/E,eAAS,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,GAAG,UAAU,SAAS,CAAC;AAAA,IACzE;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,MAAI,CAAC,SAAS,OAAQ,QAAO;AAE7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACV,OAAO,EAAE,KAAK,UAAU;AAAA,MAEvB,mBAAS,IAAI,CAAC,SACb;AAAA,QAAC;AAAA;AAAA,UAEC,KAAK,KAAK,WAAW,eAAe;AAAA,UACpC,MAAM,KAAK;AAAA,UACX,UAAQ;AAAA,UACR,WAAW,2EACT,KAAK,WACD,kCACA,sDACN;AAAA,UAEC;AAAA,iBAAK,QAAQ,oBAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,YAAW;AAAA,YACxD;AAAA,cAAC;AAAA;AAAA,gBACC,WACE,KAAK,WAAW,6BAA6B;AAAA,gBAG9C,eAAK;AAAA;AAAA,YACR;AAAA;AAAA;AAAA,QAjBK,KAAK;AAAA,MAkBZ,CACD;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,gBAAgB,EAAE,UAAU,UAAU,GAAgD;AACpG,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAAO,EAAE,YAAY,SAAS,GAM3D;AAAA,wBAAC,SAAI,WAAU,UAAU,UAAS;AAAA,IAClC,oBAAC,mBAAgB,WAAsB;AAAA,KACzC;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/navigation/subcomponents/BottomLinks.tsx"],"sourcesContent":["'use client';\n\nimport { IconHelp, IconBulb, IconStar, type TablerIcon } from '@tabler/icons-react';\nimport { useIsDefaultWhitelabel, useWhitelabel } from '../../../providers/whitelabel.provider';\nimport { useTranslations } from 'next-intl';\n\ninterface BottomLink {\n label: string;\n icon: TablerIcon;\n href?: string;\n className?: string;\n onClick?: () => void;\n}\n\nfunction openFrillWidget() {\n const widget = (window as unknown as { __frillNovidadesWidget?: { open?: () => void } }).__frillNovidadesWidget;\n widget?.open?.();\n}\n\nexport function BottomLinks() {\n const translate = useTranslations();\n const { whitelabel } = useWhitelabel();\n const isMainWhitelabel = useIsDefaultWhitelabel();\n\n const helpUrl = whitelabel?.url_help || 'https://ajuda.greatsoftwares.com.br/pt-br/';\n\n const links: BottomLink[] = [\n ...(isMainWhitelabel\n ? [\n {\n label: translate('common.navigation.bottomLinks.news'),\n icon: IconStar,\n className: 'novidades',\n onClick: openFrillWidget,\n },\n ]\n : []),\n {\n label: translate('common.navigation.bottomLinks.helpCenter'),\n icon: IconHelp,\n href: helpUrl,\n },\n ...(isMainWhitelabel\n ? [\n {\n label: translate('common.navigation.bottomLinks.sendSuggestions'),\n icon: IconBulb,\n href: 'https://ideias.greatpages.com.br/b/y0geg1ve/feature-ideas',\n },\n ]\n : []),\n ];\n\n const baseClassName =\n 'rounded-md flex items-center gap-2 p-3 cursor-pointer transition-colors no-underline bg-white hover:bg-gray-100 active:bg-gray-50';\n\n return (\n <div className=\"flex flex-col\">\n {links.map((link) =>\n link.href ? (\n <a\n key={link.label}\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`${baseClassName}${link.className ? ` ${link.className}` : ''}`}\n >\n <link.icon size={20} className=\"text-gray-400\" />\n <span className=\"paragraph-small-medium text-gray-500\">{link.label}</span>\n </a>\n ) : (\n <button\n key={link.label}\n type=\"button\"\n onClick={link.onClick}\n className={`${baseClassName} text-left${link.className ? ` ${link.className}` : ''}`}\n >\n <link.icon size={20} className=\"text-gray-400\" />\n <span className=\"paragraph-small-medium text-gray-500\">{link.label}</span>\n </button>\n )\n )}\n </div>\n );\n}\n"],"mappings":";AA4DU,SAOE,KAPF;AA1DV,SAAS,UAAU,UAAU,gBAAiC;AAC9D,SAAS,wBAAwB,qBAAqB;AACtD,SAAS,uBAAuB;AAUhC,SAAS,kBAAkB;AACzB,QAAM,SAAU,OAAyE;AACzF,UAAQ,OAAO;AACjB;AAEO,SAAS,cAAc;AAC5B,QAAM,YAAY,gBAAgB;AAClC,QAAM,EAAE,WAAW,IAAI,cAAc;AACrC,QAAM,mBAAmB,uBAAuB;AAEhD,QAAM,UAAU,YAAY,YAAY;AAExC,QAAM,QAAsB;AAAA,IAC1B,GAAI,mBACA;AAAA,MACE;AAAA,QACE,OAAO,UAAU,oCAAoC;AAAA,QACrD,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,IACF,IACA,CAAC;AAAA,IACL;AAAA,MACE,OAAO,UAAU,0CAA0C;AAAA,MAC3D,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,IACA,GAAI,mBACA;AAAA,MACE;AAAA,QACE,OAAO,UAAU,+CAA+C;AAAA,QAChE,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAEA,QAAM,gBACJ;AAEF,SACE,oBAAC,SAAI,WAAU,iBACZ,gBAAM;AAAA,IAAI,CAAC,SACV,KAAK,OACH;AAAA,MAAC;AAAA;AAAA,QAEC,MAAM,KAAK;AAAA,QACX,QAAO;AAAA,QACP,KAAI;AAAA,QACJ,WAAW,GAAG,aAAa,GAAG,KAAK,YAAY,IAAI,KAAK,SAAS,KAAK,EAAE;AAAA,QAExE;AAAA,8BAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,iBAAgB;AAAA,UAC/C,oBAAC,UAAK,WAAU,wCAAwC,eAAK,OAAM;AAAA;AAAA;AAAA,MAP9D,KAAK;AAAA,IAQZ,IAEA;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,SAAS,KAAK;AAAA,QACd,WAAW,GAAG,aAAa,aAAa,KAAK,YAAY,IAAI,KAAK,SAAS,KAAK,EAAE;AAAA,QAElF;AAAA,8BAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,iBAAgB;AAAA,UAC/C,oBAAC,UAAK,WAAU,wCAAwC,eAAK,OAAM;AAAA;AAAA;AAAA,MAN9D,KAAK;AAAA,IAOZ;AAAA,EAEJ,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/navigation/subcomponents/BottomLinks.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { IconHelp, IconBulb, IconStar, type TablerIcon } from '@tabler/icons-react';\r\nimport { useIsDefaultWhitelabel, useWhitelabel } from '../../../providers/whitelabel.provider';\r\nimport { useTranslations } from 'next-intl';\r\n\r\ninterface BottomLink {\r\n label: string;\r\n icon: TablerIcon;\r\n href?: string;\r\n className?: string;\r\n onClick?: () => void;\r\n}\r\n\r\nfunction openFrillWidget() {\r\n const widget = (window as unknown as { __frillNovidadesWidget?: { open?: () => void } }).__frillNovidadesWidget;\r\n widget?.open?.();\r\n}\r\n\r\nexport function BottomLinks() {\r\n const translate = useTranslations();\r\n const { whitelabel } = useWhitelabel();\r\n const isMainWhitelabel = useIsDefaultWhitelabel();\r\n\r\n const helpUrl = whitelabel?.url_help || 'https://ajuda.greatsoftwares.com.br/pt-br/';\r\n\r\n const links: BottomLink[] = [\r\n ...(isMainWhitelabel\r\n ? [\r\n {\r\n label: translate('common.navigation.bottomLinks.news'),\r\n icon: IconStar,\r\n className: 'novidades',\r\n onClick: openFrillWidget,\r\n },\r\n ]\r\n : []),\r\n {\r\n label: translate('common.navigation.bottomLinks.helpCenter'),\r\n icon: IconHelp,\r\n href: helpUrl,\r\n },\r\n ...(isMainWhitelabel\r\n ? [\r\n {\r\n label: translate('common.navigation.bottomLinks.sendSuggestions'),\r\n icon: IconBulb,\r\n href: 'https://ideias.greatpages.com.br/b/y0geg1ve/feature-ideas',\r\n },\r\n ]\r\n : []),\r\n ];\r\n\r\n const baseClassName =\r\n 'rounded-md flex items-center gap-2 p-3 cursor-pointer transition-colors no-underline bg-white hover:bg-gray-100 active:bg-gray-50';\r\n\r\n return (\r\n <div className=\"flex flex-col\">\r\n {links.map((link) =>\r\n link.href ? (\r\n <a\r\n key={link.label}\r\n href={link.href}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className={`${baseClassName}${link.className ? ` ${link.className}` : ''}`}\r\n >\r\n <link.icon size={20} className=\"text-gray-400\" />\r\n <span className=\"paragraph-small-medium text-gray-500\">{link.label}</span>\r\n </a>\r\n ) : (\r\n <button\r\n key={link.label}\r\n type=\"button\"\r\n onClick={link.onClick}\r\n className={`${baseClassName} text-left${link.className ? ` ${link.className}` : ''}`}\r\n >\r\n <link.icon size={20} className=\"text-gray-400\" />\r\n <span className=\"paragraph-small-medium text-gray-500\">{link.label}</span>\r\n </button>\r\n )\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"mappings":";AA4DU,SAOE,KAPF;AA1DV,SAAS,UAAU,UAAU,gBAAiC;AAC9D,SAAS,wBAAwB,qBAAqB;AACtD,SAAS,uBAAuB;AAUhC,SAAS,kBAAkB;AACzB,QAAM,SAAU,OAAyE;AACzF,UAAQ,OAAO;AACjB;AAEO,SAAS,cAAc;AAC5B,QAAM,YAAY,gBAAgB;AAClC,QAAM,EAAE,WAAW,IAAI,cAAc;AACrC,QAAM,mBAAmB,uBAAuB;AAEhD,QAAM,UAAU,YAAY,YAAY;AAExC,QAAM,QAAsB;AAAA,IAC1B,GAAI,mBACA;AAAA,MACE;AAAA,QACE,OAAO,UAAU,oCAAoC;AAAA,QACrD,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,IACF,IACA,CAAC;AAAA,IACL;AAAA,MACE,OAAO,UAAU,0CAA0C;AAAA,MAC3D,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,IACA,GAAI,mBACA;AAAA,MACE;AAAA,QACE,OAAO,UAAU,+CAA+C;AAAA,QAChE,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAEA,QAAM,gBACJ;AAEF,SACE,oBAAC,SAAI,WAAU,iBACZ,gBAAM;AAAA,IAAI,CAAC,SACV,KAAK,OACH;AAAA,MAAC;AAAA;AAAA,QAEC,MAAM,KAAK;AAAA,QACX,QAAO;AAAA,QACP,KAAI;AAAA,QACJ,WAAW,GAAG,aAAa,GAAG,KAAK,YAAY,IAAI,KAAK,SAAS,KAAK,EAAE;AAAA,QAExE;AAAA,8BAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,iBAAgB;AAAA,UAC/C,oBAAC,UAAK,WAAU,wCAAwC,eAAK,OAAM;AAAA;AAAA;AAAA,MAP9D,KAAK;AAAA,IAQZ,IAEA;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,SAAS,KAAK;AAAA,QACd,WAAW,GAAG,aAAa,aAAa,KAAK,YAAY,IAAI,KAAK,SAAS,KAAK,EAAE;AAAA,QAElF;AAAA,8BAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,iBAAgB;AAAA,UAC/C,oBAAC,UAAK,WAAU,wCAAwC,eAAK,OAAM;AAAA;AAAA;AAAA,MAN9D,KAAK;AAAA,IAOZ;AAAA,EAEJ,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/navigation/subcomponents/ProjectSelector.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useRef, useEffect, useMemo, RefObject } from 'react';\nimport { useTranslations } from 'next-intl';\nimport { useMobileNavbarSheet } from '../../../store/useMobileNavbarSheet';\nimport { useAppNavigationContext } from '../AppNavigationContext';\nimport { ProjectSelectorPopover } from '../ProjectSelectorPopover';\nimport { cn, Command, CommandEmpty, CommandInput, CommandItem, CommandList, UserAvatar, useIsDefaultWhitelabel, useDebounce } from '../../../index';\nimport { useInfiniteProjects } from '../../../modules/projects/hooks/list-infinite-projects.hook';\nimport { IconChevronDown } from '@tabler/icons-react';\nimport type { Project } from '../../../modules/projects/types';\n\nexport interface ProjectSelectorProps {\n selectedProject: Project | null;\n onSelectProject: (project: Project) => void;\n onAddProject?: () => void;\n onManageProjects?: () => void;\n}\n\nfunction ProjectItemSkeleton() {\n return (\n <div className=\"flex items-center gap-2 p-[8.8px]\">\n <div className=\"skeleton size-9 rounded-lg shrink-0\" />\n <div className=\"skeleton h-4 w-36 rounded\" />\n </div>\n );\n}\n\nexport function ProjectSelector({\n selectedProject,\n onSelectProject,\n onManageProjects,\n}: ProjectSelectorProps) {\n const translate = useTranslations();\n const isMainWhitelabel = useIsDefaultWhitelabel();\n const { breakpoint } = useAppNavigationContext();\n const [isPopoverOpen, setIsPopoverOpen] = useState(false);\n const [activeSection, setActiveSection] = useState<'projects' | null>(null);\n const titleRef = useRef<HTMLDivElement>(null);\n const { openProjectList, clearProjectList } = useMobileNavbarSheet();\n\n const [search, setSearch] = useState('');\n const debouncedSearch = useDebounce(search, 300);\n\n const { data, isLoading, isFetching, isFetchingNextPage, hasNextPage, fetchNextPage } = useInfiniteProjects({\n sort: 'title',\n limit: 20,\n ...(debouncedSearch ? { search: debouncedSearch } : {}),\n });\n const projects = useMemo(() => data?.pages.flatMap((page) => page.data) ?? [], [data]);\n const showListSkeleton = isLoading || (isFetching && !isFetchingNextPage && !!debouncedSearch);\n\n const handlePopoverOpenChange: typeof setIsPopoverOpen = (value) => {\n setIsPopoverOpen((prev) => {\n const next = typeof value === 'function' ? value(prev) : value;\n if (!next) setSearch('');\n return next;\n });\n };\n\n useEffect(() => {\n if (openProjectList && breakpoint === 'mobile') {\n setActiveSection('projects');\n clearProjectList();\n }\n }, [openProjectList, breakpoint, clearProjectList]);\n\n // Desktop and md: title + popover (aligned with NavBar logo + separator)\n if (breakpoint === 'desktop' || breakpoint === 'md') {\n return (\n <div className={cn(\n !isMainWhitelabel ? \"mt-[14.5px] mb-[7px]\" : \"mt-[6.5px] mb-[3px]\"\n )}>\n <div className=\"flex items-center h-7\">\n <ProjectSelectorPopover\n open={isPopoverOpen}\n setOpen={handlePopoverOpenChange}\n titleRef={titleRef as unknown as RefObject<HTMLSpanElement | null>}\n projects={projects}\n selectedProject={selectedProject}\n isLoading={showListSkeleton}\n isFetchingNextPage={isFetchingNextPage}\n hasNextPage={hasNextPage}\n onLoadMore={() => fetchNextPage()}\n onSelectProject={onSelectProject}\n onManageProjects={onManageProjects}\n search={search}\n onSearchChange={setSearch}\n >\n <div className=\"flex items-center gap-2 truncate select-none cursor-pointer\" ref={titleRef}>\n {isLoading ? (\n <div className=\"skeleton h-4 w-32 rounded\" />\n ) : (\n <span className=\"paragraph-medium-semibold text-gray-600 truncate max-w-[120px]\">\n {selectedProject?.title}\n </span>\n )}\n <IconChevronDown\n size={20}\n className={`transition-transform duration-200 ${isPopoverOpen ? 'rotate-180 text-gray-950' : 'text-gray-400'}`}\n />\n </div>\n </ProjectSelectorPopover>\n </div>\n </div>\n );\n }\n\n // Mobile: inline collapsible accordion\n return (\n <div className=\"flex flex-col gap-2.5\">\n <div className=\"flex items-center justify-between\">\n <div\n className=\"flex items-center gap-1 cursor-pointer\"\n onClick={() => { const next = activeSection === 'projects' ? null : 'projects'; setActiveSection(next); if (!next) setSearch(''); }}\n >\n <span className=\"paragraph-medium-semibold text-gray-600\">{selectedProject?.title}</span>\n <IconChevronDown\n size={20}\n className={`transition-transform duration-200 ${\n activeSection === 'projects' ? 'rotate-180 text-gray-950' : 'text-gray-400'\n }`}\n />\n </div>\n </div>\n {activeSection === 'projects' && (\n <div className=\"flex flex-col p-3 gap-2 border border-gray-200 rounded-lg animate-in fade-in duration-400\">\n <div className=\"flex items-center justify-between\">\n <span className=\"paragraph-small-semibold\">{translate('common.navigation.projectSelector.title')}</span>\n </div>\n <Command className=\"gap-2\" shouldFilter={false}>\n <CommandInput placeholder={translate('common.navigation.projectSelector.searchPlaceholder')} value={search} onValueChange={setSearch} />\n <CommandList\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 h-[227px]\"\n onScroll={(event) => {\n if (!hasNextPage || isFetchingNextPage || !fetchNextPage) return;\n\n const target = event.currentTarget;\n const distanceToBottom = target.scrollHeight - target.scrollTop - target.clientHeight;\n\n if (distanceToBottom <= 80) {\n fetchNextPage();\n }\n }}\n >\n <CommandEmpty>{translate('common.navigation.projectSelector.noResults')}</CommandEmpty>\n {showListSkeleton ? (\n <>\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n </>\n ) : (\n projects.map((project) => (\n <CommandItem\n key={project.id}\n value={`${project.title}-${project.id}`}\n keywords={[project.title]}\n className={selectedProject?.id === project.id ? 'bg-gray-50 min-h-[39px]' : 'min-h-[39px]'}\n onSelect={() => { onSelectProject(project); setActiveSection(null); setSearch(''); }}\n >\n <UserAvatar\n photo={project.photo}\n name={project.title}\n size={36}\n />\n {project.title}\n </CommandItem>\n ))\n )}\n {isFetchingNextPage && (\n <>\n <ProjectItemSkeleton />\n <ProjectItemSkeleton />\n </>\n )}\n </CommandList>\n </Command>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/navigation/subcomponents/ProjectSelector.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useRef, useEffect, useMemo, RefObject } from 'react';\r\nimport { useTranslations } from 'next-intl';\r\nimport { useMobileNavbarSheet } from '../../../store/useMobileNavbarSheet';\r\nimport { useAppNavigationContext } from '../AppNavigationContext';\r\nimport { ProjectSelectorPopover } from '../ProjectSelectorPopover';\r\nimport { cn, Command, CommandEmpty, CommandInput, CommandItem, CommandList, UserAvatar, useIsDefaultWhitelabel, useDebounce } from '../../../index';\r\nimport { useInfiniteProjects } from '../../../modules/projects/hooks/list-infinite-projects.hook';\r\nimport { IconChevronDown } from '@tabler/icons-react';\r\nimport type { Project } from '../../../modules/projects/types';\r\n\r\nexport interface ProjectSelectorProps {\r\n selectedProject: Project | null;\r\n onSelectProject: (project: Project) => void;\r\n onAddProject?: () => void;\r\n onManageProjects?: () => void;\r\n}\r\n\r\nfunction ProjectItemSkeleton() {\r\n return (\r\n <div className=\"flex items-center gap-2 p-[8.8px]\">\r\n <div className=\"skeleton size-9 rounded-lg shrink-0\" />\r\n <div className=\"skeleton h-4 w-36 rounded\" />\r\n </div>\r\n );\r\n}\r\n\r\nexport function ProjectSelector({\r\n selectedProject,\r\n onSelectProject,\r\n onManageProjects,\r\n}: ProjectSelectorProps) {\r\n const translate = useTranslations();\r\n const isMainWhitelabel = useIsDefaultWhitelabel();\r\n const { breakpoint } = useAppNavigationContext();\r\n const [isPopoverOpen, setIsPopoverOpen] = useState(false);\r\n const [activeSection, setActiveSection] = useState<'projects' | null>(null);\r\n const titleRef = useRef<HTMLDivElement>(null);\r\n const { openProjectList, clearProjectList } = useMobileNavbarSheet();\r\n\r\n const [search, setSearch] = useState('');\r\n const debouncedSearch = useDebounce(search, 300);\r\n\r\n const { data, isLoading, isFetching, isFetchingNextPage, hasNextPage, fetchNextPage } = useInfiniteProjects({\r\n sort: 'title',\r\n limit: 20,\r\n ...(debouncedSearch ? { search: debouncedSearch } : {}),\r\n });\r\n const projects = useMemo(() => data?.pages.flatMap((page) => page.data) ?? [], [data]);\r\n const showListSkeleton = isLoading || (isFetching && !isFetchingNextPage && !!debouncedSearch);\r\n\r\n const handlePopoverOpenChange: typeof setIsPopoverOpen = (value) => {\r\n setIsPopoverOpen((prev) => {\r\n const next = typeof value === 'function' ? value(prev) : value;\r\n if (!next) setSearch('');\r\n return next;\r\n });\r\n };\r\n\r\n useEffect(() => {\r\n if (openProjectList && breakpoint === 'mobile') {\r\n setActiveSection('projects');\r\n clearProjectList();\r\n }\r\n }, [openProjectList, breakpoint, clearProjectList]);\r\n\r\n // Desktop and md: title + popover (aligned with NavBar logo + separator)\r\n if (breakpoint === 'desktop' || breakpoint === 'md') {\r\n return (\r\n <div className={cn(\r\n !isMainWhitelabel ? \"mt-[14.5px] mb-[7px]\" : \"mt-[6.5px] mb-[3px]\"\r\n )}>\r\n <div className=\"flex items-center h-7\">\r\n <ProjectSelectorPopover\r\n open={isPopoverOpen}\r\n setOpen={handlePopoverOpenChange}\r\n titleRef={titleRef as unknown as RefObject<HTMLSpanElement | null>}\r\n projects={projects}\r\n selectedProject={selectedProject}\r\n isLoading={showListSkeleton}\r\n isFetchingNextPage={isFetchingNextPage}\r\n hasNextPage={hasNextPage}\r\n onLoadMore={() => fetchNextPage()}\r\n onSelectProject={onSelectProject}\r\n onManageProjects={onManageProjects}\r\n search={search}\r\n onSearchChange={setSearch}\r\n >\r\n <div className=\"flex items-center gap-2 truncate select-none cursor-pointer\" ref={titleRef}>\r\n {isLoading ? (\r\n <div className=\"skeleton h-4 w-32 rounded\" />\r\n ) : (\r\n <span className=\"paragraph-medium-semibold text-gray-600 truncate max-w-[120px]\">\r\n {selectedProject?.title}\r\n </span>\r\n )}\r\n <IconChevronDown\r\n size={20}\r\n className={`transition-transform duration-200 ${isPopoverOpen ? 'rotate-180 text-gray-950' : 'text-gray-400'}`}\r\n />\r\n </div>\r\n </ProjectSelectorPopover>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Mobile: inline collapsible accordion\r\n return (\r\n <div className=\"flex flex-col gap-2.5\">\r\n <div className=\"flex items-center justify-between\">\r\n <div\r\n className=\"flex items-center gap-1 cursor-pointer\"\r\n onClick={() => { const next = activeSection === 'projects' ? null : 'projects'; setActiveSection(next); if (!next) setSearch(''); }}\r\n >\r\n <span className=\"paragraph-medium-semibold text-gray-600\">{selectedProject?.title}</span>\r\n <IconChevronDown\r\n size={20}\r\n className={`transition-transform duration-200 ${\r\n activeSection === 'projects' ? 'rotate-180 text-gray-950' : 'text-gray-400'\r\n }`}\r\n />\r\n </div>\r\n </div>\r\n {activeSection === 'projects' && (\r\n <div className=\"flex flex-col p-3 gap-2 border border-gray-200 rounded-lg animate-in fade-in duration-400\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"paragraph-small-semibold\">{translate('common.navigation.projectSelector.title')}</span>\r\n </div>\r\n <Command className=\"gap-2\" shouldFilter={false}>\r\n <CommandInput placeholder={translate('common.navigation.projectSelector.searchPlaceholder')} value={search} onValueChange={setSearch} />\r\n <CommandList\r\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 h-[227px]\"\r\n onScroll={(event) => {\r\n if (!hasNextPage || isFetchingNextPage || !fetchNextPage) return;\r\n\r\n const target = event.currentTarget;\r\n const distanceToBottom = target.scrollHeight - target.scrollTop - target.clientHeight;\r\n\r\n if (distanceToBottom <= 80) {\r\n fetchNextPage();\r\n }\r\n }}\r\n >\r\n <CommandEmpty>{translate('common.navigation.projectSelector.noResults')}</CommandEmpty>\r\n {showListSkeleton ? (\r\n <>\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n </>\r\n ) : (\r\n projects.map((project) => (\r\n <CommandItem\r\n key={project.id}\r\n value={`${project.title}-${project.id}`}\r\n keywords={[project.title]}\r\n className={selectedProject?.id === project.id ? 'bg-gray-50 min-h-[39px]' : 'min-h-[39px]'}\r\n onSelect={() => { onSelectProject(project); setActiveSection(null); setSearch(''); }}\r\n >\r\n <UserAvatar\r\n photo={project.photo}\r\n name={project.title}\r\n size={36}\r\n />\r\n {project.title}\r\n </CommandItem>\r\n ))\r\n )}\r\n {isFetchingNextPage && (\r\n <>\r\n <ProjectItemSkeleton />\r\n <ProjectItemSkeleton />\r\n </>\r\n )}\r\n </CommandList>\r\n </Command>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/pages/NotFoundPage.tsx"],"sourcesContent":["'use client';\n\nimport Image from \"next/image\";\nimport { useEffect } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport { useRouter } from \"next/navigation\";\nimport { useWhitelabel, useIsDefaultWhitelabel } from \"../../providers/whitelabel.provider\";\nimport { Button } from \"../ui/buttons/Button\";\nimport { hideCrisp } from \"../embeds/CrispEmbed\";\n\nfunction GreatAppsLogo() {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"50\" height=\"50\" viewBox=\"0 0 68 68\" fill=\"none\">\n <rect x=\"4.5\" y=\"4.5\" width=\"58.4463\" height=\"58.4463\" rx=\"14.2271\" fill=\"#09090B\" />\n <rect x=\"4.5\" y=\"4.5\" width=\"58.4463\" height=\"58.4463\" rx=\"14.2271\" stroke=\"white\" strokeWidth=\"9\" />\n <path d=\"M38.0883 19.5377C38.6909 19.5377 39.1795 20.0264 39.1795 20.6289V25.5892C39.1795 25.9865 39.106 26.3827 38.9364 26.7421C38.4857 27.6992 37.5451 28.2674 36.5452 28.2674H29.9031C28.9993 28.2674 28.2663 29.0004 28.2663 29.9042V37.5427C28.2663 38.4465 28.9993 39.1795 29.9031 39.1795H37.5415C38.4453 39.1795 39.1783 38.4465 39.1783 37.5427V30.9693C39.1783 30.4522 39.3053 29.9374 39.5804 29.5009C40.0596 28.7406 40.8768 28.2899 41.7462 28.2686H46.8168C47.4193 28.2686 47.908 28.7561 47.908 29.3586V37.8238C47.908 38.692 47.5629 39.5246 46.9497 40.139L40.1379 46.9508C39.5235 47.5652 38.6909 47.9091 37.8226 47.9091H29.3587C28.7561 47.9091 28.2674 47.4205 28.2674 46.8179L28.2674 41.8126C28.2674 41.114 27.9899 40.4439 27.4965 39.9504C27.0031 39.457 26.3329 39.1795 25.6343 39.1795H20.629C20.0265 39.1795 19.5378 38.6908 19.5378 38.0883L19.5378 29.6231C19.5378 28.7549 19.8829 27.9222 20.4961 27.3078L27.468 20.3371C27.9792 19.8259 28.6731 19.5377 29.3966 19.5377H38.0871H38.0883Z\" fill=\"white\" />\n </svg>\n );\n}\n\nexport function NotFoundPage() {\n const translate = useTranslations();\n const router = useRouter();\n\n useEffect(() => {\n hideCrisp();\n }, []);\n const { whitelabel } = useWhitelabel();\n const isGreatApps = useIsDefaultWhitelabel();\n const whitelabelLogo = whitelabel?.logo\n ? `${process.env.NEXT_PUBLIC_STORAGE_URL}/${whitelabel.logo}`\n : null;\n\n return (\n <div className=\"relative flex min-h-screen w-full flex-col items-center justify-center overflow-hidden bg-white\">\n <div className=\"flex flex-col items-center gap-[22px] text-center\">\n <div className=\"relative flex flex-col items-center\">\n <Image src=\"/images/404.svg\" alt=\"404\" width={440} height={173} priority unoptimized />\n\n <div className=\"-mt-1 w-full border-t border-zinc-100\" />\n\n <div className=\"-mt-[25px]\">\n {isGreatApps ? (\n <GreatAppsLogo />\n ) : whitelabelLogo ? (\n <Image src={whitelabelLogo} alt={whitelabel?.name || ''} width={50} height={50} className=\"rounded-xl object-contain\" />\n ) : null}\n </div>\n </div>\n\n <h1 className=\"max-w-[554px] px-6 font-[family-name:var(--font-outfit)] text-[32px] leading-[36px] font-semibold text-zinc-950 sm:px-0 sm:text-[56px] sm:leading-[56px]\">\n {translate('common.notFound.title')}\n </h1>\n\n <p className=\"max-w-[496px] px-6 paragraph-medium-medium text-zinc-950 sm:px-0\">\n {translate('common.notFound.description')}\n </p>\n\n <Button\n variant=\"secondary\"\n className=\"h-10!\"\n onClick={() => {\n if (window.history.length > 1) {\n router.back();\n } else {\n router.push('/');\n }\n }}\n >\n {translate('common.notFound.backToHome')}\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":";AAYI,SACE,KADF;AAVJ,OAAO,WAAW;AAClB,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,eAAe,8BAA8B;AACtD,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAE1B,SAAS,gBAAgB;AACvB,SACE,qBAAC,SAAI,OAAM,8BAA6B,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QACtF;AAAA,wBAAC,UAAK,GAAE,OAAM,GAAE,OAAM,OAAM,WAAU,QAAO,WAAU,IAAG,WAAU,MAAK,WAAU;AAAA,IACnF,oBAAC,UAAK,GAAE,OAAM,GAAE,OAAM,OAAM,WAAU,QAAO,WAAU,IAAG,WAAU,QAAO,SAAQ,aAAY,KAAI;AAAA,IACnG,oBAAC,UAAK,GAAE,m9BAAk9B,MAAK,SAAQ;AAAA,KACz+B;AAEJ;AAEO,SAAS,eAAe;AAC7B,QAAM,YAAY,gBAAgB;AAClC,QAAM,SAAS,UAAU;AAEzB,YAAU,MAAM;AACd,cAAU;AAAA,EACZ,GAAG,CAAC,CAAC;AACL,QAAM,EAAE,WAAW,IAAI,cAAc;AACrC,QAAM,cAAc,uBAAuB;AAC3C,QAAM,iBAAiB,YAAY,OAC/B,GAAG,QAAQ,IAAI,uBAAuB,IAAI,WAAW,IAAI,KACzD;AAEJ,SACE,oBAAC,SAAI,WAAU,mGACb,+BAAC,SAAI,WAAU,qDACb;AAAA,yBAAC,SAAI,WAAU,uCACb;AAAA,0BAAC,SAAM,KAAI,mBAAkB,KAAI,OAAM,OAAO,KAAK,QAAQ,KAAK,UAAQ,MAAC,aAAW,MAAC;AAAA,MAErF,oBAAC,SAAI,WAAU,yCAAwC;AAAA,MAEvD,oBAAC,SAAI,WAAU,cACZ,wBACC,oBAAC,iBAAc,IACb,iBACF,oBAAC,SAAM,KAAK,gBAAgB,KAAK,YAAY,QAAQ,IAAI,OAAO,IAAI,QAAQ,IAAI,WAAU,6BAA4B,IACpH,MACN;AAAA,OACF;AAAA,IAEA,oBAAC,QAAG,WAAU,4JACX,oBAAU,uBAAuB,GACpC;AAAA,IAEA,oBAAC,OAAE,WAAU,oEACV,oBAAU,6BAA6B,GAC1C;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,SAAS,MAAM;AACb,cAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,mBAAO,KAAK;AAAA,UACd,OAAO;AACL,mBAAO,KAAK,GAAG;AAAA,UACjB;AAAA,QACF;AAAA,QAEC,oBAAU,4BAA4B;AAAA;AAAA,IACzC;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/pages/NotFoundPage.tsx"],"sourcesContent":["'use client';\r\n\r\nimport Image from \"next/image\";\r\nimport { useEffect } from \"react\";\r\nimport { useTranslations } from \"next-intl\";\r\nimport { useRouter } from \"next/navigation\";\r\nimport { useWhitelabel, useIsDefaultWhitelabel } from \"../../providers/whitelabel.provider\";\r\nimport { Button } from \"../ui/buttons/Button\";\r\nimport { hideCrisp } from \"../embeds/CrispEmbed\";\r\n\r\nfunction GreatAppsLogo() {\r\n return (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"50\" height=\"50\" viewBox=\"0 0 68 68\" fill=\"none\">\r\n <rect x=\"4.5\" y=\"4.5\" width=\"58.4463\" height=\"58.4463\" rx=\"14.2271\" fill=\"#09090B\" />\r\n <rect x=\"4.5\" y=\"4.5\" width=\"58.4463\" height=\"58.4463\" rx=\"14.2271\" stroke=\"white\" strokeWidth=\"9\" />\r\n <path d=\"M38.0883 19.5377C38.6909 19.5377 39.1795 20.0264 39.1795 20.6289V25.5892C39.1795 25.9865 39.106 26.3827 38.9364 26.7421C38.4857 27.6992 37.5451 28.2674 36.5452 28.2674H29.9031C28.9993 28.2674 28.2663 29.0004 28.2663 29.9042V37.5427C28.2663 38.4465 28.9993 39.1795 29.9031 39.1795H37.5415C38.4453 39.1795 39.1783 38.4465 39.1783 37.5427V30.9693C39.1783 30.4522 39.3053 29.9374 39.5804 29.5009C40.0596 28.7406 40.8768 28.2899 41.7462 28.2686H46.8168C47.4193 28.2686 47.908 28.7561 47.908 29.3586V37.8238C47.908 38.692 47.5629 39.5246 46.9497 40.139L40.1379 46.9508C39.5235 47.5652 38.6909 47.9091 37.8226 47.9091H29.3587C28.7561 47.9091 28.2674 47.4205 28.2674 46.8179L28.2674 41.8126C28.2674 41.114 27.9899 40.4439 27.4965 39.9504C27.0031 39.457 26.3329 39.1795 25.6343 39.1795H20.629C20.0265 39.1795 19.5378 38.6908 19.5378 38.0883L19.5378 29.6231C19.5378 28.7549 19.8829 27.9222 20.4961 27.3078L27.468 20.3371C27.9792 19.8259 28.6731 19.5377 29.3966 19.5377H38.0871H38.0883Z\" fill=\"white\" />\r\n </svg>\r\n );\r\n}\r\n\r\nexport function NotFoundPage() {\r\n const translate = useTranslations();\r\n const router = useRouter();\r\n\r\n useEffect(() => {\r\n hideCrisp();\r\n }, []);\r\n const { whitelabel } = useWhitelabel();\r\n const isGreatApps = useIsDefaultWhitelabel();\r\n const whitelabelLogo = whitelabel?.logo\r\n ? `${process.env.NEXT_PUBLIC_STORAGE_URL}/${whitelabel.logo}`\r\n : null;\r\n\r\n return (\r\n <div className=\"relative flex min-h-screen w-full flex-col items-center justify-center overflow-hidden bg-white\">\r\n <div className=\"flex flex-col items-center gap-[22px] text-center\">\r\n <div className=\"relative flex flex-col items-center\">\r\n <Image src=\"/images/404.svg\" alt=\"404\" width={440} height={173} priority unoptimized />\r\n\r\n <div className=\"-mt-1 w-full border-t border-zinc-100\" />\r\n\r\n <div className=\"-mt-[25px]\">\r\n {isGreatApps ? (\r\n <GreatAppsLogo />\r\n ) : whitelabelLogo ? (\r\n <Image src={whitelabelLogo} alt={whitelabel?.name || ''} width={50} height={50} className=\"rounded-xl object-contain\" />\r\n ) : null}\r\n </div>\r\n </div>\r\n\r\n <h1 className=\"max-w-[554px] px-6 font-[family-name:var(--font-outfit)] text-[32px] leading-[36px] font-semibold text-zinc-950 sm:px-0 sm:text-[56px] sm:leading-[56px]\">\r\n {translate('common.notFound.title')}\r\n </h1>\r\n\r\n <p className=\"max-w-[496px] px-6 paragraph-medium-medium text-zinc-950 sm:px-0\">\r\n {translate('common.notFound.description')}\r\n </p>\r\n\r\n <Button\r\n variant=\"secondary\"\r\n className=\"h-10!\"\r\n onClick={() => {\r\n if (window.history.length > 1) {\r\n router.back();\r\n } else {\r\n router.push('/');\r\n }\r\n }}\r\n >\r\n {translate('common.notFound.backToHome')}\r\n </Button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"mappings":";AAYI,SACE,KADF;AAVJ,OAAO,WAAW;AAClB,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,eAAe,8BAA8B;AACtD,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAE1B,SAAS,gBAAgB;AACvB,SACE,qBAAC,SAAI,OAAM,8BAA6B,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QACtF;AAAA,wBAAC,UAAK,GAAE,OAAM,GAAE,OAAM,OAAM,WAAU,QAAO,WAAU,IAAG,WAAU,MAAK,WAAU;AAAA,IACnF,oBAAC,UAAK,GAAE,OAAM,GAAE,OAAM,OAAM,WAAU,QAAO,WAAU,IAAG,WAAU,QAAO,SAAQ,aAAY,KAAI;AAAA,IACnG,oBAAC,UAAK,GAAE,m9BAAk9B,MAAK,SAAQ;AAAA,KACz+B;AAEJ;AAEO,SAAS,eAAe;AAC7B,QAAM,YAAY,gBAAgB;AAClC,QAAM,SAAS,UAAU;AAEzB,YAAU,MAAM;AACd,cAAU;AAAA,EACZ,GAAG,CAAC,CAAC;AACL,QAAM,EAAE,WAAW,IAAI,cAAc;AACrC,QAAM,cAAc,uBAAuB;AAC3C,QAAM,iBAAiB,YAAY,OAC/B,GAAG,QAAQ,IAAI,uBAAuB,IAAI,WAAW,IAAI,KACzD;AAEJ,SACE,oBAAC,SAAI,WAAU,mGACb,+BAAC,SAAI,WAAU,qDACb;AAAA,yBAAC,SAAI,WAAU,uCACb;AAAA,0BAAC,SAAM,KAAI,mBAAkB,KAAI,OAAM,OAAO,KAAK,QAAQ,KAAK,UAAQ,MAAC,aAAW,MAAC;AAAA,MAErF,oBAAC,SAAI,WAAU,yCAAwC;AAAA,MAEvD,oBAAC,SAAI,WAAU,cACZ,wBACC,oBAAC,iBAAc,IACb,iBACF,oBAAC,SAAM,KAAK,gBAAgB,KAAK,YAAY,QAAQ,IAAI,OAAO,IAAI,QAAQ,IAAI,WAAU,6BAA4B,IACpH,MACN;AAAA,OACF;AAAA,IAEA,oBAAC,QAAG,WAAU,4JACX,oBAAU,uBAAuB,GACpC;AAAA,IAEA,oBAAC,OAAE,WAAU,oEACV,oBAAU,6BAA6B,GAC1C;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,SAAS,MAAM;AACb,cAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,mBAAO,KAAK;AAAA,UACd,OAAO;AACL,mBAAO,KAAK,GAAG;AAAA,UACjB;AAAA,QACF;AAAA,QAEC,oBAAU,4BAA4B;AAAA;AAAA,IACzC;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -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 { 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
+ {"version":3,"sources":["../../../../src/components/pages/notifications/Notifications.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { IconBell, IconCheck, IconLoader2 } from '@tabler/icons-react';\r\nimport { useTranslations } from 'next-intl';\r\nimport { Button } from \"../../ui/buttons/Button\";\r\nimport {\r\n Tabs,\r\n TabsContent,\r\n TabsList,\r\n TabsTrigger,\r\n} from \"../../ui/data-display/Tabs\";\r\nimport { useInfiniteMessages, useMarkAllMessagesAsRead } from \"../../../modules/users/hooks/messages.hook\";\r\nimport NotificationCard from \"../../widgets/notifications/NotificationCard\";\r\nimport { Toast } from \"../../ui/feedback/Toast\";\r\nimport { formatDistanceToNow } from \"date-fns\";\r\nimport { ptBR } from \"date-fns/locale\";\r\nimport { toast } from \"sonner\";\r\nimport React from \"react\";\r\nimport Link from \"next/link\";\r\n\r\nfunction parseNotificationUrl(raw: string): string | null {\r\n if (!raw) return null;\r\n const match = raw.match(/href=\"([^\"]+)\"/);\r\n return match ? match[1] : raw.startsWith('/') ? raw : null;\r\n}\r\n\r\nfunction NotificationsList({\r\n pages,\r\n isFetchingNextPage,\r\n hasNextPage,\r\n fetchNextPage,\r\n}: {\r\n pages: ReturnType<typeof useInfiniteMessages>[\"data\"];\r\n isFetchingNextPage: boolean;\r\n hasNextPage: boolean;\r\n fetchNextPage: () => void;\r\n}) {\r\n const translate = useTranslations();\r\n const notifications = pages?.pages.flatMap((p) => p.data) ?? [];\r\n\r\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\r\n const target = e.currentTarget;\r\n const nearBottom =\r\n target.scrollTop + target.clientHeight >= target.scrollHeight - 50;\r\n if (!nearBottom) return;\r\n if (hasNextPage && !isFetchingNextPage) {\r\n fetchNextPage();\r\n }\r\n };\r\n\r\n if (notifications.length === 0 && !isFetchingNextPage) {\r\n return (\r\n <div className=\"rounded-lg border border-zinc-200 bg-white\">\r\n <div className=\"flex flex-col items-center justify-center py-16 gap-2\">\r\n <span className=\"paragraph-medium-regular text-zinc-500\">{translate('common.notifications.page.empty')}</span>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className=\"flex flex-col border border-gray-200 rounded-lg w-full bg-white max-h-[70vh] overflow-y-auto custom-scrollbar\"\r\n onScroll={handleScroll}\r\n >\r\n {notifications.map((notification, index) => {\r\n const detailsUrl = parseNotificationUrl(notification.url);\r\n return (\r\n <NotificationCard\r\n key={notification.id}\r\n icon={<IconBell size={20} className=\"text-pages-600\" />}\r\n iconBgColor=\"bg-zinc-50\"\r\n title={notification.subject}\r\n description={notification.message}\r\n gapPx={8}\r\n time={formatDistanceToNow(new Date(notification.datetime_add), {\r\n addSuffix: true,\r\n locale: ptBR,\r\n })}\r\n isUnread={notification.status === 1}\r\n showBorder={index < notifications.length - 1}\r\n actions={\r\n detailsUrl ? (\r\n <Button asChild variant=\"secondary\" className=\"h-8! px-3! paragraph-small-semibold\">\r\n <Link href={detailsUrl}>{translate('common.notifications.page.details')}</Link>\r\n </Button>\r\n ) : undefined\r\n }\r\n />\r\n );\r\n })}\r\n {isFetchingNextPage && (\r\n <div className=\"flex items-center justify-center py-4\">\r\n <IconLoader2 size={20} className=\"animate-spin text-gray-400\" />\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport function NotificationPageContent() {\r\n const translate = useTranslations();\r\n const unreadNotifications = useInfiniteMessages({\r\n readed: false,\r\n type: \"notification\",\r\n order: \"desc\",\r\n });\r\n const allNotifications = useInfiniteMessages({\r\n type: \"notification\",\r\n order: \"desc\",\r\n });\r\n\r\n const totalAll = allNotifications.data?.pages[0]?.total ?? 0;\r\n const totalUnread = unreadNotifications.data?.pages[0]?.total ?? 0;\r\n\r\n const { mutate: markAllAsRead, isPending: isMarkingAll } = useMarkAllMessagesAsRead();\r\n\r\n const handleMarkAllAsRead = () => {\r\n markAllAsRead(undefined, {\r\n onSuccess: () => {\r\n toast.custom((t) => (\r\n <Toast variant=\"success\" message={translate('common.notifications.page.markAllSuccess')} toastId={t} />\r\n ));\r\n },\r\n onError: () => {\r\n toast.custom((t) => (\r\n <Toast variant=\"error\" message={translate('common.notifications.page.markAllError')} toastId={t} />\r\n ));\r\n },\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"flex flex-col gap-6 lg:gap-8\">\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"flex flex-col gap-2\">\r\n <h1 className=\"title-large-semibold text-gray-950\">\r\n {translate('common.notifications.page.title')}\r\n </h1>\r\n <p className=\"paragraph-small-regular text-gray-600 hidden lg:block\">\r\n {translate('common.notifications.page.subtitle')}\r\n </p>\r\n </div>\r\n <Button\r\n variant={\"secondary\"}\r\n className=\"h-10! lg:h-12! shrink-0\"\r\n onClick={handleMarkAllAsRead}\r\n disabled={isMarkingAll || totalUnread === 0}\r\n >\r\n {isMarkingAll ? <IconLoader2 size={20} className=\"animate-spin\" /> : <IconCheck size={20} />}\r\n <span className=\"lg:block hidden\">{translate('common.notifications.page.markAllReadDesktop')}</span>\r\n <span className=\"lg:hidden\">{translate('common.notifications.page.markAllReadMobile')}</span>\r\n </Button>\r\n </div>\r\n <Tabs\r\n defaultValue=\"all\"\r\n className=\"flex flex-col w-full bg-transparent gap-6 lg:gap-8\"\r\n >\r\n <TabsList className=\"h-auto pb-0 bg-transparent\">\r\n <TabsTrigger className=\"gap-2\" value=\"all\">\r\n {translate('common.notifications.page.tabAll')}{\" \"}\r\n <span className=\"text-gray-500\">({totalAll})</span>\r\n </TabsTrigger>\r\n <TabsTrigger className=\"gap-2\" value=\"unreads\" disabled={totalUnread === 0}>\r\n {translate('common.notifications.page.tabUnread')}{\" \"}\r\n <span className=\"text-gray-500\">({totalUnread})</span>\r\n </TabsTrigger>\r\n </TabsList>\r\n\r\n <TabsContent value=\"all\">\r\n <NotificationsList\r\n pages={allNotifications.data}\r\n isFetchingNextPage={allNotifications.isFetchingNextPage}\r\n hasNextPage={allNotifications.hasNextPage}\r\n fetchNextPage={allNotifications.fetchNextPage}\r\n />\r\n </TabsContent>\r\n\r\n <TabsContent value=\"unreads\">\r\n <NotificationsList\r\n pages={unreadNotifications.data}\r\n isFetchingNextPage={unreadNotifications.isFetchingNextPage}\r\n hasNextPage={unreadNotifications.hasNextPage}\r\n fetchNextPage={unreadNotifications.fetchNextPage}\r\n />\r\n </TabsContent>\r\n </Tabs>\r\n </div>\r\n );\r\n}\r\n"],"mappings":"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","names":[]}