@greatapps/common 1.1.700 → 1.1.702

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 (563) 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/HexaPromoModal.mjs +2 -2
  34. package/dist/components/modals/HexaPromoModal.mjs.map +1 -1
  35. package/dist/components/modals/HexaPromoModalGate.mjs +8 -1
  36. package/dist/components/modals/HexaPromoModalGate.mjs.map +1 -1
  37. package/dist/components/modals/Modals.mjs.map +1 -1
  38. package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
  39. package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
  40. package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
  41. package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
  42. package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
  43. package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
  44. package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
  45. package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
  46. package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
  47. package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
  48. package/dist/components/navigation/SubscriptionBanner.mjs.map +1 -1
  49. package/dist/components/navigation/TrialBanner.mjs.map +1 -1
  50. package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
  51. package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
  52. package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
  53. package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
  54. package/dist/components/pages/NotFoundPage.mjs.map +1 -1
  55. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  56. package/dist/components/ui/buttons/Button.mjs.map +1 -1
  57. package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
  58. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  59. package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
  60. package/dist/components/ui/data-display/Badge.mjs.map +1 -1
  61. package/dist/components/ui/data-display/Card.mjs.map +1 -1
  62. package/dist/components/ui/data-display/CardBrandIcons.mjs.map +1 -1
  63. package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
  64. package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
  65. package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
  66. package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
  67. package/dist/components/ui/data-display/Separator.mjs.map +1 -1
  68. package/dist/components/ui/data-display/Table.mjs.map +1 -1
  69. package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
  70. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
  71. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  72. package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
  73. package/dist/components/ui/feedback/Progress.mjs.map +1 -1
  74. package/dist/components/ui/feedback/Skeleton.mjs.map +1 -1
  75. package/dist/components/ui/feedback/Toast.mjs.map +1 -1
  76. package/dist/components/ui/form/Calendar.mjs.map +1 -1
  77. package/dist/components/ui/form/Checkbox.mjs.map +1 -1
  78. package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
  79. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  80. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  81. package/dist/components/ui/form/FormField.mjs.map +1 -1
  82. package/dist/components/ui/form/Input.mjs.map +1 -1
  83. package/dist/components/ui/form/InputOtp.mjs.map +1 -1
  84. package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
  85. package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
  86. package/dist/components/ui/form/Select.mjs +1 -1
  87. package/dist/components/ui/form/Select.mjs.map +1 -1
  88. package/dist/components/ui/form/Switch.mjs.map +1 -1
  89. package/dist/components/ui/form/Textarea.mjs.map +1 -1
  90. package/dist/components/ui/overlay/Command.mjs.map +1 -1
  91. package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
  92. package/dist/components/ui/overlay/Popover.mjs.map +1 -1
  93. package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
  94. package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
  95. package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
  96. package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
  97. package/dist/components/widgets/ImageUpload/ImageUpload.mjs.map +1 -1
  98. package/dist/components/widgets/ImageUpload/index.mjs.map +1 -1
  99. package/dist/components/widgets/notifications/NotificationCard.mjs.map +1 -1
  100. package/dist/handlers.mjs.map +1 -1
  101. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
  102. package/dist/hooks/useAuthQueryKey.mjs.map +1 -1
  103. package/dist/hooks/useBrandLoadingIcon.mjs.map +1 -1
  104. package/dist/hooks/useRouter.mjs.map +1 -1
  105. package/dist/http.mjs.map +1 -1
  106. package/dist/i18n/config.mjs.map +1 -1
  107. package/dist/i18n/country-language.mjs.map +1 -1
  108. package/dist/i18n/messages/en-us.mjs.map +1 -1
  109. package/dist/i18n/messages/es-es.mjs.map +1 -1
  110. package/dist/i18n/messages/index.mjs.map +1 -1
  111. package/dist/i18n/messages/pt-br.mjs.map +1 -1
  112. package/dist/i18n/normalize.mjs.map +1 -1
  113. package/dist/i18n/resolve-locale.mjs.map +1 -1
  114. package/dist/i18n.mjs.map +1 -1
  115. package/dist/index.mjs.map +1 -1
  116. package/dist/infra/http/api-fetch.mjs.map +1 -1
  117. package/dist/infra/route/parse-id.mjs.map +1 -1
  118. package/dist/infra/route/parse-numeric.mjs.map +1 -1
  119. package/dist/infra/route/safe-route-handler.mjs.map +1 -1
  120. package/dist/infra/route/search-params.mjs.map +1 -1
  121. package/dist/infra/utils/array.mjs.map +1 -1
  122. package/dist/infra/utils/date.mjs.map +1 -1
  123. package/dist/middleware.mjs.map +1 -1
  124. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  125. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  126. package/dist/modules/accounts/actions/get-account-token.action.mjs.map +1 -1
  127. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  128. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  129. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  130. package/dist/modules/accounts/hooks/use-account-token.hook.mjs.map +1 -1
  131. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -1
  132. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  133. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  134. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  135. package/dist/modules/accounts/hooks/useViaCep.mjs.map +1 -1
  136. package/dist/modules/accounts/services/account-token.service.mjs.map +1 -1
  137. package/dist/modules/accounts/services/account.service.mjs.map +1 -1
  138. package/dist/modules/auth/actions/social-google-login.action.mjs.map +1 -1
  139. package/dist/modules/auth/actions/social-google-onboarding.action.mjs.map +1 -1
  140. package/dist/modules/auth/actions/unlink-google.action.mjs.map +1 -1
  141. package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -1
  142. package/dist/modules/auth/actions/verify-two-factor.action.mjs.map +1 -1
  143. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  144. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  145. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  146. package/dist/modules/auth/hooks/social-google-login.hook.mjs.map +1 -1
  147. package/dist/modules/auth/hooks/social-google-onboarding.hook.mjs.map +1 -1
  148. package/dist/modules/auth/hooks/unlink-google.hook.mjs.map +1 -1
  149. package/dist/modules/auth/hooks/useManagementPermissions.mjs.map +1 -1
  150. package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -1
  151. package/dist/modules/auth/utils/assert-management-permission.mjs.map +1 -1
  152. package/dist/modules/auth/utils/assert-management-subscription.mjs.map +1 -1
  153. package/dist/modules/auth/utils/assert-paid-subscription.mjs.map +1 -1
  154. package/dist/modules/auth/utils/assert-subscription-addon.mjs.map +1 -1
  155. package/dist/modules/auth/utils/build-wl-override.mjs.map +1 -1
  156. package/dist/modules/auth/utils/require-token-not-expired.mjs.map +1 -1
  157. package/dist/modules/auth/utils/require-valid-session.mjs.map +1 -1
  158. package/dist/modules/cards/actions/create-card.action.mjs.map +1 -1
  159. package/dist/modules/cards/actions/create-setup-intent.action.mjs.map +1 -1
  160. package/dist/modules/cards/actions/delete-card.action.mjs.map +1 -1
  161. package/dist/modules/cards/actions/set-default-card.action.mjs.map +1 -1
  162. package/dist/modules/cards/handlers/find-card-by-id.handler.mjs.map +1 -1
  163. package/dist/modules/cards/handlers/list-cards.handler.mjs.map +1 -1
  164. package/dist/modules/cards/hooks/card-by-id.hook.mjs.map +1 -1
  165. package/dist/modules/cards/hooks/cards.hook.mjs.map +1 -1
  166. package/dist/modules/cards/hooks/create-card.hook.mjs.map +1 -1
  167. package/dist/modules/cards/hooks/create-setup-intent.hook.mjs.map +1 -1
  168. package/dist/modules/cards/hooks/delete-card.hook.mjs.map +1 -1
  169. package/dist/modules/cards/hooks/delete-confirmation.hook.mjs.map +1 -1
  170. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
  171. package/dist/modules/cards/hooks/set-default-card.hook.mjs.map +1 -1
  172. package/dist/modules/cards/services/cards.service.mjs.map +1 -1
  173. package/dist/modules/cards/types.mjs.map +1 -1
  174. package/dist/modules/charges/actions/charge-action.action.mjs.map +1 -1
  175. package/dist/modules/charges/handlers/find-charge-by-id.handler.mjs.map +1 -1
  176. package/dist/modules/charges/handlers/list-charges.handler.mjs.map +1 -1
  177. package/dist/modules/charges/hooks/charge-action.hook.mjs.map +1 -1
  178. package/dist/modules/charges/hooks/charge-by-id.hook.mjs.map +1 -1
  179. package/dist/modules/charges/hooks/charges.hook.mjs.map +1 -1
  180. package/dist/modules/charges/services/charges.service.mjs.map +1 -1
  181. package/dist/modules/charges/types/charge.type.mjs.map +1 -1
  182. package/dist/modules/ia-credits/handlers/list-ia-credits.handler.mjs.map +1 -1
  183. package/dist/modules/ia-credits/hooks/ia-credits.hook.mjs.map +1 -1
  184. package/dist/modules/images/actions/process-image.action.mjs.map +1 -1
  185. package/dist/modules/images/constants/image.constants.mjs.map +1 -1
  186. package/dist/modules/images/hooks/use-image-upload.hook.mjs.map +1 -1
  187. package/dist/modules/images/services/image-processing.service.mjs.map +1 -1
  188. package/dist/modules/images/utils/base64.mjs.map +1 -1
  189. package/dist/modules/images/utils/compress-image.mjs.map +1 -1
  190. package/dist/modules/images/utils/crop-image.mjs.map +1 -1
  191. package/dist/modules/images/utils/validate-image.mjs.map +1 -1
  192. package/dist/modules/pages/constants/query-keys.constants.mjs.map +1 -1
  193. package/dist/modules/pages/handlers/count-pages.handler.mjs.map +1 -1
  194. package/dist/modules/pages/hooks/count-pages.hook.mjs.map +1 -1
  195. package/dist/modules/pages/services/pages.service.mjs.map +1 -1
  196. package/dist/modules/plans/handlers/find-plan-by-id.handler.mjs.map +1 -1
  197. package/dist/modules/plans/handlers/list-plans.handler.mjs.map +1 -1
  198. package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
  199. package/dist/modules/plans/hooks/use-has-plan-addon.hook.mjs.map +1 -1
  200. package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
  201. package/dist/modules/plans/services/plans.service.mjs.map +1 -1
  202. package/dist/modules/plans/types/plan.type.mjs.map +1 -1
  203. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
  204. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  205. package/dist/modules/projects/actions/create-project.action.mjs.map +1 -1
  206. package/dist/modules/projects/actions/delete-project.action.mjs.map +1 -1
  207. package/dist/modules/projects/actions/find-project.action.mjs.map +1 -1
  208. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  209. package/dist/modules/projects/actions/list-projects.action.mjs.map +1 -1
  210. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  211. package/dist/modules/projects/actions/update-project.action.mjs.map +1 -1
  212. package/dist/modules/projects/handlers/find-project.handler.mjs.map +1 -1
  213. package/dist/modules/projects/handlers/list-all-account-users.handler.mjs.map +1 -1
  214. package/dist/modules/projects/handlers/list-available-users.handler.mjs.map +1 -1
  215. package/dist/modules/projects/handlers/list-project-users.handler.mjs.map +1 -1
  216. package/dist/modules/projects/handlers/list-projects.handler.mjs.map +1 -1
  217. package/dist/modules/projects/hooks/add-project-user.hook.mjs.map +1 -1
  218. package/dist/modules/projects/hooks/create-project.hook.mjs.map +1 -1
  219. package/dist/modules/projects/hooks/delete-project.hook.mjs.map +1 -1
  220. package/dist/modules/projects/hooks/find-project.hook.mjs.map +1 -1
  221. package/dist/modules/projects/hooks/list-all-account-users.hook.mjs.map +1 -1
  222. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  223. package/dist/modules/projects/hooks/list-infinite-projects.hook.mjs.map +1 -1
  224. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  225. package/dist/modules/projects/hooks/list-projects.hook.mjs.map +1 -1
  226. package/dist/modules/projects/hooks/remove-project-user.hook.mjs.map +1 -1
  227. package/dist/modules/projects/hooks/update-project.hook.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 +2 -0
  241. package/dist/modules/subscriptions/hooks/update-subscription-plan.hook.mjs.map +1 -1
  242. package/dist/modules/subscriptions/hooks/use-cancelled-subscription-guard.mjs.map +1 -1
  243. package/dist/modules/subscriptions/types/calculate-subscription.type.mjs.map +1 -1
  244. package/dist/modules/subscriptions/types/pix-pending.type.mjs.map +1 -1
  245. package/dist/modules/subscriptions/utils/build-plan-extras.mjs.map +1 -1
  246. package/dist/modules/subscriptions/utils/get-subscription-cancellation-state.mjs.map +1 -1
  247. package/dist/modules/subscriptions/utils/get-subscription-expiry-date.mjs.map +1 -1
  248. package/dist/modules/subscriptions/utils/has-subscription-expired.mjs.map +1 -1
  249. package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
  250. package/dist/modules/subscriptions/utils/resolve-plan-extras-prices.mjs.map +1 -1
  251. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
  252. package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
  253. package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
  254. package/dist/modules/users/handlers/list-messages.handler.mjs.map +1 -1
  255. package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
  256. package/dist/modules/users/services/messages.service.mjs.map +1 -1
  257. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
  258. package/dist/modules/whitelabel/actions/revalidate-whitelabel.action.mjs.map +1 -1
  259. package/dist/modules/whitelabel/utils/normalize-hostname.mjs.map +1 -1
  260. package/dist/providers/auth.provider.mjs.map +1 -1
  261. package/dist/providers/navigation.provider.mjs.map +1 -1
  262. package/dist/providers/whitelabel.provider.mjs.map +1 -1
  263. package/dist/route.mjs.map +1 -1
  264. package/dist/store/useAccountModals.mjs.map +1 -1
  265. package/dist/store/useBuyCreditsModal.mjs.map +1 -1
  266. package/dist/store/useCreditsDisabledModal.mjs.map +1 -1
  267. package/dist/store/useDesktopSidebarStore.mjs.map +1 -1
  268. package/dist/store/useHexaPromoModal.mjs.map +1 -1
  269. package/dist/store/useMdSidebarStore.mjs.map +1 -1
  270. package/dist/store/usePaidPlanRequiredModal.mjs.map +1 -1
  271. package/dist/utils/constants/br-states.mjs.map +1 -1
  272. package/dist/utils/cookies/hexa-promo.mjs.map +1 -1
  273. package/dist/utils/countries.mjs.map +1 -1
  274. package/dist/utils/format/currency.mjs.map +1 -1
  275. package/dist/utils/intl/cookie-domain.mjs.map +1 -1
  276. package/dist/utils/intl/locale-cookie.mjs.map +1 -1
  277. package/dist/utils/next-navigation.mjs.map +1 -1
  278. package/dist/utils/redirect.mjs.map +1 -1
  279. package/dist/utils/safeMutationAction.mjs.map +1 -1
  280. package/dist/utils/safeServerAction.mjs.map +1 -1
  281. package/dist/utils/withAction.mjs.map +1 -1
  282. package/package.json +115 -115
  283. package/src/components/account/ConfigurationsMyAccountModal.tsx +179 -179
  284. package/src/components/account/ConfirmDeleteAccountModal.tsx +110 -110
  285. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +68 -68
  286. package/src/components/account/DeleteAccountModal.tsx +160 -160
  287. package/src/components/account/DisableTwoFactorAuthModal.tsx +92 -92
  288. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +51 -51
  289. package/src/components/account/TwoFactorAuthModal.tsx +220 -220
  290. package/src/components/account/hooks/useChangePhoneForm.tsx +113 -113
  291. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +116 -116
  292. package/src/components/account/sections/ChangeEmailModal.tsx +239 -239
  293. package/src/components/account/sections/ChangePasswordSection.tsx +68 -68
  294. package/src/components/account/sections/ChangePhoneModal.tsx +273 -273
  295. package/src/components/account/sections/MyProfileSection.tsx +276 -276
  296. package/src/components/account/sections/PreferencesSection.tsx +278 -278
  297. package/src/components/account/sections/SecuritySection.tsx +102 -102
  298. package/src/components/account/sections/TokenSection.tsx +85 -85
  299. package/src/components/embeds/ClarityEmbed.tsx +70 -70
  300. package/src/components/embeds/CrispEmbed.tsx +195 -195
  301. package/src/components/embeds/EmbedWidgets.tsx +62 -62
  302. package/src/components/embeds/FrillEmbed.tsx +146 -146
  303. package/src/components/layouts/AppMobileNavBar.tsx +214 -214
  304. package/src/components/layouts/AppNavBar.tsx +40 -40
  305. package/src/components/layouts/MdSideBarNavigation.tsx +56 -56
  306. package/src/components/layouts/NavBar.tsx +228 -228
  307. package/src/components/layouts/NotificationsPopover.tsx +120 -120
  308. package/src/components/layouts/ProfilePopover.tsx +191 -191
  309. package/src/components/layouts/SideBarNavigation.tsx +65 -65
  310. package/src/components/layouts/UsersSelectorPopover.tsx +236 -236
  311. package/src/components/layouts/WhitelabelCodes.tsx +59 -59
  312. package/src/components/modals/BuyCreditsModal.tsx +390 -390
  313. package/src/components/modals/CreditsDisabledModal.tsx +62 -62
  314. package/src/components/modals/HexaPromoModal.tsx +212 -212
  315. package/src/components/modals/HexaPromoModalGate.tsx +93 -80
  316. package/src/components/modals/Modals.tsx +25 -25
  317. package/src/components/modals/PaidPlanRequiredModal.tsx +60 -60
  318. package/src/components/modals/cards/AddCardModal.tsx +420 -420
  319. package/src/components/modals/cards/CannotDeleteCardModal.tsx +124 -124
  320. package/src/components/modals/cards/CardFormFields.tsx +363 -363
  321. package/src/components/modals/cards/DeleteCardModal.tsx +136 -136
  322. package/src/components/navigation/CancelledSubscriptionBanner.tsx +62 -62
  323. package/src/components/navigation/NavItemsContext.ts +20 -20
  324. package/src/components/navigation/OverdueInvoiceBanner.tsx +51 -51
  325. package/src/components/navigation/PendingCancellationBanner.tsx +60 -60
  326. package/src/components/navigation/ProjectSelectorPopover.tsx +180 -180
  327. package/src/components/navigation/SubscriptionBanner.tsx +94 -94
  328. package/src/components/navigation/TrialBanner.tsx +54 -54
  329. package/src/components/navigation/UpcomingInvoiceBanner.tsx +55 -55
  330. package/src/components/navigation/shells/TabsMobileShell.tsx +74 -74
  331. package/src/components/navigation/subcomponents/BottomLinks.tsx +85 -85
  332. package/src/components/navigation/subcomponents/ProjectSelector.tsx +184 -184
  333. package/src/components/pages/NotFoundPage.tsx +75 -75
  334. package/src/components/pages/notifications/Notifications.tsx +190 -190
  335. package/src/components/ui/buttons/Button.tsx +77 -77
  336. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  337. package/src/components/ui/buttons/CopyButton.tsx +59 -59
  338. package/src/components/ui/data-display/Accordion.tsx +81 -81
  339. package/src/components/ui/data-display/Badge.tsx +47 -47
  340. package/src/components/ui/data-display/Card.tsx +93 -93
  341. package/src/components/ui/data-display/CardBrandIcons.tsx +336 -336
  342. package/src/components/ui/data-display/CardItem.tsx +135 -135
  343. package/src/components/ui/data-display/Pagination.tsx +126 -126
  344. package/src/components/ui/data-display/PaymentInfoCard.tsx +193 -193
  345. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  346. package/src/components/ui/data-display/Separator.tsx +29 -29
  347. package/src/components/ui/data-display/Table.tsx +117 -117
  348. package/src/components/ui/data-display/Tabs.tsx +67 -67
  349. package/src/components/ui/feedback/CircularProgress.tsx +79 -79
  350. package/src/components/ui/feedback/DefaultCircularProgress.tsx +67 -67
  351. package/src/components/ui/feedback/LoadingOverlay.tsx +30 -30
  352. package/src/components/ui/feedback/Progress.tsx +40 -40
  353. package/src/components/ui/feedback/Skeleton.tsx +5 -5
  354. package/src/components/ui/feedback/Toast.tsx +104 -104
  355. package/src/components/ui/form/Calendar.tsx +228 -228
  356. package/src/components/ui/form/Checkbox.tsx +31 -31
  357. package/src/components/ui/form/ComboboxField.tsx +159 -159
  358. package/src/components/ui/form/DatePicker.tsx +100 -100
  359. package/src/components/ui/form/DateRangePicker.tsx +111 -111
  360. package/src/components/ui/form/FormField.tsx +133 -133
  361. package/src/components/ui/form/Input.tsx +20 -20
  362. package/src/components/ui/form/InputOtp.tsx +80 -80
  363. package/src/components/ui/form/PhoneInput.tsx +210 -210
  364. package/src/components/ui/form/RadioGroup.tsx +45 -45
  365. package/src/components/ui/form/Select.tsx +200 -200
  366. package/src/components/ui/form/Switch.tsx +32 -32
  367. package/src/components/ui/form/Textarea.tsx +19 -19
  368. package/src/components/ui/overlay/Command.tsx +185 -185
  369. package/src/components/ui/overlay/Dialog.tsx +153 -153
  370. package/src/components/ui/overlay/Popover.tsx +49 -49
  371. package/src/components/ui/overlay/Sheet.tsx +170 -170
  372. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  373. package/src/components/widgets/ImageUpload/ImageCropModal.tsx +392 -392
  374. package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +62 -62
  375. package/src/components/widgets/ImageUpload/ImageUpload.tsx +131 -131
  376. package/src/components/widgets/ImageUpload/index.ts +3 -3
  377. package/src/components/widgets/notifications/NotificationCard.tsx +73 -73
  378. package/src/handlers.ts +22 -22
  379. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  380. package/src/hooks/useAuthQueryKey.ts +32 -32
  381. package/src/hooks/useBrandLoadingIcon.tsx +18 -18
  382. package/src/hooks/useRouter.ts +38 -38
  383. package/src/http.ts +1 -1
  384. package/src/i18n/config.ts +17 -17
  385. package/src/i18n/country-language.ts +60 -60
  386. package/src/i18n/messages/en-us.ts +519 -519
  387. package/src/i18n/messages/es-es.ts +520 -520
  388. package/src/i18n/messages/index.ts +24 -24
  389. package/src/i18n/messages/pt-br.ts +543 -543
  390. package/src/i18n/normalize.ts +15 -15
  391. package/src/i18n/resolve-locale.ts +77 -77
  392. package/src/i18n.ts +10 -10
  393. package/src/index.ts +587 -587
  394. package/src/infra/http/api-fetch.ts +39 -39
  395. package/src/infra/route/parse-id.ts +9 -9
  396. package/src/infra/route/parse-numeric.ts +16 -16
  397. package/src/infra/route/safe-route-handler.ts +16 -16
  398. package/src/infra/route/search-params.ts +9 -9
  399. package/src/infra/utils/array.ts +167 -167
  400. package/src/infra/utils/date.ts +59 -59
  401. package/src/middleware.ts +4 -4
  402. package/src/modules/accounts/actions/account-management.action.ts +109 -109
  403. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  404. package/src/modules/accounts/actions/get-account-token.action.ts +8 -8
  405. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  406. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  407. package/src/modules/accounts/hooks/current-account.hook.tsx +26 -26
  408. package/src/modules/accounts/hooks/use-account-token.hook.tsx +14 -14
  409. package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -32
  410. package/src/modules/accounts/hooks/useAccountManagement.ts +95 -95
  411. package/src/modules/accounts/hooks/useCurrencies.ts +18 -18
  412. package/src/modules/accounts/hooks/useTimezones.ts +18 -18
  413. package/src/modules/accounts/hooks/useViaCep.ts +25 -25
  414. package/src/modules/accounts/services/account-token.service.ts +52 -52
  415. package/src/modules/accounts/services/account.service.ts +243 -243
  416. package/src/modules/accounts/types.ts +230 -230
  417. package/src/modules/auth/actions/social-google-login.action.ts +12 -12
  418. package/src/modules/auth/actions/social-google-onboarding.action.ts +13 -13
  419. package/src/modules/auth/actions/unlink-google.action.ts +8 -8
  420. package/src/modules/auth/actions/validate-session.action.ts +70 -70
  421. package/src/modules/auth/actions/verify-two-factor.action.ts +19 -19
  422. package/src/modules/auth/hooks/login.hook.tsx +13 -13
  423. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  424. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  425. package/src/modules/auth/hooks/social-google-login.hook.tsx +13 -13
  426. package/src/modules/auth/hooks/social-google-onboarding.hook.tsx +13 -13
  427. package/src/modules/auth/hooks/unlink-google.hook.tsx +13 -13
  428. package/src/modules/auth/hooks/useManagementPermissions.ts +52 -52
  429. package/src/modules/auth/hooks/useUserQuery.ts +103 -103
  430. package/src/modules/auth/types/management-permission.type.ts +14 -14
  431. package/src/modules/auth/utils/assert-management-permission.ts +56 -56
  432. package/src/modules/auth/utils/assert-management-subscription.ts +38 -38
  433. package/src/modules/auth/utils/assert-paid-subscription.ts +47 -47
  434. package/src/modules/auth/utils/assert-subscription-addon.ts +42 -42
  435. package/src/modules/auth/utils/build-wl-override.ts +43 -43
  436. package/src/modules/auth/utils/require-token-not-expired.ts +53 -53
  437. package/src/modules/auth/utils/require-valid-session.ts +35 -35
  438. package/src/modules/cards/actions/create-card.action.ts +9 -9
  439. package/src/modules/cards/actions/create-setup-intent.action.ts +8 -8
  440. package/src/modules/cards/actions/delete-card.action.ts +8 -8
  441. package/src/modules/cards/actions/set-default-card.action.ts +8 -8
  442. package/src/modules/cards/handlers/find-card-by-id.handler.ts +15 -15
  443. package/src/modules/cards/handlers/list-cards.handler.ts +10 -10
  444. package/src/modules/cards/hooks/card-by-id.hook.ts +17 -17
  445. package/src/modules/cards/hooks/cards.hook.ts +22 -22
  446. package/src/modules/cards/hooks/create-card.hook.ts +30 -30
  447. package/src/modules/cards/hooks/create-setup-intent.hook.ts +11 -11
  448. package/src/modules/cards/hooks/delete-card.hook.ts +52 -52
  449. package/src/modules/cards/hooks/delete-confirmation.hook.ts +40 -40
  450. package/src/modules/cards/hooks/handle-delete-card.hook.ts +47 -47
  451. package/src/modules/cards/hooks/set-default-card.hook.ts +55 -55
  452. package/src/modules/cards/services/cards.service.ts +136 -136
  453. package/src/modules/cards/types.ts +52 -52
  454. package/src/modules/charges/actions/charge-action.action.ts +13 -13
  455. package/src/modules/charges/handlers/find-charge-by-id.handler.ts +14 -14
  456. package/src/modules/charges/handlers/list-charges.handler.ts +15 -15
  457. package/src/modules/charges/hooks/charge-action.hook.ts +24 -24
  458. package/src/modules/charges/hooks/charge-by-id.hook.ts +19 -19
  459. package/src/modules/charges/hooks/charges.hook.ts +19 -19
  460. package/src/modules/charges/services/charges.service.ts +63 -63
  461. package/src/modules/charges/types/charge.type.ts +68 -68
  462. package/src/modules/ia-credits/handlers/list-ia-credits.handler.ts +14 -14
  463. package/src/modules/ia-credits/hooks/ia-credits.hook.ts +103 -103
  464. package/src/modules/images/actions/process-image.action.ts +40 -40
  465. package/src/modules/images/constants/image.constants.ts +11 -11
  466. package/src/modules/images/hooks/use-image-upload.hook.ts +153 -153
  467. package/src/modules/images/services/image-processing.service.ts +75 -75
  468. package/src/modules/images/types/image.type.ts +54 -54
  469. package/src/modules/images/utils/base64.ts +26 -26
  470. package/src/modules/images/utils/compress-image.ts +20 -20
  471. package/src/modules/images/utils/crop-image.ts +68 -68
  472. package/src/modules/images/utils/validate-image.ts +86 -86
  473. package/src/modules/pages/constants/query-keys.constants.ts +1 -1
  474. package/src/modules/pages/handlers/count-pages.handler.ts +12 -12
  475. package/src/modules/pages/hooks/count-pages.hook.ts +21 -21
  476. package/src/modules/pages/services/pages.service.ts +27 -27
  477. package/src/modules/plans/handlers/find-plan-by-id.handler.ts +14 -14
  478. package/src/modules/plans/handlers/list-plans.handler.ts +22 -22
  479. package/src/modules/plans/hooks/list-plans.hook.ts +23 -23
  480. package/src/modules/plans/hooks/use-has-plan-addon.hook.ts +14 -14
  481. package/src/modules/plans/hooks/use-plan-by-id.hook.ts +39 -39
  482. package/src/modules/plans/services/plans.service.ts +136 -136
  483. package/src/modules/plans/types/plan.type.ts +79 -79
  484. package/src/modules/plans/utils/map-api-plan-to-ui.ts +167 -167
  485. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  486. package/src/modules/projects/actions/create-project.action.ts +9 -9
  487. package/src/modules/projects/actions/delete-project.action.ts +8 -8
  488. package/src/modules/projects/actions/find-project.action.ts +8 -8
  489. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  490. package/src/modules/projects/actions/list-projects.action.ts +16 -16
  491. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  492. package/src/modules/projects/actions/update-project.action.ts +9 -9
  493. package/src/modules/projects/handlers/find-project.handler.ts +15 -15
  494. package/src/modules/projects/handlers/list-all-account-users.handler.ts +23 -23
  495. package/src/modules/projects/handlers/list-available-users.handler.ts +26 -26
  496. package/src/modules/projects/handlers/list-project-users.handler.ts +26 -26
  497. package/src/modules/projects/handlers/list-projects.handler.ts +23 -23
  498. package/src/modules/projects/hooks/add-project-user.hook.ts +72 -72
  499. package/src/modules/projects/hooks/create-project.hook.ts +120 -120
  500. package/src/modules/projects/hooks/delete-project.hook.ts +58 -58
  501. package/src/modules/projects/hooks/find-project.hook.ts +18 -18
  502. package/src/modules/projects/hooks/list-all-account-users.hook.ts +40 -40
  503. package/src/modules/projects/hooks/list-available-users.hook.ts +39 -39
  504. package/src/modules/projects/hooks/list-infinite-projects.hook.ts +44 -44
  505. package/src/modules/projects/hooks/list-project-users.hook.ts +39 -39
  506. package/src/modules/projects/hooks/list-projects.hook.ts +23 -23
  507. package/src/modules/projects/hooks/remove-project-user.hook.ts +72 -72
  508. package/src/modules/projects/hooks/update-project.hook.ts +86 -86
  509. package/src/modules/projects/services/projects.service.ts +156 -156
  510. package/src/modules/subscriptions/actions/calculate-subscription.action.ts +9 -9
  511. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  512. package/src/modules/subscriptions/actions/update-subscription-payment.action.ts +13 -13
  513. package/src/modules/subscriptions/actions/update-subscription-plan.action.ts +14 -14
  514. package/src/modules/subscriptions/constants/query-keys.constants.ts +3 -3
  515. package/src/modules/subscriptions/constants/subscription.constants.ts +1 -1
  516. package/src/modules/subscriptions/handlers/list-subscriptions.handler.ts +17 -17
  517. package/src/modules/subscriptions/hooks/calculate-subscription.hook.ts +13 -13
  518. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +22 -22
  519. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +22 -22
  520. package/src/modules/subscriptions/hooks/update-subscription-payment.hook.ts +25 -25
  521. package/src/modules/subscriptions/hooks/update-subscription-plan.hook.ts +31 -28
  522. package/src/modules/subscriptions/hooks/use-cancelled-subscription-guard.ts +44 -44
  523. package/src/modules/subscriptions/types/billing-period.type.ts +1 -1
  524. package/src/modules/subscriptions/types/calculate-subscription.type.ts +116 -116
  525. package/src/modules/subscriptions/types/pix-pending.type.ts +38 -38
  526. package/src/modules/subscriptions/utils/build-plan-extras.ts +56 -56
  527. package/src/modules/subscriptions/utils/get-subscription-cancellation-state.ts +37 -37
  528. package/src/modules/subscriptions/utils/get-subscription-expiry-date.ts +33 -33
  529. package/src/modules/subscriptions/utils/has-subscription-expired.ts +11 -11
  530. package/src/modules/subscriptions/utils/periodicity.ts +79 -79
  531. package/src/modules/subscriptions/utils/resolve-plan-extras-prices.ts +23 -23
  532. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  533. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  534. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  535. package/src/modules/users/handlers/list-messages.handler.ts +39 -39
  536. package/src/modules/users/hooks/messages.hook.ts +69 -69
  537. package/src/modules/users/services/messages.service.ts +49 -49
  538. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  539. package/src/modules/whitelabel/actions/revalidate-whitelabel.action.ts +19 -19
  540. package/src/modules/whitelabel/schema.ts +84 -84
  541. package/src/modules/whitelabel/utils/normalize-hostname.ts +26 -26
  542. package/src/providers/auth.provider.tsx +267 -267
  543. package/src/providers/navigation.provider.tsx +99 -99
  544. package/src/providers/whitelabel.provider.tsx +90 -90
  545. package/src/route.ts +4 -4
  546. package/src/store/useAccountModals.ts +85 -85
  547. package/src/store/useBuyCreditsModal.ts +21 -21
  548. package/src/store/useCreditsDisabledModal.ts +11 -11
  549. package/src/store/useDesktopSidebarStore.ts +47 -47
  550. package/src/store/useHexaPromoModal.ts +13 -13
  551. package/src/store/useMdSidebarStore.ts +34 -34
  552. package/src/store/usePaidPlanRequiredModal.ts +19 -19
  553. package/src/utils/constants/br-states.ts +29 -29
  554. package/src/utils/cookies/hexa-promo.ts +114 -114
  555. package/src/utils/countries.ts +224 -224
  556. package/src/utils/format/currency.ts +70 -70
  557. package/src/utils/intl/cookie-domain.ts +29 -29
  558. package/src/utils/intl/locale-cookie.ts +18 -18
  559. package/src/utils/next-navigation.ts +7 -7
  560. package/src/utils/redirect.ts +78 -78
  561. package/src/utils/safeMutationAction.ts +24 -24
  562. package/src/utils/safeServerAction.ts +21 -21
  563. package/src/utils/withAction.ts +13 -13
