@greatapps/common 1.1.697 → 1.1.699

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 (557) 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.map +1 -1
  92. package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
  93. package/dist/components/widgets/ImageUpload/ImageUpload.mjs.map +1 -1
  94. package/dist/components/widgets/ImageUpload/index.mjs.map +1 -1
  95. package/dist/components/widgets/notifications/NotificationCard.mjs.map +1 -1
  96. package/dist/handlers.mjs.map +1 -1
  97. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
  98. package/dist/hooks/useAuthQueryKey.mjs.map +1 -1
  99. package/dist/hooks/useBrandLoadingIcon.mjs.map +1 -1
  100. package/dist/hooks/useRouter.mjs.map +1 -1
  101. package/dist/http.mjs.map +1 -1
  102. package/dist/i18n/config.mjs.map +1 -1
  103. package/dist/i18n/country-language.mjs.map +1 -1
  104. package/dist/i18n/messages/en-us.mjs.map +1 -1
  105. package/dist/i18n/messages/es-es.mjs.map +1 -1
  106. package/dist/i18n/messages/index.mjs.map +1 -1
  107. package/dist/i18n/messages/pt-br.mjs.map +1 -1
  108. package/dist/i18n/normalize.mjs.map +1 -1
  109. package/dist/i18n/resolve-locale.mjs.map +1 -1
  110. package/dist/i18n.mjs.map +1 -1
  111. package/dist/index.mjs.map +1 -1
  112. package/dist/infra/http/api-fetch.mjs.map +1 -1
  113. package/dist/infra/route/parse-id.mjs.map +1 -1
  114. package/dist/infra/route/parse-numeric.mjs.map +1 -1
  115. package/dist/infra/route/safe-route-handler.mjs.map +1 -1
  116. package/dist/infra/route/search-params.mjs.map +1 -1
  117. package/dist/infra/utils/array.mjs.map +1 -1
  118. package/dist/infra/utils/date.mjs.map +1 -1
  119. package/dist/middleware.mjs.map +1 -1
  120. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  121. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  122. package/dist/modules/accounts/actions/get-account-token.action.mjs.map +1 -1
  123. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  124. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  125. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  126. package/dist/modules/accounts/hooks/use-account-token.hook.mjs.map +1 -1
  127. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -1
  128. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  129. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  130. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  131. package/dist/modules/accounts/hooks/useViaCep.mjs.map +1 -1
  132. package/dist/modules/accounts/services/account-token.service.mjs.map +1 -1
  133. package/dist/modules/accounts/services/account.service.mjs.map +1 -1
  134. package/dist/modules/auth/actions/social-google-login.action.mjs.map +1 -1
  135. package/dist/modules/auth/actions/social-google-onboarding.action.mjs.map +1 -1
  136. package/dist/modules/auth/actions/unlink-google.action.mjs.map +1 -1
  137. package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -1
  138. package/dist/modules/auth/actions/verify-two-factor.action.mjs.map +1 -1
  139. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  140. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  141. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  142. package/dist/modules/auth/hooks/social-google-login.hook.mjs.map +1 -1
  143. package/dist/modules/auth/hooks/social-google-onboarding.hook.mjs.map +1 -1
  144. package/dist/modules/auth/hooks/unlink-google.hook.mjs.map +1 -1
  145. package/dist/modules/auth/hooks/useManagementPermissions.mjs.map +1 -1
  146. package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -1
  147. package/dist/modules/auth/utils/assert-management-permission.mjs.map +1 -1
  148. package/dist/modules/auth/utils/assert-management-subscription.mjs.map +1 -1
  149. package/dist/modules/auth/utils/assert-paid-subscription.mjs.map +1 -1
  150. package/dist/modules/auth/utils/assert-subscription-addon.mjs.map +1 -1
  151. package/dist/modules/auth/utils/build-wl-override.mjs.map +1 -1
  152. package/dist/modules/auth/utils/require-token-not-expired.mjs.map +1 -1
  153. package/dist/modules/auth/utils/require-valid-session.mjs.map +1 -1
  154. package/dist/modules/cards/actions/create-card.action.mjs.map +1 -1
  155. package/dist/modules/cards/actions/create-setup-intent.action.mjs.map +1 -1
  156. package/dist/modules/cards/actions/delete-card.action.mjs.map +1 -1
  157. package/dist/modules/cards/actions/set-default-card.action.mjs.map +1 -1
  158. package/dist/modules/cards/handlers/find-card-by-id.handler.mjs.map +1 -1
  159. package/dist/modules/cards/handlers/list-cards.handler.mjs.map +1 -1
  160. package/dist/modules/cards/hooks/card-by-id.hook.mjs.map +1 -1
  161. package/dist/modules/cards/hooks/cards.hook.mjs.map +1 -1
  162. package/dist/modules/cards/hooks/create-card.hook.mjs.map +1 -1
  163. package/dist/modules/cards/hooks/create-setup-intent.hook.mjs.map +1 -1
  164. package/dist/modules/cards/hooks/delete-card.hook.mjs.map +1 -1
  165. package/dist/modules/cards/hooks/delete-confirmation.hook.mjs.map +1 -1
  166. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
  167. package/dist/modules/cards/hooks/set-default-card.hook.mjs.map +1 -1
  168. package/dist/modules/cards/services/cards.service.mjs.map +1 -1
  169. package/dist/modules/cards/types.mjs.map +1 -1
  170. package/dist/modules/charges/actions/charge-action.action.mjs.map +1 -1
  171. package/dist/modules/charges/handlers/find-charge-by-id.handler.mjs.map +1 -1
  172. package/dist/modules/charges/handlers/list-charges.handler.mjs.map +1 -1
  173. package/dist/modules/charges/hooks/charge-action.hook.mjs.map +1 -1
  174. package/dist/modules/charges/hooks/charge-by-id.hook.mjs.map +1 -1
  175. package/dist/modules/charges/hooks/charges.hook.mjs.map +1 -1
  176. package/dist/modules/charges/services/charges.service.mjs.map +1 -1
  177. package/dist/modules/charges/types/charge.type.mjs.map +1 -1
  178. package/dist/modules/ia-credits/handlers/list-ia-credits.handler.mjs.map +1 -1
  179. package/dist/modules/ia-credits/hooks/ia-credits.hook.mjs.map +1 -1
  180. package/dist/modules/images/actions/process-image.action.mjs.map +1 -1
  181. package/dist/modules/images/constants/image.constants.mjs.map +1 -1
  182. package/dist/modules/images/hooks/use-image-upload.hook.mjs.map +1 -1
  183. package/dist/modules/images/services/image-processing.service.mjs.map +1 -1
  184. package/dist/modules/images/utils/base64.mjs.map +1 -1
  185. package/dist/modules/images/utils/compress-image.mjs.map +1 -1
  186. package/dist/modules/images/utils/crop-image.mjs.map +1 -1
  187. package/dist/modules/images/utils/validate-image.mjs.map +1 -1
  188. package/dist/modules/pages/constants/query-keys.constants.mjs.map +1 -1
  189. package/dist/modules/pages/handlers/count-pages.handler.mjs.map +1 -1
  190. package/dist/modules/pages/hooks/count-pages.hook.mjs.map +1 -1
  191. package/dist/modules/pages/services/pages.service.mjs.map +1 -1
  192. package/dist/modules/plans/handlers/find-plan-by-id.handler.mjs.map +1 -1
  193. package/dist/modules/plans/handlers/list-plans.handler.mjs.map +1 -1
  194. package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
  195. package/dist/modules/plans/hooks/use-has-plan-addon.hook.mjs.map +1 -1
  196. package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
  197. package/dist/modules/plans/services/plans.service.mjs +1 -1
  198. package/dist/modules/plans/services/plans.service.mjs.map +1 -1
  199. package/dist/modules/plans/types/plan.type.mjs +5 -1
  200. package/dist/modules/plans/types/plan.type.mjs.map +1 -1
  201. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
  202. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  203. package/dist/modules/projects/actions/create-project.action.mjs.map +1 -1
  204. package/dist/modules/projects/actions/delete-project.action.mjs.map +1 -1
  205. package/dist/modules/projects/actions/find-project.action.mjs.map +1 -1
  206. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  207. package/dist/modules/projects/actions/list-projects.action.mjs.map +1 -1
  208. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  209. package/dist/modules/projects/actions/update-project.action.mjs.map +1 -1
  210. package/dist/modules/projects/handlers/find-project.handler.mjs.map +1 -1
  211. package/dist/modules/projects/handlers/list-all-account-users.handler.mjs.map +1 -1
  212. package/dist/modules/projects/handlers/list-available-users.handler.mjs.map +1 -1
  213. package/dist/modules/projects/handlers/list-project-users.handler.mjs.map +1 -1
  214. package/dist/modules/projects/handlers/list-projects.handler.mjs.map +1 -1
  215. package/dist/modules/projects/hooks/add-project-user.hook.mjs.map +1 -1
  216. package/dist/modules/projects/hooks/create-project.hook.mjs.map +1 -1
  217. package/dist/modules/projects/hooks/delete-project.hook.mjs.map +1 -1
  218. package/dist/modules/projects/hooks/find-project.hook.mjs.map +1 -1
  219. package/dist/modules/projects/hooks/list-all-account-users.hook.mjs.map +1 -1
  220. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  221. package/dist/modules/projects/hooks/list-infinite-projects.hook.mjs.map +1 -1
  222. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  223. package/dist/modules/projects/hooks/list-projects.hook.mjs.map +1 -1
  224. package/dist/modules/projects/hooks/remove-project-user.hook.mjs.map +1 -1
  225. package/dist/modules/projects/hooks/update-project.hook.mjs.map +1 -1
  226. package/dist/modules/projects/services/project-users.service.mjs +2 -2
  227. package/dist/modules/projects/services/project-users.service.mjs.map +1 -1
  228. package/dist/modules/projects/services/projects.service.mjs.map +1 -1
  229. package/dist/modules/subscriptions/actions/calculate-subscription.action.mjs.map +1 -1
  230. package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
  231. package/dist/modules/subscriptions/actions/update-subscription-payment.action.mjs.map +1 -1
  232. package/dist/modules/subscriptions/actions/update-subscription-plan.action.mjs.map +1 -1
  233. package/dist/modules/subscriptions/constants/query-keys.constants.mjs.map +1 -1
  234. package/dist/modules/subscriptions/constants/subscription.constants.mjs.map +1 -1
  235. package/dist/modules/subscriptions/handlers/list-subscriptions.handler.mjs.map +1 -1
  236. package/dist/modules/subscriptions/hooks/calculate-subscription.hook.mjs.map +1 -1
  237. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  238. package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
  239. package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs.map +1 -1
  240. package/dist/modules/subscriptions/hooks/update-subscription-plan.hook.mjs.map +1 -1
  241. package/dist/modules/subscriptions/hooks/use-cancelled-subscription-guard.mjs.map +1 -1
  242. package/dist/modules/subscriptions/types/calculate-subscription.type.mjs.map +1 -1
  243. package/dist/modules/subscriptions/types/pix-pending.type.mjs.map +1 -1
  244. package/dist/modules/subscriptions/utils/build-plan-extras.mjs.map +1 -1
  245. package/dist/modules/subscriptions/utils/get-subscription-cancellation-state.mjs.map +1 -1
  246. package/dist/modules/subscriptions/utils/get-subscription-expiry-date.mjs.map +1 -1
  247. package/dist/modules/subscriptions/utils/has-subscription-expired.mjs.map +1 -1
  248. package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
  249. package/dist/modules/subscriptions/utils/resolve-plan-extras-prices.mjs.map +1 -1
  250. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
  251. package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
  252. package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
  253. package/dist/modules/users/handlers/list-messages.handler.mjs.map +1 -1
  254. package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
  255. package/dist/modules/users/services/messages.service.mjs.map +1 -1
  256. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
  257. package/dist/modules/whitelabel/actions/revalidate-whitelabel.action.mjs.map +1 -1
  258. package/dist/modules/whitelabel/utils/normalize-hostname.mjs.map +1 -1
  259. package/dist/providers/auth.provider.mjs.map +1 -1
  260. package/dist/providers/navigation.provider.mjs.map +1 -1
  261. package/dist/providers/whitelabel.provider.mjs.map +1 -1
  262. package/dist/route.mjs.map +1 -1
  263. package/dist/store/useAccountModals.mjs.map +1 -1
  264. package/dist/store/useBuyCreditsModal.mjs.map +1 -1
  265. package/dist/store/useCreditsDisabledModal.mjs.map +1 -1
  266. package/dist/store/useDesktopSidebarStore.mjs.map +1 -1
  267. package/dist/store/useMdSidebarStore.mjs.map +1 -1
  268. package/dist/store/usePaidPlanRequiredModal.mjs.map +1 -1
  269. package/dist/utils/constants/br-states.mjs.map +1 -1
  270. package/dist/utils/countries.mjs.map +1 -1
  271. package/dist/utils/format/currency.mjs.map +1 -1
  272. package/dist/utils/intl/cookie-domain.mjs.map +1 -1
  273. package/dist/utils/intl/locale-cookie.mjs.map +1 -1
  274. package/dist/utils/next-navigation.mjs.map +1 -1
  275. package/dist/utils/redirect.mjs.map +1 -1
  276. package/dist/utils/safeMutationAction.mjs.map +1 -1
  277. package/dist/utils/safeServerAction.mjs.map +1 -1
  278. package/dist/utils/withAction.mjs.map +1 -1
  279. package/package.json +115 -115
  280. package/src/components/account/ConfigurationsMyAccountModal.tsx +179 -179
  281. package/src/components/account/ConfirmDeleteAccountModal.tsx +110 -110
  282. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +68 -68
  283. package/src/components/account/DeleteAccountModal.tsx +160 -160
  284. package/src/components/account/DisableTwoFactorAuthModal.tsx +92 -92
  285. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +51 -51
  286. package/src/components/account/TwoFactorAuthModal.tsx +220 -220
  287. package/src/components/account/hooks/useChangePhoneForm.tsx +113 -113
  288. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +116 -116
  289. package/src/components/account/sections/ChangeEmailModal.tsx +239 -239
  290. package/src/components/account/sections/ChangePasswordSection.tsx +68 -68
  291. package/src/components/account/sections/ChangePhoneModal.tsx +273 -273
  292. package/src/components/account/sections/MyProfileSection.tsx +276 -276
  293. package/src/components/account/sections/PreferencesSection.tsx +278 -278
  294. package/src/components/account/sections/SecuritySection.tsx +102 -102
  295. package/src/components/account/sections/TokenSection.tsx +85 -85
  296. package/src/components/embeds/ClarityEmbed.tsx +70 -70
  297. package/src/components/embeds/CrispEmbed.tsx +195 -195
  298. package/src/components/embeds/EmbedWidgets.tsx +62 -62
  299. package/src/components/embeds/FrillEmbed.tsx +146 -146
  300. package/src/components/layouts/AppMobileNavBar.tsx +214 -214
  301. package/src/components/layouts/AppNavBar.tsx +40 -40
  302. package/src/components/layouts/MdSideBarNavigation.tsx +56 -56
  303. package/src/components/layouts/NavBar.tsx +228 -228
  304. package/src/components/layouts/NotificationsPopover.tsx +120 -120
  305. package/src/components/layouts/ProfilePopover.tsx +191 -191
  306. package/src/components/layouts/SideBarNavigation.tsx +65 -65
  307. package/src/components/layouts/UsersSelectorPopover.tsx +236 -236
  308. package/src/components/layouts/WhitelabelCodes.tsx +59 -59
  309. package/src/components/modals/BuyCreditsModal.tsx +390 -390
  310. package/src/components/modals/CreditsDisabledModal.tsx +62 -62
  311. package/src/components/modals/Modals.tsx +25 -25
  312. package/src/components/modals/PaidPlanRequiredModal.tsx +60 -60
  313. package/src/components/modals/cards/AddCardModal.tsx +420 -420
  314. package/src/components/modals/cards/CannotDeleteCardModal.tsx +124 -124
  315. package/src/components/modals/cards/CardFormFields.tsx +363 -363
  316. package/src/components/modals/cards/DeleteCardModal.tsx +136 -136
  317. package/src/components/navigation/CancelledSubscriptionBanner.tsx +62 -62
  318. package/src/components/navigation/NavItemsContext.ts +20 -20
  319. package/src/components/navigation/OverdueInvoiceBanner.tsx +51 -51
  320. package/src/components/navigation/PendingCancellationBanner.tsx +60 -60
  321. package/src/components/navigation/ProjectSelectorPopover.tsx +180 -180
  322. package/src/components/navigation/SubscriptionBanner.tsx +94 -94
  323. package/src/components/navigation/TrialBanner.tsx +54 -54
  324. package/src/components/navigation/UpcomingInvoiceBanner.tsx +55 -55
  325. package/src/components/navigation/shells/TabsMobileShell.tsx +74 -74
  326. package/src/components/navigation/subcomponents/BottomLinks.tsx +85 -85
  327. package/src/components/navigation/subcomponents/ProjectSelector.tsx +184 -184
  328. package/src/components/pages/NotFoundPage.tsx +75 -75
  329. package/src/components/pages/notifications/Notifications.tsx +190 -190
  330. package/src/components/ui/buttons/Button.tsx +77 -77
  331. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  332. package/src/components/ui/buttons/CopyButton.tsx +59 -59
  333. package/src/components/ui/data-display/Accordion.tsx +81 -81
  334. package/src/components/ui/data-display/Badge.tsx +47 -47
  335. package/src/components/ui/data-display/Card.tsx +93 -93
  336. package/src/components/ui/data-display/CardBrandIcons.tsx +336 -336
  337. package/src/components/ui/data-display/CardItem.tsx +135 -135
  338. package/src/components/ui/data-display/Pagination.tsx +126 -126
  339. package/src/components/ui/data-display/PaymentInfoCard.tsx +193 -193
  340. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  341. package/src/components/ui/data-display/Separator.tsx +29 -29
  342. package/src/components/ui/data-display/Table.tsx +117 -117
  343. package/src/components/ui/data-display/Tabs.tsx +67 -67
  344. package/src/components/ui/feedback/CircularProgress.tsx +79 -79
  345. package/src/components/ui/feedback/DefaultCircularProgress.tsx +67 -67
  346. package/src/components/ui/feedback/LoadingOverlay.tsx +30 -30
  347. package/src/components/ui/feedback/Progress.tsx +40 -40
  348. package/src/components/ui/feedback/Skeleton.tsx +5 -5
  349. package/src/components/ui/feedback/Toast.tsx +104 -104
  350. package/src/components/ui/form/Calendar.tsx +228 -228
  351. package/src/components/ui/form/Checkbox.tsx +31 -31
  352. package/src/components/ui/form/ComboboxField.tsx +159 -159
  353. package/src/components/ui/form/DatePicker.tsx +100 -100
  354. package/src/components/ui/form/DateRangePicker.tsx +111 -111
  355. package/src/components/ui/form/FormField.tsx +133 -133
  356. package/src/components/ui/form/Input.tsx +20 -20
  357. package/src/components/ui/form/InputOtp.tsx +80 -80
  358. package/src/components/ui/form/PhoneInput.tsx +210 -210
  359. package/src/components/ui/form/RadioGroup.tsx +45 -45
  360. package/src/components/ui/form/Select.tsx +200 -200
  361. package/src/components/ui/form/Switch.tsx +32 -32
  362. package/src/components/ui/form/Textarea.tsx +19 -19
  363. package/src/components/ui/overlay/Command.tsx +185 -185
  364. package/src/components/ui/overlay/Dialog.tsx +153 -153
  365. package/src/components/ui/overlay/Popover.tsx +49 -49
  366. package/src/components/ui/overlay/Sheet.tsx +170 -170
  367. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  368. package/src/components/widgets/ImageUpload/ImageCropModal.tsx +392 -392
  369. package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +62 -62
  370. package/src/components/widgets/ImageUpload/ImageUpload.tsx +131 -131
  371. package/src/components/widgets/ImageUpload/index.ts +3 -3
  372. package/src/components/widgets/notifications/NotificationCard.tsx +73 -73
  373. package/src/handlers.ts +22 -22
  374. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  375. package/src/hooks/useAuthQueryKey.ts +32 -32
  376. package/src/hooks/useBrandLoadingIcon.tsx +18 -18
  377. package/src/hooks/useRouter.ts +38 -38
  378. package/src/http.ts +1 -1
  379. package/src/i18n/config.ts +17 -17
  380. package/src/i18n/country-language.ts +60 -60
  381. package/src/i18n/messages/en-us.ts +519 -519
  382. package/src/i18n/messages/es-es.ts +520 -520
  383. package/src/i18n/messages/index.ts +24 -24
  384. package/src/i18n/messages/pt-br.ts +543 -543
  385. package/src/i18n/normalize.ts +15 -15
  386. package/src/i18n/resolve-locale.ts +77 -77
  387. package/src/i18n.ts +10 -10
  388. package/src/index.ts +584 -584
  389. package/src/infra/http/api-fetch.ts +39 -39
  390. package/src/infra/route/parse-id.ts +9 -9
  391. package/src/infra/route/parse-numeric.ts +16 -16
  392. package/src/infra/route/safe-route-handler.ts +16 -16
  393. package/src/infra/route/search-params.ts +9 -9
  394. package/src/infra/utils/array.ts +167 -167
  395. package/src/infra/utils/date.ts +59 -59
  396. package/src/middleware.ts +4 -4
  397. package/src/modules/accounts/actions/account-management.action.ts +109 -109
  398. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  399. package/src/modules/accounts/actions/get-account-token.action.ts +8 -8
  400. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  401. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  402. package/src/modules/accounts/hooks/current-account.hook.tsx +26 -26
  403. package/src/modules/accounts/hooks/use-account-token.hook.tsx +14 -14
  404. package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -32
  405. package/src/modules/accounts/hooks/useAccountManagement.ts +95 -95
  406. package/src/modules/accounts/hooks/useCurrencies.ts +18 -18
  407. package/src/modules/accounts/hooks/useTimezones.ts +18 -18
  408. package/src/modules/accounts/hooks/useViaCep.ts +25 -25
  409. package/src/modules/accounts/services/account-token.service.ts +52 -52
  410. package/src/modules/accounts/services/account.service.ts +243 -243
  411. package/src/modules/accounts/types.ts +230 -230
  412. package/src/modules/auth/actions/social-google-login.action.ts +12 -12
  413. package/src/modules/auth/actions/social-google-onboarding.action.ts +13 -13
  414. package/src/modules/auth/actions/unlink-google.action.ts +8 -8
  415. package/src/modules/auth/actions/validate-session.action.ts +70 -70
  416. package/src/modules/auth/actions/verify-two-factor.action.ts +19 -19
  417. package/src/modules/auth/hooks/login.hook.tsx +13 -13
  418. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  419. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  420. package/src/modules/auth/hooks/social-google-login.hook.tsx +13 -13
  421. package/src/modules/auth/hooks/social-google-onboarding.hook.tsx +13 -13
  422. package/src/modules/auth/hooks/unlink-google.hook.tsx +13 -13
  423. package/src/modules/auth/hooks/useManagementPermissions.ts +52 -52
  424. package/src/modules/auth/hooks/useUserQuery.ts +103 -103
  425. package/src/modules/auth/types/management-permission.type.ts +14 -14
  426. package/src/modules/auth/utils/assert-management-permission.ts +56 -56
  427. package/src/modules/auth/utils/assert-management-subscription.ts +38 -38
  428. package/src/modules/auth/utils/assert-paid-subscription.ts +47 -47
  429. package/src/modules/auth/utils/assert-subscription-addon.ts +42 -42
  430. package/src/modules/auth/utils/build-wl-override.ts +43 -43
  431. package/src/modules/auth/utils/require-token-not-expired.ts +53 -53
  432. package/src/modules/auth/utils/require-valid-session.ts +35 -35
  433. package/src/modules/cards/actions/create-card.action.ts +9 -9
  434. package/src/modules/cards/actions/create-setup-intent.action.ts +8 -8
  435. package/src/modules/cards/actions/delete-card.action.ts +8 -8
  436. package/src/modules/cards/actions/set-default-card.action.ts +8 -8
  437. package/src/modules/cards/handlers/find-card-by-id.handler.ts +15 -15
  438. package/src/modules/cards/handlers/list-cards.handler.ts +10 -10
  439. package/src/modules/cards/hooks/card-by-id.hook.ts +17 -17
  440. package/src/modules/cards/hooks/cards.hook.ts +22 -22
  441. package/src/modules/cards/hooks/create-card.hook.ts +30 -30
  442. package/src/modules/cards/hooks/create-setup-intent.hook.ts +11 -11
  443. package/src/modules/cards/hooks/delete-card.hook.ts +52 -52
  444. package/src/modules/cards/hooks/delete-confirmation.hook.ts +40 -40
  445. package/src/modules/cards/hooks/handle-delete-card.hook.ts +47 -47
  446. package/src/modules/cards/hooks/set-default-card.hook.ts +55 -55
  447. package/src/modules/cards/services/cards.service.ts +136 -136
  448. package/src/modules/cards/types.ts +52 -52
  449. package/src/modules/charges/actions/charge-action.action.ts +13 -13
  450. package/src/modules/charges/handlers/find-charge-by-id.handler.ts +14 -14
  451. package/src/modules/charges/handlers/list-charges.handler.ts +15 -15
  452. package/src/modules/charges/hooks/charge-action.hook.ts +24 -24
  453. package/src/modules/charges/hooks/charge-by-id.hook.ts +19 -19
  454. package/src/modules/charges/hooks/charges.hook.ts +19 -19
  455. package/src/modules/charges/services/charges.service.ts +63 -63
  456. package/src/modules/charges/types/charge.type.ts +68 -68
  457. package/src/modules/ia-credits/handlers/list-ia-credits.handler.ts +14 -14
  458. package/src/modules/ia-credits/hooks/ia-credits.hook.ts +103 -103
  459. package/src/modules/images/actions/process-image.action.ts +40 -40
  460. package/src/modules/images/constants/image.constants.ts +11 -11
  461. package/src/modules/images/hooks/use-image-upload.hook.ts +153 -153
  462. package/src/modules/images/services/image-processing.service.ts +75 -75
  463. package/src/modules/images/types/image.type.ts +54 -54
  464. package/src/modules/images/utils/base64.ts +26 -26
  465. package/src/modules/images/utils/compress-image.ts +20 -20
  466. package/src/modules/images/utils/crop-image.ts +68 -68
  467. package/src/modules/images/utils/validate-image.ts +86 -86
  468. package/src/modules/pages/constants/query-keys.constants.ts +1 -1
  469. package/src/modules/pages/handlers/count-pages.handler.ts +12 -12
  470. package/src/modules/pages/hooks/count-pages.hook.ts +21 -21
  471. package/src/modules/pages/services/pages.service.ts +27 -27
  472. package/src/modules/plans/handlers/find-plan-by-id.handler.ts +14 -14
  473. package/src/modules/plans/handlers/list-plans.handler.ts +22 -22
  474. package/src/modules/plans/hooks/list-plans.hook.ts +23 -23
  475. package/src/modules/plans/hooks/use-has-plan-addon.hook.ts +14 -14
  476. package/src/modules/plans/hooks/use-plan-by-id.hook.ts +39 -39
  477. package/src/modules/plans/services/plans.service.ts +136 -135
  478. package/src/modules/plans/types/plan.type.ts +79 -75
  479. package/src/modules/plans/utils/map-api-plan-to-ui.ts +167 -167
  480. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  481. package/src/modules/projects/actions/create-project.action.ts +9 -9
  482. package/src/modules/projects/actions/delete-project.action.ts +8 -8
  483. package/src/modules/projects/actions/find-project.action.ts +8 -8
  484. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  485. package/src/modules/projects/actions/list-projects.action.ts +16 -16
  486. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  487. package/src/modules/projects/actions/update-project.action.ts +9 -9
  488. package/src/modules/projects/handlers/find-project.handler.ts +15 -15
  489. package/src/modules/projects/handlers/list-all-account-users.handler.ts +23 -23
  490. package/src/modules/projects/handlers/list-available-users.handler.ts +26 -26
  491. package/src/modules/projects/handlers/list-project-users.handler.ts +26 -26
  492. package/src/modules/projects/handlers/list-projects.handler.ts +23 -23
  493. package/src/modules/projects/hooks/add-project-user.hook.ts +72 -72
  494. package/src/modules/projects/hooks/create-project.hook.ts +120 -120
  495. package/src/modules/projects/hooks/delete-project.hook.ts +58 -58
  496. package/src/modules/projects/hooks/find-project.hook.ts +18 -18
  497. package/src/modules/projects/hooks/list-all-account-users.hook.ts +40 -40
  498. package/src/modules/projects/hooks/list-available-users.hook.ts +39 -39
  499. package/src/modules/projects/hooks/list-infinite-projects.hook.ts +44 -44
  500. package/src/modules/projects/hooks/list-project-users.hook.ts +39 -39
  501. package/src/modules/projects/hooks/list-projects.hook.ts +23 -23
  502. package/src/modules/projects/hooks/remove-project-user.hook.ts +72 -72
  503. package/src/modules/projects/hooks/update-project.hook.ts +86 -86
  504. package/src/modules/projects/services/project-users.service.ts +3 -2
  505. package/src/modules/projects/services/projects.service.ts +156 -156
  506. package/src/modules/subscriptions/actions/calculate-subscription.action.ts +9 -9
  507. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  508. package/src/modules/subscriptions/actions/update-subscription-payment.action.ts +13 -13
  509. package/src/modules/subscriptions/actions/update-subscription-plan.action.ts +14 -14
  510. package/src/modules/subscriptions/constants/query-keys.constants.ts +3 -3
  511. package/src/modules/subscriptions/constants/subscription.constants.ts +1 -1
  512. package/src/modules/subscriptions/handlers/list-subscriptions.handler.ts +17 -17
  513. package/src/modules/subscriptions/hooks/calculate-subscription.hook.ts +13 -13
  514. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +22 -22
  515. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +22 -22
  516. package/src/modules/subscriptions/hooks/update-subscription-payment.hook.ts +25 -25
  517. package/src/modules/subscriptions/hooks/update-subscription-plan.hook.ts +28 -28
  518. package/src/modules/subscriptions/hooks/use-cancelled-subscription-guard.ts +44 -44
  519. package/src/modules/subscriptions/types/billing-period.type.ts +1 -1
  520. package/src/modules/subscriptions/types/calculate-subscription.type.ts +116 -116
  521. package/src/modules/subscriptions/types/pix-pending.type.ts +38 -38
  522. package/src/modules/subscriptions/utils/build-plan-extras.ts +56 -56
  523. package/src/modules/subscriptions/utils/get-subscription-cancellation-state.ts +37 -37
  524. package/src/modules/subscriptions/utils/get-subscription-expiry-date.ts +33 -33
  525. package/src/modules/subscriptions/utils/has-subscription-expired.ts +11 -11
  526. package/src/modules/subscriptions/utils/periodicity.ts +79 -79
  527. package/src/modules/subscriptions/utils/resolve-plan-extras-prices.ts +23 -23
  528. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  529. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  530. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  531. package/src/modules/users/handlers/list-messages.handler.ts +39 -39
  532. package/src/modules/users/hooks/messages.hook.ts +69 -69
  533. package/src/modules/users/services/messages.service.ts +49 -49
  534. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  535. package/src/modules/whitelabel/actions/revalidate-whitelabel.action.ts +19 -19
  536. package/src/modules/whitelabel/schema.ts +84 -84
  537. package/src/modules/whitelabel/utils/normalize-hostname.ts +26 -26
  538. package/src/providers/auth.provider.tsx +264 -264
  539. package/src/providers/navigation.provider.tsx +99 -99
  540. package/src/providers/whitelabel.provider.tsx +90 -90
  541. package/src/route.ts +4 -4
  542. package/src/store/useAccountModals.ts +85 -85
  543. package/src/store/useBuyCreditsModal.ts +21 -21
  544. package/src/store/useCreditsDisabledModal.ts +11 -11
  545. package/src/store/useDesktopSidebarStore.ts +47 -47
  546. package/src/store/useMdSidebarStore.ts +34 -34
  547. package/src/store/usePaidPlanRequiredModal.ts +19 -19
  548. package/src/utils/constants/br-states.ts +29 -29
  549. package/src/utils/countries.ts +224 -224
  550. package/src/utils/format/currency.ts +70 -70
  551. package/src/utils/intl/cookie-domain.ts +29 -29
  552. package/src/utils/intl/locale-cookie.ts +18 -18
  553. package/src/utils/next-navigation.ts +7 -7
  554. package/src/utils/redirect.ts +78 -78
  555. package/src/utils/safeMutationAction.ts +24 -24
  556. package/src/utils/safeServerAction.ts +21 -21
  557. package/src/utils/withAction.ts +13 -13
@@ -1,390 +1,390 @@
1
- 'use client';
2
-
3
- import {
4
- Dialog,
5
- DialogContent,
6
- DialogHeader,
7
- DialogTitle,
8
- } from '../ui/overlay/Dialog';
9
- import { Button } from '../ui/buttons/Button';
10
- import { Separator } from '../ui/data-display/Separator';
11
- import { Toast } from '../ui/feedback/Toast';
12
- import { SelectField } from '../ui/form/SelectField';
13
- import { Skeleton } from '../ui/feedback/Skeleton';
14
- import { PaymentInfoCard } from '../ui/data-display/PaymentInfoCard';
15
- import { ADDON_IDS } from '../../modules/subscriptions/constants/addons.constants';
16
- import {
17
- AI_CREDIT_OPTIONS,
18
- AI_CREDIT_VALUES,
19
- } from '../../modules/subscriptions/constants/addons.constants';
20
- import { useBuyCreditsModal } from '../../store/useBuyCreditsModal';
21
- import { useModalManager } from '../../store/useModalManager';
22
- import { useCards } from '../../modules/cards/hooks/cards.hook';
23
- import { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';
24
- import { useCalculateSubscription } from '../../modules/subscriptions/hooks/calculate-subscription.hook';
25
- import { useUpdateSubscriptionPlan } from '../../modules/subscriptions/hooks/update-subscription-plan.hook';
26
- import { getPriceFromCalculatedData } from '../../modules/subscriptions/utils/periodicity';
27
- import { useIsDefaultWhitelabel, useExternalContracting } from '../../providers/whitelabel.provider';
28
- import { IconInfoCircle, IconX, IconLoader2, IconSparkles } from '@tabler/icons-react';
29
- import { useTranslations } from 'next-intl';
30
- import { useCallback, useEffect, useMemo, useRef } from 'react';
31
- import { useForm } from 'react-hook-form';
32
- import { zodResolver } from '@hookform/resolvers/zod';
33
- import z from 'zod';
34
- import { toast } from 'sonner';
35
-
36
- const buyCreditSchema = z.object({
37
- creditOption: z.number().refine((val) => AI_CREDIT_VALUES.has(val), {
38
- message: 'Selecione uma opção de créditos',
39
- }),
40
- selectedCardId: z.string().min(1, 'Selecione um cartão'),
41
- });
42
-
43
- type BuyCreditFormData = z.infer<typeof buyCreditSchema>;
44
-
45
- export default function BuyCreditsModal() {
46
- const translate = useTranslations();
47
- const { open, closeModal } = useBuyCreditsModal();
48
- const { openModal } = useModalManager();
49
- const isDefaultWl = useIsDefaultWhitelabel();
50
- const { isExternalContracting, redirectToExternal } = useExternalContracting();
51
- const { data: cardsData } = useCards();
52
- const { data: subscriptionData } = useActiveSubscription();
53
- const subscription = subscriptionData?.data?.[0] ?? null;
54
- const defaultCardId =
55
- cardsData?.data?.find((card) => card.is_default)?.id?.toString() ??
56
- cardsData?.data?.[0]?.id?.toString() ??
57
- '';
58
-
59
- const {
60
- mutate: calculate,
61
- isPending: isCalculatePending,
62
- data: calculateData,
63
- } = useCalculateSubscription();
64
- const updatePlanMutation = useUpdateSubscriptionPlan();
65
-
66
- const aiItem = useMemo(
67
- () => subscription?.items?.find((item) => item.id_addon === ADDON_IDS.AI),
68
- [subscription]
69
- );
70
-
71
- const currentCredits = aiItem?.quantity ?? 0;
72
- const subscriptionId = subscription?.id;
73
- const planId = subscription?.id_plan;
74
-
75
- const form = useForm<BuyCreditFormData>({
76
- resolver: zodResolver(buyCreditSchema),
77
- mode: 'onChange',
78
- defaultValues: {
79
- creditOption: currentCredits,
80
- selectedCardId: defaultCardId,
81
- },
82
- });
83
-
84
- const hasInitialized = useRef(false);
85
-
86
- useEffect(() => {
87
- if (!open) {
88
- hasInitialized.current = false;
89
- return;
90
- }
91
-
92
- if (hasInitialized.current || !subscription) return;
93
- hasInitialized.current = true;
94
-
95
- form.reset({
96
- creditOption: currentCredits,
97
- selectedCardId: defaultCardId,
98
- });
99
-
100
- calculate({
101
- id_product: 1,
102
- ...(planId != null && { id_plan: planId }),
103
- ...(subscriptionId != null && { id_subscription: subscriptionId }),
104
- plan_extras: [
105
- { id_addon: ADDON_IDS.AI, quantity: currentCredits },
106
- ],
107
- });
108
- }, [
109
- open,
110
- subscription,
111
- currentCredits,
112
- defaultCardId,
113
- form,
114
- calculate,
115
- planId,
116
- subscriptionId,
117
- ]);
118
-
119
- // Sync selectedCardId when cards load after modal opened
120
- useEffect(() => {
121
- if (open && defaultCardId && !form.getValues('selectedCardId')) {
122
- form.setValue('selectedCardId', defaultCardId, { shouldValidate: true });
123
- }
124
- }, [open, defaultCardId, form]);
125
-
126
- const creditOption = form.watch('creditOption');
127
- const selectedCardId = form.watch('selectedCardId');
128
- const { isDirty, isSubmitting, isValid } = form.formState;
129
-
130
-
131
- const handleCreditOptionChange = useCallback(
132
- (value: string | number | boolean) => {
133
- const credits = Number(value);
134
-
135
- form.setValue('creditOption', credits, {
136
- shouldValidate: true,
137
- shouldDirty: true,
138
- });
139
-
140
- const option = AI_CREDIT_OPTIONS.find((opt) => opt.credits === credits);
141
- if (!option) return;
142
-
143
- calculate({
144
- id_product: 1,
145
- ...(planId != null && { id_plan: planId }),
146
- ...(subscriptionId != null && { id_subscription: subscriptionId }),
147
- plan_extras: [
148
- { id_addon: ADDON_IDS.AI, quantity: option.credits, currency: 'BRL' },
149
- ],
150
- });
151
- },
152
- [form, subscriptionId, planId, calculate]
153
- );
154
-
155
- const calculatedData = calculateData?.data ?? null;
156
-
157
- const isIncreasingCredits = creditOption > currentCredits;
158
- const hasChanged = creditOption !== currentCredits;
159
-
160
- const immediateChargeTotal = calculatedData?.target?.immediate_charge?.total ?? null;
161
-
162
- const totalPrice = useMemo(() => {
163
- if (!calculatedData) return null;
164
- return getPriceFromCalculatedData(calculatedData, subscription?.periodicity);
165
- }, [calculatedData, subscription]);
166
-
167
- const formatPrice = useCallback((price: number) => {
168
- return price.toLocaleString('pt-BR', {
169
- style: 'currency',
170
- currency: 'BRL',
171
- });
172
- }, []);
173
-
174
- const isConfirmDisabled = !isDirty || !isValid || isCalculatePending || isSubmitting;
175
-
176
- const handleClose = useCallback(() => {
177
- form.reset();
178
- closeModal();
179
- }, [form, closeModal]);
180
-
181
- const handleOpenAddCardModal = useCallback(() => {
182
- openModal('addCardModal');
183
- }, [openModal]);
184
-
185
- const selectOptions = useMemo(() => {
186
- return AI_CREDIT_OPTIONS.map((opt) => ({
187
- value: opt.credits,
188
- label: (
189
- <div className="flex items-center justify-between gap-2 w-full">
190
- <span className="paragraph-small-medium text-zinc-950 flex-1">
191
- {translate('common.credits.buy.creditsOptionLabel', { credits: opt.credits.toLocaleString('pt-BR') })}
192
- </span>
193
- <span className="paragraph-small-medium text-zinc-500 opacity-70">{opt.priceLabel}</span>
194
- </div>
195
- ),
196
- displayValue: translate('common.credits.buy.creditsOptionDisplayValue', { credits: opt.credits.toLocaleString('pt-BR') }),
197
- }));
198
- }, [translate]);
199
-
200
- const onSubmit = useCallback(
201
- async (data: BuyCreditFormData) => {
202
- if (!subscriptionId) return;
203
-
204
- const option = AI_CREDIT_OPTIONS.find((opt) => opt.credits === data.creditOption);
205
- if (!option) return;
206
-
207
- await updatePlanMutation.mutateAsync({
208
- subscriptionId,
209
- data: {
210
- plan_extras: [
211
- {
212
- id_addon: ADDON_IDS.AI,
213
- quantity: option.credits,
214
- },
215
- ],
216
- },
217
- });
218
-
219
- toast.custom((t) => (
220
- <Toast
221
- variant="success"
222
- message={translate('common.credits.buy.creditsChangedToast', { credits: data.creditOption.toLocaleString('pt-BR') })}
223
- toastId={t}
224
- />
225
- ));
226
- form.reset();
227
- closeModal();
228
- },
229
- [subscriptionId, updatePlanMutation, form, closeModal]
230
- );
231
-
232
- const renderPriceDisplay = useCallback(() => {
233
- if (isCalculatePending) {
234
- return <Skeleton className="h-7 w-24" />;
235
- }
236
- if (totalPrice !== null) {
237
- return (
238
- <span className="paragraph-xlarge-semibold text-zinc-950">
239
- {totalPrice === 0 ? translate('common.credits.buy.defaultPrice') : formatPrice(totalPrice)}
240
- </span>
241
- );
242
- }
243
- return <span className="paragraph-xlarge-semibold text-zinc-400">--</span>;
244
- }, [isCalculatePending, totalPrice, formatPrice]);
245
-
246
- if (isExternalContracting) {
247
- return (
248
- <Dialog open={open} onOpenChange={handleClose}>
249
- <DialogContent className="flex flex-col p-0 gap-0 w-full md:w-[410px] lg:w-[410px]">
250
- <DialogHeader className="gap-3 text-left p-5">
251
- <div className="flex items-center justify-center w-10 h-10 bg-zinc-50 rounded-lg">
252
- <IconSparkles size={24} className="text-zinc-950" />
253
- </div>
254
- <div className="flex flex-col gap-2">
255
- <DialogTitle className="paragraph-medium-semibold text-zinc-950">
256
- {translate('common.credits.buy.externalTitle')}
257
- </DialogTitle>
258
- <span className="paragraph-small-regular text-zinc-600">
259
- {translate('common.credits.buy.externalDescription')}
260
- </span>
261
- </div>
262
- </DialogHeader>
263
- <div className="flex items-center gap-2 p-5 border-t border-zinc-200">
264
- <Button
265
- className="w-fit h-10!"
266
- onClick={() => {
267
- closeModal();
268
- redirectToExternal('contracting');
269
- }}
270
- >
271
- {translate('common.credits.buy.externalButton')}
272
- </Button>
273
- </div>
274
- </DialogContent>
275
- </Dialog>
276
- );
277
- }
278
-
279
- return (
280
- <Dialog open={open} onOpenChange={handleClose}>
281
- <DialogContent
282
- showCloseButton={false}
283
- className="flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[433px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%] overflow-hidden lg:overflow-y-auto"
284
- >
285
- <DialogHeader className="px-4 py-3 border-b border-zinc-200 shrink-0 relative">
286
- <DialogTitle className="paragraph-medium-semibold text-zinc-950 text-center">
287
- {translate('common.credits.buy.title')}
288
- </DialogTitle>
289
- <button
290
- type="button"
291
- onClick={handleClose}
292
- className="absolute right-3 top-1/2 -translate-y-1/2 size-8 flex items-center justify-center rounded-lg cursor-pointer hover:bg-zinc-100 transition-colors"
293
- >
294
- <IconX size={18} className="text-zinc-400" />
295
- </button>
296
- </DialogHeader>
297
-
298
- <form
299
- onSubmit={form.handleSubmit(onSubmit)}
300
- className="flex flex-col flex-1 lg:flex-none overflow-hidden"
301
- >
302
- <div className="flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none overflow-y-auto">
303
- <div className="flex flex-col gap-4">
304
- <SelectField
305
- options={selectOptions}
306
- value={creditOption}
307
- onChange={handleCreditOptionChange}
308
- className="h-12!"
309
- />
310
-
311
- <PaymentInfoCard
312
- selectedCardId={selectedCardId}
313
- onCardSelect={(cardId) =>
314
- form.setValue('selectedCardId', cardId, { shouldValidate: true })
315
- }
316
- onOpenAddCard={handleOpenAddCardModal}
317
- />
318
-
319
- {hasChanged && (
320
- <div className={`flex items-center gap-3 p-4 rounded-lg ${isDefaultWl ? 'bg-cyan-50' : 'bg-zinc-50'}`}>
321
- <IconInfoCircle className="size-4 text-zinc-950 shrink-0" />
322
- <span className="paragraph-small-regular text-zinc-950">
323
- {isIncreasingCredits
324
- ? translate('common.credits.buy.paymentOnConfirm')
325
- : translate('common.credits.buy.nextInvoiceChanges')}
326
- </span>
327
- </div>
328
- )}
329
- </div>
330
-
331
- <Separator className="bg-zinc-200 hidden lg:block" />
332
-
333
- <div className="hidden lg:flex flex-col gap-2">
334
- {immediateChargeTotal !== null && immediateChargeTotal > 0 && (
335
- <div className="flex items-center justify-between">
336
- <span className="paragraph-xsmall-medium text-zinc-500">{translate('common.credits.buy.immediateCharge')}</span>
337
- {isCalculatePending ? (
338
- <Skeleton className="h-5 w-20" />
339
- ) : (
340
- <span className="paragraph-small-semibold text-zinc-950">
341
- {formatPrice(immediateChargeTotal)}
342
- </span>
343
- )}
344
- </div>
345
- )}
346
- <div className="flex items-center justify-between">
347
- <span className="paragraph-small-medium text-zinc-500">{translate('common.credits.buy.totalPlanValue')}</span>
348
- {renderPriceDisplay()}
349
- </div>
350
- </div>
351
-
352
- <Button
353
- type="submit"
354
- disabled={isConfirmDisabled}
355
- className="w-full hidden lg:inline-flex"
356
- >
357
- {isSubmitting && <IconLoader2 className="size-4 animate-spin" />}
358
- {translate('common.credits.buy.confirmAndPay')}
359
- </Button>
360
- </div>
361
-
362
- <div className="flex flex-col gap-4 p-4 border-t border-zinc-200 shrink-0 lg:hidden">
363
- <div className="flex flex-col gap-2">
364
- {immediateChargeTotal !== null && immediateChargeTotal > 0 && (
365
- <div className="flex items-center justify-between">
366
- <span className="paragraph-xsmall-medium text-zinc-500">{translate('common.credits.buy.immediateCharge')}</span>
367
- {isCalculatePending ? (
368
- <Skeleton className="h-5 w-20" />
369
- ) : (
370
- <span className="paragraph-small-semibold text-zinc-950">
371
- {formatPrice(immediateChargeTotal)}
372
- </span>
373
- )}
374
- </div>
375
- )}
376
- <div className="flex items-center justify-between">
377
- <span className="paragraph-small-medium text-zinc-500">{translate('common.credits.buy.totalPlanValue')}</span>
378
- {renderPriceDisplay()}
379
- </div>
380
- </div>
381
- <Button type="submit" disabled={isConfirmDisabled} className="w-full">
382
- {isSubmitting && <IconLoader2 className="size-4 animate-spin" />}
383
- {translate('common.credits.buy.confirmAndPay')}
384
- </Button>
385
- </div>
386
- </form>
387
- </DialogContent>
388
- </Dialog>
389
- );
390
- }
1
+ 'use client';
2
+
3
+ import {
4
+ Dialog,
5
+ DialogContent,
6
+ DialogHeader,
7
+ DialogTitle,
8
+ } from '../ui/overlay/Dialog';
9
+ import { Button } from '../ui/buttons/Button';
10
+ import { Separator } from '../ui/data-display/Separator';
11
+ import { Toast } from '../ui/feedback/Toast';
12
+ import { SelectField } from '../ui/form/SelectField';
13
+ import { Skeleton } from '../ui/feedback/Skeleton';
14
+ import { PaymentInfoCard } from '../ui/data-display/PaymentInfoCard';
15
+ import { ADDON_IDS } from '../../modules/subscriptions/constants/addons.constants';
16
+ import {
17
+ AI_CREDIT_OPTIONS,
18
+ AI_CREDIT_VALUES,
19
+ } from '../../modules/subscriptions/constants/addons.constants';
20
+ import { useBuyCreditsModal } from '../../store/useBuyCreditsModal';
21
+ import { useModalManager } from '../../store/useModalManager';
22
+ import { useCards } from '../../modules/cards/hooks/cards.hook';
23
+ import { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';
24
+ import { useCalculateSubscription } from '../../modules/subscriptions/hooks/calculate-subscription.hook';
25
+ import { useUpdateSubscriptionPlan } from '../../modules/subscriptions/hooks/update-subscription-plan.hook';
26
+ import { getPriceFromCalculatedData } from '../../modules/subscriptions/utils/periodicity';
27
+ import { useIsDefaultWhitelabel, useExternalContracting } from '../../providers/whitelabel.provider';
28
+ import { IconInfoCircle, IconX, IconLoader2, IconSparkles } from '@tabler/icons-react';
29
+ import { useTranslations } from 'next-intl';
30
+ import { useCallback, useEffect, useMemo, useRef } from 'react';
31
+ import { useForm } from 'react-hook-form';
32
+ import { zodResolver } from '@hookform/resolvers/zod';
33
+ import z from 'zod';
34
+ import { toast } from 'sonner';
35
+
36
+ const buyCreditSchema = z.object({
37
+ creditOption: z.number().refine((val) => AI_CREDIT_VALUES.has(val), {
38
+ message: 'Selecione uma opção de créditos',
39
+ }),
40
+ selectedCardId: z.string().min(1, 'Selecione um cartão'),
41
+ });
42
+
43
+ type BuyCreditFormData = z.infer<typeof buyCreditSchema>;
44
+
45
+ export default function BuyCreditsModal() {
46
+ const translate = useTranslations();
47
+ const { open, closeModal } = useBuyCreditsModal();
48
+ const { openModal } = useModalManager();
49
+ const isDefaultWl = useIsDefaultWhitelabel();
50
+ const { isExternalContracting, redirectToExternal } = useExternalContracting();
51
+ const { data: cardsData } = useCards();
52
+ const { data: subscriptionData } = useActiveSubscription();
53
+ const subscription = subscriptionData?.data?.[0] ?? null;
54
+ const defaultCardId =
55
+ cardsData?.data?.find((card) => card.is_default)?.id?.toString() ??
56
+ cardsData?.data?.[0]?.id?.toString() ??
57
+ '';
58
+
59
+ const {
60
+ mutate: calculate,
61
+ isPending: isCalculatePending,
62
+ data: calculateData,
63
+ } = useCalculateSubscription();
64
+ const updatePlanMutation = useUpdateSubscriptionPlan();
65
+
66
+ const aiItem = useMemo(
67
+ () => subscription?.items?.find((item) => item.id_addon === ADDON_IDS.AI),
68
+ [subscription]
69
+ );
70
+
71
+ const currentCredits = aiItem?.quantity ?? 0;
72
+ const subscriptionId = subscription?.id;
73
+ const planId = subscription?.id_plan;
74
+
75
+ const form = useForm<BuyCreditFormData>({
76
+ resolver: zodResolver(buyCreditSchema),
77
+ mode: 'onChange',
78
+ defaultValues: {
79
+ creditOption: currentCredits,
80
+ selectedCardId: defaultCardId,
81
+ },
82
+ });
83
+
84
+ const hasInitialized = useRef(false);
85
+
86
+ useEffect(() => {
87
+ if (!open) {
88
+ hasInitialized.current = false;
89
+ return;
90
+ }
91
+
92
+ if (hasInitialized.current || !subscription) return;
93
+ hasInitialized.current = true;
94
+
95
+ form.reset({
96
+ creditOption: currentCredits,
97
+ selectedCardId: defaultCardId,
98
+ });
99
+
100
+ calculate({
101
+ id_product: 1,
102
+ ...(planId != null && { id_plan: planId }),
103
+ ...(subscriptionId != null && { id_subscription: subscriptionId }),
104
+ plan_extras: [
105
+ { id_addon: ADDON_IDS.AI, quantity: currentCredits },
106
+ ],
107
+ });
108
+ }, [
109
+ open,
110
+ subscription,
111
+ currentCredits,
112
+ defaultCardId,
113
+ form,
114
+ calculate,
115
+ planId,
116
+ subscriptionId,
117
+ ]);
118
+
119
+ // Sync selectedCardId when cards load after modal opened
120
+ useEffect(() => {
121
+ if (open && defaultCardId && !form.getValues('selectedCardId')) {
122
+ form.setValue('selectedCardId', defaultCardId, { shouldValidate: true });
123
+ }
124
+ }, [open, defaultCardId, form]);
125
+
126
+ const creditOption = form.watch('creditOption');
127
+ const selectedCardId = form.watch('selectedCardId');
128
+ const { isDirty, isSubmitting, isValid } = form.formState;
129
+
130
+
131
+ const handleCreditOptionChange = useCallback(
132
+ (value: string | number | boolean) => {
133
+ const credits = Number(value);
134
+
135
+ form.setValue('creditOption', credits, {
136
+ shouldValidate: true,
137
+ shouldDirty: true,
138
+ });
139
+
140
+ const option = AI_CREDIT_OPTIONS.find((opt) => opt.credits === credits);
141
+ if (!option) return;
142
+
143
+ calculate({
144
+ id_product: 1,
145
+ ...(planId != null && { id_plan: planId }),
146
+ ...(subscriptionId != null && { id_subscription: subscriptionId }),
147
+ plan_extras: [
148
+ { id_addon: ADDON_IDS.AI, quantity: option.credits, currency: 'BRL' },
149
+ ],
150
+ });
151
+ },
152
+ [form, subscriptionId, planId, calculate]
153
+ );
154
+
155
+ const calculatedData = calculateData?.data ?? null;
156
+
157
+ const isIncreasingCredits = creditOption > currentCredits;
158
+ const hasChanged = creditOption !== currentCredits;
159
+
160
+ const immediateChargeTotal = calculatedData?.target?.immediate_charge?.total ?? null;
161
+
162
+ const totalPrice = useMemo(() => {
163
+ if (!calculatedData) return null;
164
+ return getPriceFromCalculatedData(calculatedData, subscription?.periodicity);
165
+ }, [calculatedData, subscription]);
166
+
167
+ const formatPrice = useCallback((price: number) => {
168
+ return price.toLocaleString('pt-BR', {
169
+ style: 'currency',
170
+ currency: 'BRL',
171
+ });
172
+ }, []);
173
+
174
+ const isConfirmDisabled = !isDirty || !isValid || isCalculatePending || isSubmitting;
175
+
176
+ const handleClose = useCallback(() => {
177
+ form.reset();
178
+ closeModal();
179
+ }, [form, closeModal]);
180
+
181
+ const handleOpenAddCardModal = useCallback(() => {
182
+ openModal('addCardModal');
183
+ }, [openModal]);
184
+
185
+ const selectOptions = useMemo(() => {
186
+ return AI_CREDIT_OPTIONS.map((opt) => ({
187
+ value: opt.credits,
188
+ label: (
189
+ <div className="flex items-center justify-between gap-2 w-full">
190
+ <span className="paragraph-small-medium text-zinc-950 flex-1">
191
+ {translate('common.credits.buy.creditsOptionLabel', { credits: opt.credits.toLocaleString('pt-BR') })}
192
+ </span>
193
+ <span className="paragraph-small-medium text-zinc-500 opacity-70">{opt.priceLabel}</span>
194
+ </div>
195
+ ),
196
+ displayValue: translate('common.credits.buy.creditsOptionDisplayValue', { credits: opt.credits.toLocaleString('pt-BR') }),
197
+ }));
198
+ }, [translate]);
199
+
200
+ const onSubmit = useCallback(
201
+ async (data: BuyCreditFormData) => {
202
+ if (!subscriptionId) return;
203
+
204
+ const option = AI_CREDIT_OPTIONS.find((opt) => opt.credits === data.creditOption);
205
+ if (!option) return;
206
+
207
+ await updatePlanMutation.mutateAsync({
208
+ subscriptionId,
209
+ data: {
210
+ plan_extras: [
211
+ {
212
+ id_addon: ADDON_IDS.AI,
213
+ quantity: option.credits,
214
+ },
215
+ ],
216
+ },
217
+ });
218
+
219
+ toast.custom((t) => (
220
+ <Toast
221
+ variant="success"
222
+ message={translate('common.credits.buy.creditsChangedToast', { credits: data.creditOption.toLocaleString('pt-BR') })}
223
+ toastId={t}
224
+ />
225
+ ));
226
+ form.reset();
227
+ closeModal();
228
+ },
229
+ [subscriptionId, updatePlanMutation, form, closeModal]
230
+ );
231
+
232
+ const renderPriceDisplay = useCallback(() => {
233
+ if (isCalculatePending) {
234
+ return <Skeleton className="h-7 w-24" />;
235
+ }
236
+ if (totalPrice !== null) {
237
+ return (
238
+ <span className="paragraph-xlarge-semibold text-zinc-950">
239
+ {totalPrice === 0 ? translate('common.credits.buy.defaultPrice') : formatPrice(totalPrice)}
240
+ </span>
241
+ );
242
+ }
243
+ return <span className="paragraph-xlarge-semibold text-zinc-400">--</span>;
244
+ }, [isCalculatePending, totalPrice, formatPrice]);
245
+
246
+ if (isExternalContracting) {
247
+ return (
248
+ <Dialog open={open} onOpenChange={handleClose}>
249
+ <DialogContent className="flex flex-col p-0 gap-0 w-full md:w-[410px] lg:w-[410px]">
250
+ <DialogHeader className="gap-3 text-left p-5">
251
+ <div className="flex items-center justify-center w-10 h-10 bg-zinc-50 rounded-lg">
252
+ <IconSparkles size={24} className="text-zinc-950" />
253
+ </div>
254
+ <div className="flex flex-col gap-2">
255
+ <DialogTitle className="paragraph-medium-semibold text-zinc-950">
256
+ {translate('common.credits.buy.externalTitle')}
257
+ </DialogTitle>
258
+ <span className="paragraph-small-regular text-zinc-600">
259
+ {translate('common.credits.buy.externalDescription')}
260
+ </span>
261
+ </div>
262
+ </DialogHeader>
263
+ <div className="flex items-center gap-2 p-5 border-t border-zinc-200">
264
+ <Button
265
+ className="w-fit h-10!"
266
+ onClick={() => {
267
+ closeModal();
268
+ redirectToExternal('contracting');
269
+ }}
270
+ >
271
+ {translate('common.credits.buy.externalButton')}
272
+ </Button>
273
+ </div>
274
+ </DialogContent>
275
+ </Dialog>
276
+ );
277
+ }
278
+
279
+ return (
280
+ <Dialog open={open} onOpenChange={handleClose}>
281
+ <DialogContent
282
+ showCloseButton={false}
283
+ className="flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[433px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%] overflow-hidden lg:overflow-y-auto"
284
+ >
285
+ <DialogHeader className="px-4 py-3 border-b border-zinc-200 shrink-0 relative">
286
+ <DialogTitle className="paragraph-medium-semibold text-zinc-950 text-center">
287
+ {translate('common.credits.buy.title')}
288
+ </DialogTitle>
289
+ <button
290
+ type="button"
291
+ onClick={handleClose}
292
+ className="absolute right-3 top-1/2 -translate-y-1/2 size-8 flex items-center justify-center rounded-lg cursor-pointer hover:bg-zinc-100 transition-colors"
293
+ >
294
+ <IconX size={18} className="text-zinc-400" />
295
+ </button>
296
+ </DialogHeader>
297
+
298
+ <form
299
+ onSubmit={form.handleSubmit(onSubmit)}
300
+ className="flex flex-col flex-1 lg:flex-none overflow-hidden"
301
+ >
302
+ <div className="flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none overflow-y-auto">
303
+ <div className="flex flex-col gap-4">
304
+ <SelectField
305
+ options={selectOptions}
306
+ value={creditOption}
307
+ onChange={handleCreditOptionChange}
308
+ className="h-12!"
309
+ />
310
+
311
+ <PaymentInfoCard
312
+ selectedCardId={selectedCardId}
313
+ onCardSelect={(cardId) =>
314
+ form.setValue('selectedCardId', cardId, { shouldValidate: true })
315
+ }
316
+ onOpenAddCard={handleOpenAddCardModal}
317
+ />
318
+
319
+ {hasChanged && (
320
+ <div className={`flex items-center gap-3 p-4 rounded-lg ${isDefaultWl ? 'bg-cyan-50' : 'bg-zinc-50'}`}>
321
+ <IconInfoCircle className="size-4 text-zinc-950 shrink-0" />
322
+ <span className="paragraph-small-regular text-zinc-950">
323
+ {isIncreasingCredits
324
+ ? translate('common.credits.buy.paymentOnConfirm')
325
+ : translate('common.credits.buy.nextInvoiceChanges')}
326
+ </span>
327
+ </div>
328
+ )}
329
+ </div>
330
+
331
+ <Separator className="bg-zinc-200 hidden lg:block" />
332
+
333
+ <div className="hidden lg:flex flex-col gap-2">
334
+ {immediateChargeTotal !== null && immediateChargeTotal > 0 && (
335
+ <div className="flex items-center justify-between">
336
+ <span className="paragraph-xsmall-medium text-zinc-500">{translate('common.credits.buy.immediateCharge')}</span>
337
+ {isCalculatePending ? (
338
+ <Skeleton className="h-5 w-20" />
339
+ ) : (
340
+ <span className="paragraph-small-semibold text-zinc-950">
341
+ {formatPrice(immediateChargeTotal)}
342
+ </span>
343
+ )}
344
+ </div>
345
+ )}
346
+ <div className="flex items-center justify-between">
347
+ <span className="paragraph-small-medium text-zinc-500">{translate('common.credits.buy.totalPlanValue')}</span>
348
+ {renderPriceDisplay()}
349
+ </div>
350
+ </div>
351
+
352
+ <Button
353
+ type="submit"
354
+ disabled={isConfirmDisabled}
355
+ className="w-full hidden lg:inline-flex"
356
+ >
357
+ {isSubmitting && <IconLoader2 className="size-4 animate-spin" />}
358
+ {translate('common.credits.buy.confirmAndPay')}
359
+ </Button>
360
+ </div>
361
+
362
+ <div className="flex flex-col gap-4 p-4 border-t border-zinc-200 shrink-0 lg:hidden">
363
+ <div className="flex flex-col gap-2">
364
+ {immediateChargeTotal !== null && immediateChargeTotal > 0 && (
365
+ <div className="flex items-center justify-between">
366
+ <span className="paragraph-xsmall-medium text-zinc-500">{translate('common.credits.buy.immediateCharge')}</span>
367
+ {isCalculatePending ? (
368
+ <Skeleton className="h-5 w-20" />
369
+ ) : (
370
+ <span className="paragraph-small-semibold text-zinc-950">
371
+ {formatPrice(immediateChargeTotal)}
372
+ </span>
373
+ )}
374
+ </div>
375
+ )}
376
+ <div className="flex items-center justify-between">
377
+ <span className="paragraph-small-medium text-zinc-500">{translate('common.credits.buy.totalPlanValue')}</span>
378
+ {renderPriceDisplay()}
379
+ </div>
380
+ </div>
381
+ <Button type="submit" disabled={isConfirmDisabled} className="w-full">
382
+ {isSubmitting && <IconLoader2 className="size-4 animate-spin" />}
383
+ {translate('common.credits.buy.confirmAndPay')}
384
+ </Button>
385
+ </div>
386
+ </form>
387
+ </DialogContent>
388
+ </Dialog>
389
+ );
390
+ }