@@ -1,153 +1,153 @@
1
- 'use client'
2
-
3
- import { useState, useCallback, useRef, useEffect } from 'react'
4
- import type { Crop } from 'react-image-crop'
5
- import { cropImageToCanvas } from '../utils/crop-image'
6
- import { validateImage } from '../utils/validate-image'
7
- import type { ImageConfig } from '../types/image.type'
8
-
9
- export interface ImageTooSmallError {
10
- fileName: string
11
- minWidth: number
12
- minHeight: number
13
- }
14
-
15
- export interface UseImageUploadOptions {
16
- config: ImageConfig
17
- onSuccess?: (base64Image: string) => void
18
- onError?: (error: string) => void
19
- }
20
-
21
- export function useImageUpload(options: UseImageUploadOptions) {
22
- const { config, onSuccess, onError } = options
23
-
24
- // Refs para manter callbacks sempre atualizados (evita stale closures)
25
- const onSuccessRef = useRef(onSuccess)
26
- const onErrorRef = useRef(onError)
27
- useEffect(() => {
28
- onSuccessRef.current = onSuccess
29
- onErrorRef.current = onError
30
- }, [onSuccess, onError])
31
-
32
- const [originalImage, setOriginalImage] = useState<string | null>(null)
33
- const [croppedPreview, setCroppedPreview] = useState<string | null>(null)
34
- const [showCropModal, setShowCropModal] = useState(false)
35
- const [showTooSmallModal, setShowTooSmallModal] = useState(false)
36
- const [tooSmallError, setTooSmallError] = useState<ImageTooSmallError | null>(null)
37
- const [isProcessing, setIsProcessing] = useState(false)
38
- const [fileName, setFileName] = useState<string>('')
39
- const fileInputRef = useRef<HTMLInputElement>(null)
40
- const currentFileName = useRef<string>('')
41
- // Saída deve sair como PNG para não perder transparência. Só JPEG é achatado.
42
- const preserveTransparency = useRef<boolean>(false)
43
-
44
- const handleFileSelect = useCallback(
45
- (file: File) => {
46
- const validation = validateImage(file)
47
- if (!validation.valid) {
48
- onErrorRef.current?.(validation.error || 'Arquivo inválido')
49
- return
50
- }
51
-
52
- currentFileName.current = file.name
53
- // JPEG é o único formato aceito sem canal alpha. Para qualquer outro
54
- // formato — png, webp, gif — ou quando o navegador não informa o tipo
55
- // (file.type === ''), saímos como PNG para não achatar a transparência
56
- // em fundo preto (JPEG não tem alpha → pixel transparente vira preto).
57
- preserveTransparency.current = file.type !== 'image/jpeg'
58
- setFileName(file.name)
59
-
60
- // Usa object URL em vez de base64 — mais eficiente para imagens grandes
61
- const objectUrl = URL.createObjectURL(file)
62
- setOriginalImage(objectUrl)
63
-
64
- // Carrega imagem em memória para garantir que é válida antes de abrir modal
65
- const img = new Image()
66
- img.onload = () => {
67
- setShowCropModal(true)
68
- }
69
- img.onerror = () => {
70
- URL.revokeObjectURL(objectUrl)
71
- setOriginalImage(null)
72
- onErrorRef.current?.('Erro ao carregar a imagem. Tente uma imagem menor ou em outro formato.')
73
- }
74
- img.src = objectUrl
75
- },
76
- []
77
- )
78
-
79
- const handleImageLoadInModal = useCallback(
80
- (_naturalWidth: number, _naturalHeight: number) => {
81
- // Validação agora é feita antes de abrir a modal
82
- },
83
- []
84
- )
85
-
86
- const handleSelectAnotherFile = useCallback(() => {
87
- setShowTooSmallModal(false)
88
- setTooSmallError(null)
89
- fileInputRef.current?.click()
90
- }, [])
91
-
92
- const handleCancelTooSmall = useCallback(() => {
93
- setShowTooSmallModal(false)
94
- setShowCropModal(false)
95
- setTooSmallError(null)
96
- if (originalImage) URL.revokeObjectURL(originalImage)
97
- setOriginalImage(null)
98
- }, [originalImage])
99
-
100
- const handleCropConfirm = useCallback(
101
- async (imageElement: HTMLImageElement, cropArea: Crop) => {
102
- setIsProcessing(true)
103
- try {
104
- // Crop é feito inteiramente no cliente via Canvas
105
- // Já produz imagem no tamanho final (config.width x config.height)
106
- const croppedBase64 = await cropImageToCanvas(
107
- imageElement,
108
- cropArea,
109
- config.width,
110
- config.height,
111
- preserveTransparency.current ? 'image/png' : 'image/jpeg'
112
- )
113
-
114
- setCroppedPreview(croppedBase64)
115
- setShowCropModal(false)
116
- if (originalImage) URL.revokeObjectURL(originalImage)
117
- setOriginalImage(null)
118
- onSuccessRef.current?.(croppedBase64)
119
- } catch {
120
- onErrorRef.current?.('Erro ao aplicar crop')
121
- } finally {
122
- setIsProcessing(false)
123
- }
124
- },
125
- [config]
126
- )
127
-
128
- const clear = useCallback(() => {
129
- if (originalImage) URL.revokeObjectURL(originalImage)
130
- setOriginalImage(null)
131
- setCroppedPreview(null)
132
- }, [originalImage])
133
-
134
- return {
135
- originalImage,
136
- croppedPreview,
137
- showCropModal,
138
- showTooSmallModal,
139
- tooSmallError,
140
- config,
141
- isProcessing,
142
- fileName,
143
- fileInputRef,
144
- handleFileSelect,
145
- handleCropConfirm,
146
- handleImageLoadInModal,
147
- handleSelectAnotherFile,
148
- handleCancelTooSmall,
149
- setShowCropModal,
150
- setShowTooSmallModal,
151
- clear,
152
- }
153
- }
1
+ 'use client'
2
+
3
+ import { useState, useCallback, useRef, useEffect } from 'react'
4
+ import type { Crop } from 'react-image-crop'
5
+ import { cropImageToCanvas } from '../utils/crop-image'
6
+ import { validateImage } from '../utils/validate-image'
7
+ import type { ImageConfig } from '../types/image.type'
8
+
9
+ export interface ImageTooSmallError {
10
+ fileName: string
11
+ minWidth: number
12
+ minHeight: number
13
+ }
14
+
15
+ export interface UseImageUploadOptions {
16
+ config: ImageConfig
17
+ onSuccess?: (base64Image: string) => void
18
+ onError?: (error: string) => void
19
+ }
20
+
21
+ export function useImageUpload(options: UseImageUploadOptions) {
22
+ const { config, onSuccess, onError } = options
23
+
24
+ // Refs para manter callbacks sempre atualizados (evita stale closures)
25
+ const onSuccessRef = useRef(onSuccess)
26
+ const onErrorRef = useRef(onError)
27
+ useEffect(() => {
28
+ onSuccessRef.current = onSuccess
29
+ onErrorRef.current = onError
30
+ }, [onSuccess, onError])
31
+
32
+ const [originalImage, setOriginalImage] = useState<string | null>(null)
33
+ const [croppedPreview, setCroppedPreview] = useState<string | null>(null)
34
+ const [showCropModal, setShowCropModal] = useState(false)
35
+ const [showTooSmallModal, setShowTooSmallModal] = useState(false)
36
+ const [tooSmallError, setTooSmallError] = useState<ImageTooSmallError | null>(null)
37
+ const [isProcessing, setIsProcessing] = useState(false)
38
+ const [fileName, setFileName] = useState<string>('')
39
+ const fileInputRef = useRef<HTMLInputElement>(null)
40
+ const currentFileName = useRef<string>('')
41
+ // Saída deve sair como PNG para não perder transparência. Só JPEG é achatado.
42
+ const preserveTransparency = useRef<boolean>(false)
43
+
44
+ const handleFileSelect = useCallback(
45
+ (file: File) => {
46
+ const validation = validateImage(file)
47
+ if (!validation.valid) {
48
+ onErrorRef.current?.(validation.error || 'Arquivo inválido')
49
+ return
50
+ }
51
+
52
+ currentFileName.current = file.name
53
+ // JPEG é o único formato aceito sem canal alpha. Para qualquer outro
54
+ // formato — png, webp, gif — ou quando o navegador não informa o tipo
55
+ // (file.type === ''), saímos como PNG para não achatar a transparência
56
+ // em fundo preto (JPEG não tem alpha → pixel transparente vira preto).
57
+ preserveTransparency.current = file.type !== 'image/jpeg'
58
+ setFileName(file.name)
59
+
60
+ // Usa object URL em vez de base64 — mais eficiente para imagens grandes
61
+ const objectUrl = URL.createObjectURL(file)
62
+ setOriginalImage(objectUrl)
63
+
64
+ // Carrega imagem em memória para garantir que é válida antes de abrir modal
65
+ const img = new Image()
66
+ img.onload = () => {
67
+ setShowCropModal(true)
68
+ }
69
+ img.onerror = () => {
70
+ URL.revokeObjectURL(objectUrl)
71
+ setOriginalImage(null)
72
+ onErrorRef.current?.('Erro ao carregar a imagem. Tente uma imagem menor ou em outro formato.')
73
+ }
74
+ img.src = objectUrl
75
+ },
76
+ []
77
+ )
78
+
79
+ const handleImageLoadInModal = useCallback(
80
+ (_naturalWidth: number, _naturalHeight: number) => {
81
+ // Validação agora é feita antes de abrir a modal
82
+ },
83
+ []
84
+ )
85
+
86
+ const handleSelectAnotherFile = useCallback(() => {
87
+ setShowTooSmallModal(false)
88
+ setTooSmallError(null)
89
+ fileInputRef.current?.click()
90
+ }, [])
91
+
92
+ const handleCancelTooSmall = useCallback(() => {
93
+ setShowTooSmallModal(false)
94
+ setShowCropModal(false)
95
+ setTooSmallError(null)
96
+ if (originalImage) URL.revokeObjectURL(originalImage)
97
+ setOriginalImage(null)
98
+ }, [originalImage])
99
+
100
+ const handleCropConfirm = useCallback(
101
+ async (imageElement: HTMLImageElement, cropArea: Crop) => {
102
+ setIsProcessing(true)
103
+ try {
104
+ // Crop é feito inteiramente no cliente via Canvas
105
+ // Já produz imagem no tamanho final (config.width x config.height)
106
+ const croppedBase64 = await cropImageToCanvas(
107
+ imageElement,
108
+ cropArea,
109
+ config.width,
110
+ config.height,
111
+ preserveTransparency.current ? 'image/png' : 'image/jpeg'
112
+ )
113
+
114
+ setCroppedPreview(croppedBase64)
115
+ setShowCropModal(false)
116
+ if (originalImage) URL.revokeObjectURL(originalImage)
117
+ setOriginalImage(null)
118
+ onSuccessRef.current?.(croppedBase64)
119
+ } catch {
120
+ onErrorRef.current?.('Erro ao aplicar crop')
121
+ } finally {
122
+ setIsProcessing(false)
123
+ }
124
+ },
125
+ [config]
126
+ )
127
+
128
+ const clear = useCallback(() => {
129
+ if (originalImage) URL.revokeObjectURL(originalImage)
130
+ setOriginalImage(null)
131
+ setCroppedPreview(null)
132
+ }, [originalImage])
133
+
134
+ return {
135
+ originalImage,
136
+ croppedPreview,
137
+ showCropModal,
138
+ showTooSmallModal,
139
+ tooSmallError,
140
+ config,
141
+ isProcessing,
142
+ fileName,
143
+ fileInputRef,
144
+ handleFileSelect,
145
+ handleCropConfirm,
146
+ handleImageLoadInModal,
147
+ handleSelectAnotherFile,
148
+ handleCancelTooSmall,
149
+ setShowCropModal,
150
+ setShowTooSmallModal,
151
+ clear,
152
+ }
153
+ }
@@ -1,75 +1,75 @@
1
- import type { ProcessImageInput, ProcessImageOutput } from '../types/image.type'
2
-
3
- export async function processImage(input: ProcessImageInput): Promise<ProcessImageOutput> {
4
- const {
5
- imageBytes,
6
- targetWidth,
7
- targetHeight,
8
- outputFormat = 'jpeg',
9
- quality = 85,
10
- } = input
11
-
12
- // Dynamic import to avoid fs.createReadStream error in edge runtime
13
- const { PhotonImage, resize, crop, SamplingFilter } = await import(
14
- '@cf-wasm/photon/edge-light'
15
- )
16
-
17
- const image = PhotonImage.new_from_byteslice(imageBytes)
18
-
19
- try {
20
- const sourceWidth = image.get_width()
21
- const sourceHeight = image.get_height()
22
- const targetAspect = targetWidth / targetHeight
23
- const sourceAspect = sourceWidth / sourceHeight
24
-
25
- let cropX1 = 0
26
- let cropY1 = 0
27
- let cropX2 = sourceWidth
28
- let cropY2 = sourceHeight
29
-
30
- if (sourceAspect > targetAspect) {
31
- const cropWidth = Math.round(sourceHeight * targetAspect)
32
- cropX1 = Math.round((sourceWidth - cropWidth) / 2)
33
- cropX2 = cropX1 + cropWidth
34
- } else if (sourceAspect < targetAspect) {
35
- const cropHeight = Math.round(sourceWidth / targetAspect)
36
- cropY1 = Math.round((sourceHeight - cropHeight) / 2)
37
- cropY2 = cropY1 + cropHeight
38
- }
39
-
40
- const cropped = crop(image, cropX1, cropY1, cropX2, cropY2)
41
- const resized = resize(
42
- cropped,
43
- targetWidth,
44
- targetHeight,
45
- SamplingFilter.Triangle
46
- )
47
-
48
- let outputBytes: Uint8Array
49
- switch (outputFormat) {
50
- case 'jpeg':
51
- outputBytes = resized.get_bytes_jpeg(quality)
52
- break
53
- case 'png':
54
- outputBytes = resized.get_bytes()
55
- break
56
- case 'webp':
57
- outputBytes = resized.get_bytes_webp()
58
- break
59
- default:
60
- outputBytes = resized.get_bytes_jpeg(quality)
61
- }
62
-
63
- cropped.free()
64
- resized.free()
65
-
66
- return {
67
- bytes: outputBytes,
68
- width: targetWidth,
69
- height: targetHeight,
70
- format: `image/${outputFormat}`,
71
- }
72
- } finally {
73
- image.free()
74
- }
75
- }
1
+ import type { ProcessImageInput, ProcessImageOutput } from '../types/image.type'
2
+
3
+ export async function processImage(input: ProcessImageInput): Promise<ProcessImageOutput> {
4
+ const {
5
+ imageBytes,
6
+ targetWidth,
7
+ targetHeight,
8
+ outputFormat = 'jpeg',
9
+ quality = 85,
10
+ } = input
11
+
12
+ // Dynamic import to avoid fs.createReadStream error in edge runtime
13
+ const { PhotonImage, resize, crop, SamplingFilter } = await import(
14
+ '@cf-wasm/photon/edge-light'
15
+ )
16
+
17
+ const image = PhotonImage.new_from_byteslice(imageBytes)
18
+
19
+ try {
20
+ const sourceWidth = image.get_width()
21
+ const sourceHeight = image.get_height()
22
+ const targetAspect = targetWidth / targetHeight
23
+ const sourceAspect = sourceWidth / sourceHeight
24
+
25
+ let cropX1 = 0
26
+ let cropY1 = 0
27
+ let cropX2 = sourceWidth
28
+ let cropY2 = sourceHeight
29
+
30
+ if (sourceAspect > targetAspect) {
31
+ const cropWidth = Math.round(sourceHeight * targetAspect)
32
+ cropX1 = Math.round((sourceWidth - cropWidth) / 2)
33
+ cropX2 = cropX1 + cropWidth
34
+ } else if (sourceAspect < targetAspect) {
35
+ const cropHeight = Math.round(sourceWidth / targetAspect)
36
+ cropY1 = Math.round((sourceHeight - cropHeight) / 2)
37
+ cropY2 = cropY1 + cropHeight
38
+ }
39
+
40
+ const cropped = crop(image, cropX1, cropY1, cropX2, cropY2)
41
+ const resized = resize(
42
+ cropped,
43
+ targetWidth,
44
+ targetHeight,
45
+ SamplingFilter.Triangle
46
+ )
47
+
48
+ let outputBytes: Uint8Array
49
+ switch (outputFormat) {
50
+ case 'jpeg':
51
+ outputBytes = resized.get_bytes_jpeg(quality)
52
+ break
53
+ case 'png':
54
+ outputBytes = resized.get_bytes()
55
+ break
56
+ case 'webp':
57
+ outputBytes = resized.get_bytes_webp()
58
+ break
59
+ default:
60
+ outputBytes = resized.get_bytes_jpeg(quality)
61
+ }
62
+
63
+ cropped.free()
64
+ resized.free()
65
+
66
+ return {
67
+ bytes: outputBytes,
68
+ width: targetWidth,
69
+ height: targetHeight,
70
+ format: `image/${outputFormat}`,
71
+ }
72
+ } finally {
73
+ image.free()
74
+ }
75
+ }
@@ -1,54 +1,54 @@
1
- export interface ImageConfig {
2
- width: number
3
- height: number
4
- aspectRatio: number
5
- label?: string
6
- }
7
-
8
- export interface CropArea {
9
- x: number
10
- y: number
11
- width: number
12
- height: number
13
- unit?: '%' | 'px'
14
- }
15
-
16
- export interface ProcessedImage {
17
- base64: string
18
- width: number
19
- height: number
20
- format: string
21
- }
22
-
23
- export interface CompressImageOptions {
24
- maxSizeMB?: number
25
- maxWidthOrHeight?: number
26
- }
27
-
28
- export interface ProcessImageInput {
29
- imageBytes: Uint8Array
30
- targetWidth: number
31
- targetHeight: number
32
- outputFormat?: 'jpeg' | 'png' | 'webp'
33
- quality?: number
34
- }
35
-
36
- export interface ProcessImageOutput {
37
- bytes: Uint8Array
38
- width: number
39
- height: number
40
- format: string
41
- }
42
-
43
- export interface ProcessImageActionInput {
44
- base64Image: string
45
- targetWidth: number
46
- targetHeight: number
47
- cropArea?: CropArea
48
- }
49
-
50
- export interface ProcessImageActionOutput {
51
- success: boolean
52
- base64Image?: string
53
- error?: string
54
- }
1
+ export interface ImageConfig {
2
+ width: number
3
+ height: number
4
+ aspectRatio: number
5
+ label?: string
6
+ }
7
+
8
+ export interface CropArea {
9
+ x: number
10
+ y: number
11
+ width: number
12
+ height: number
13
+ unit?: '%' | 'px'
14
+ }
15
+
16
+ export interface ProcessedImage {
17
+ base64: string
18
+ width: number
19
+ height: number
20
+ format: string
21
+ }
22
+
23
+ export interface CompressImageOptions {
24
+ maxSizeMB?: number
25
+ maxWidthOrHeight?: number
26
+ }
27
+
28
+ export interface ProcessImageInput {
29
+ imageBytes: Uint8Array
30
+ targetWidth: number
31
+ targetHeight: number
32
+ outputFormat?: 'jpeg' | 'png' | 'webp'
33
+ quality?: number
34
+ }
35
+
36
+ export interface ProcessImageOutput {
37
+ bytes: Uint8Array
38
+ width: number
39
+ height: number
40
+ format: string
41
+ }
42
+
43
+ export interface ProcessImageActionInput {
44
+ base64Image: string
45
+ targetWidth: number
46
+ targetHeight: number
47
+ cropArea?: CropArea
48
+ }
49
+
50
+ export interface ProcessImageActionOutput {
51
+ success: boolean
52
+ base64Image?: string
53
+ error?: string
54
+ }
@@ -1,26 +1,26 @@
1
- /**
2
- * Converts a base64 string to a File object
3
- */
4
- export function base64ToFile(base64: string, filename: string): File {
5
- const arr = base64.split(',')
6
- const mime = arr[0].match(/:(.*?);/)?.[1] || 'image/webp'
7
- const bstr = atob(arr[1])
8
- let n = bstr.length
9
- const u8arr = new Uint8Array(n)
10
- while (n--) {
11
- u8arr[n] = bstr.charCodeAt(n)
12
- }
13
- return new File([u8arr], filename, { type: mime })
14
- }
15
-
16
- /**
17
- * Converts a File to a base64 string
18
- */
19
- export function fileToBase64(file: File): Promise<string> {
20
- return new Promise((resolve, reject) => {
21
- const reader = new FileReader()
22
- reader.onload = () => resolve(reader.result as string)
23
- reader.onerror = reject
24
- reader.readAsDataURL(file)
25
- })
26
- }
1
+ /**
2
+ * Converts a base64 string to a File object
3
+ */
4
+ export function base64ToFile(base64: string, filename: string): File {
5
+ const arr = base64.split(',')
6
+ const mime = arr[0].match(/:(.*?);/)?.[1] || 'image/webp'
7
+ const bstr = atob(arr[1])
8
+ let n = bstr.length
9
+ const u8arr = new Uint8Array(n)
10
+ while (n--) {
11
+ u8arr[n] = bstr.charCodeAt(n)
12
+ }
13
+ return new File([u8arr], filename, { type: mime })
14
+ }
15
+
16
+ /**
17
+ * Converts a File to a base64 string
18
+ */
19
+ export function fileToBase64(file: File): Promise<string> {
20
+ return new Promise((resolve, reject) => {
21
+ const reader = new FileReader()
22
+ reader.onload = () => resolve(reader.result as string)
23
+ reader.onerror = reject
24
+ reader.readAsDataURL(file)
25
+ })
26
+ }
@@ -1,20 +1,20 @@
1
- import imageCompression from 'browser-image-compression'
2
- import type { CompressImageOptions } from '../types/image.type'
3
-
4
- export async function compressImage(
5
- file: File,
6
- options: CompressImageOptions = {}
7
- ): Promise<File> {
8
- const { maxSizeMB = 1, maxWidthOrHeight = 1920 } = options
9
-
10
- if (file.size <= maxSizeMB * 1024 * 1024) {
11
- return file
12
- }
13
-
14
- return imageCompression(file, {
15
- maxSizeMB,
16
- maxWidthOrHeight,
17
- useWebWorker: true,
18
- fileType: file.type as 'image/jpeg' | 'image/png' | 'image/webp',
19
- })
20
- }
1
+ import imageCompression from 'browser-image-compression'
2
+ import type { CompressImageOptions } from '../types/image.type'
3
+
4
+ export async function compressImage(
5
+ file: File,
6
+ options: CompressImageOptions = {}
7
+ ): Promise<File> {
8
+ const { maxSizeMB = 1, maxWidthOrHeight = 1920 } = options
9
+
10
+ if (file.size <= maxSizeMB * 1024 * 1024) {
11
+ return file
12
+ }
13
+
14
+ return imageCompression(file, {
15
+ maxSizeMB,
16
+ maxWidthOrHeight,
17
+ useWebWorker: true,
18
+ fileType: file.type as 'image/jpeg' | 'image/png' | 'image/webp',
19
+ })
20
+ }