@greatapps/common 1.1.699 → 1.1.700

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 (566) 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 +166 -0
  34. package/dist/components/modals/HexaPromoModal.mjs.map +1 -0
  35. package/dist/components/modals/HexaPromoModalGate.mjs +54 -0
  36. package/dist/components/modals/HexaPromoModalGate.mjs.map +1 -0
  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 +38 -32
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/infra/http/api-fetch.mjs.map +1 -1
  118. package/dist/infra/route/parse-id.mjs.map +1 -1
  119. package/dist/infra/route/parse-numeric.mjs.map +1 -1
  120. package/dist/infra/route/safe-route-handler.mjs.map +1 -1
  121. package/dist/infra/route/search-params.mjs.map +1 -1
  122. package/dist/infra/utils/array.mjs.map +1 -1
  123. package/dist/infra/utils/date.mjs.map +1 -1
  124. package/dist/middleware.mjs.map +1 -1
  125. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  126. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  127. package/dist/modules/accounts/actions/get-account-token.action.mjs.map +1 -1
  128. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  129. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  130. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  131. package/dist/modules/accounts/hooks/use-account-token.hook.mjs.map +1 -1
  132. package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -1
  133. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  134. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  135. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  136. package/dist/modules/accounts/hooks/useViaCep.mjs.map +1 -1
  137. package/dist/modules/accounts/services/account-token.service.mjs.map +1 -1
  138. package/dist/modules/accounts/services/account.service.mjs.map +1 -1
  139. package/dist/modules/auth/actions/social-google-login.action.mjs.map +1 -1
  140. package/dist/modules/auth/actions/social-google-onboarding.action.mjs.map +1 -1
  141. package/dist/modules/auth/actions/unlink-google.action.mjs.map +1 -1
  142. package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -1
  143. package/dist/modules/auth/actions/verify-two-factor.action.mjs.map +1 -1
  144. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  145. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  146. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  147. package/dist/modules/auth/hooks/social-google-login.hook.mjs.map +1 -1
  148. package/dist/modules/auth/hooks/social-google-onboarding.hook.mjs.map +1 -1
  149. package/dist/modules/auth/hooks/unlink-google.hook.mjs.map +1 -1
  150. package/dist/modules/auth/hooks/useManagementPermissions.mjs.map +1 -1
  151. package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -1
  152. package/dist/modules/auth/utils/assert-management-permission.mjs.map +1 -1
  153. package/dist/modules/auth/utils/assert-management-subscription.mjs.map +1 -1
  154. package/dist/modules/auth/utils/assert-paid-subscription.mjs.map +1 -1
  155. package/dist/modules/auth/utils/assert-subscription-addon.mjs.map +1 -1
  156. package/dist/modules/auth/utils/build-wl-override.mjs.map +1 -1
  157. package/dist/modules/auth/utils/require-token-not-expired.mjs.map +1 -1
  158. package/dist/modules/auth/utils/require-valid-session.mjs.map +1 -1
  159. package/dist/modules/cards/actions/create-card.action.mjs.map +1 -1
  160. package/dist/modules/cards/actions/create-setup-intent.action.mjs.map +1 -1
  161. package/dist/modules/cards/actions/delete-card.action.mjs.map +1 -1
  162. package/dist/modules/cards/actions/set-default-card.action.mjs.map +1 -1
  163. package/dist/modules/cards/handlers/find-card-by-id.handler.mjs.map +1 -1
  164. package/dist/modules/cards/handlers/list-cards.handler.mjs.map +1 -1
  165. package/dist/modules/cards/hooks/card-by-id.hook.mjs.map +1 -1
  166. package/dist/modules/cards/hooks/cards.hook.mjs.map +1 -1
  167. package/dist/modules/cards/hooks/create-card.hook.mjs.map +1 -1
  168. package/dist/modules/cards/hooks/create-setup-intent.hook.mjs.map +1 -1
  169. package/dist/modules/cards/hooks/delete-card.hook.mjs.map +1 -1
  170. package/dist/modules/cards/hooks/delete-confirmation.hook.mjs.map +1 -1
  171. package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
  172. package/dist/modules/cards/hooks/set-default-card.hook.mjs.map +1 -1
  173. package/dist/modules/cards/services/cards.service.mjs.map +1 -1
  174. package/dist/modules/cards/types.mjs.map +1 -1
  175. package/dist/modules/charges/actions/charge-action.action.mjs.map +1 -1
  176. package/dist/modules/charges/handlers/find-charge-by-id.handler.mjs.map +1 -1
  177. package/dist/modules/charges/handlers/list-charges.handler.mjs.map +1 -1
  178. package/dist/modules/charges/hooks/charge-action.hook.mjs.map +1 -1
  179. package/dist/modules/charges/hooks/charge-by-id.hook.mjs.map +1 -1
  180. package/dist/modules/charges/hooks/charges.hook.mjs.map +1 -1
  181. package/dist/modules/charges/services/charges.service.mjs.map +1 -1
  182. package/dist/modules/charges/types/charge.type.mjs.map +1 -1
  183. package/dist/modules/ia-credits/handlers/list-ia-credits.handler.mjs.map +1 -1
  184. package/dist/modules/ia-credits/hooks/ia-credits.hook.mjs.map +1 -1
  185. package/dist/modules/images/actions/process-image.action.mjs.map +1 -1
  186. package/dist/modules/images/constants/image.constants.mjs.map +1 -1
  187. package/dist/modules/images/hooks/use-image-upload.hook.mjs.map +1 -1
  188. package/dist/modules/images/services/image-processing.service.mjs.map +1 -1
  189. package/dist/modules/images/utils/base64.mjs.map +1 -1
  190. package/dist/modules/images/utils/compress-image.mjs.map +1 -1
  191. package/dist/modules/images/utils/crop-image.mjs.map +1 -1
  192. package/dist/modules/images/utils/validate-image.mjs.map +1 -1
  193. package/dist/modules/pages/constants/query-keys.constants.mjs.map +1 -1
  194. package/dist/modules/pages/handlers/count-pages.handler.mjs.map +1 -1
  195. package/dist/modules/pages/hooks/count-pages.hook.mjs.map +1 -1
  196. package/dist/modules/pages/services/pages.service.mjs.map +1 -1
  197. package/dist/modules/plans/handlers/find-plan-by-id.handler.mjs.map +1 -1
  198. package/dist/modules/plans/handlers/list-plans.handler.mjs.map +1 -1
  199. package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
  200. package/dist/modules/plans/hooks/use-has-plan-addon.hook.mjs.map +1 -1
  201. package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
  202. package/dist/modules/plans/services/plans.service.mjs.map +1 -1
  203. package/dist/modules/plans/types/plan.type.mjs.map +1 -1
  204. package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
  205. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  206. package/dist/modules/projects/actions/create-project.action.mjs.map +1 -1
  207. package/dist/modules/projects/actions/delete-project.action.mjs.map +1 -1
  208. package/dist/modules/projects/actions/find-project.action.mjs.map +1 -1
  209. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  210. package/dist/modules/projects/actions/list-projects.action.mjs.map +1 -1
  211. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  212. package/dist/modules/projects/actions/update-project.action.mjs.map +1 -1
  213. package/dist/modules/projects/handlers/find-project.handler.mjs.map +1 -1
  214. package/dist/modules/projects/handlers/list-all-account-users.handler.mjs.map +1 -1
  215. package/dist/modules/projects/handlers/list-available-users.handler.mjs.map +1 -1
  216. package/dist/modules/projects/handlers/list-project-users.handler.mjs.map +1 -1
  217. package/dist/modules/projects/handlers/list-projects.handler.mjs.map +1 -1
  218. package/dist/modules/projects/hooks/add-project-user.hook.mjs.map +1 -1
  219. package/dist/modules/projects/hooks/create-project.hook.mjs.map +1 -1
  220. package/dist/modules/projects/hooks/delete-project.hook.mjs.map +1 -1
  221. package/dist/modules/projects/hooks/find-project.hook.mjs.map +1 -1
  222. package/dist/modules/projects/hooks/list-all-account-users.hook.mjs.map +1 -1
  223. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  224. package/dist/modules/projects/hooks/list-infinite-projects.hook.mjs.map +1 -1
  225. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  226. package/dist/modules/projects/hooks/list-projects.hook.mjs.map +1 -1
  227. package/dist/modules/projects/hooks/remove-project-user.hook.mjs.map +1 -1
  228. package/dist/modules/projects/hooks/update-project.hook.mjs.map +1 -1
  229. package/dist/modules/projects/services/projects.service.mjs.map +1 -1
  230. package/dist/modules/subscriptions/actions/calculate-subscription.action.mjs.map +1 -1
  231. package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
  232. package/dist/modules/subscriptions/actions/update-subscription-payment.action.mjs.map +1 -1
  233. package/dist/modules/subscriptions/actions/update-subscription-plan.action.mjs.map +1 -1
  234. package/dist/modules/subscriptions/constants/query-keys.constants.mjs.map +1 -1
  235. package/dist/modules/subscriptions/constants/subscription.constants.mjs.map +1 -1
  236. package/dist/modules/subscriptions/handlers/list-subscriptions.handler.mjs.map +1 -1
  237. package/dist/modules/subscriptions/hooks/calculate-subscription.hook.mjs.map +1 -1
  238. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  239. package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
  240. package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs.map +1 -1
  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 +2 -0
  261. package/dist/providers/auth.provider.mjs.map +1 -1
  262. package/dist/providers/navigation.provider.mjs.map +1 -1
  263. package/dist/providers/whitelabel.provider.mjs.map +1 -1
  264. package/dist/route.mjs.map +1 -1
  265. package/dist/store/useAccountModals.mjs.map +1 -1
  266. package/dist/store/useBuyCreditsModal.mjs.map +1 -1
  267. package/dist/store/useCreditsDisabledModal.mjs.map +1 -1
  268. package/dist/store/useDesktopSidebarStore.mjs.map +1 -1
  269. package/dist/store/useHexaPromoModal.mjs +14 -0
  270. package/dist/store/useHexaPromoModal.mjs.map +1 -0
  271. package/dist/store/useMdSidebarStore.mjs.map +1 -1
  272. package/dist/store/usePaidPlanRequiredModal.mjs.map +1 -1
  273. package/dist/utils/constants/br-states.mjs.map +1 -1
  274. package/dist/utils/cookies/hexa-promo.mjs +88 -0
  275. package/dist/utils/cookies/hexa-promo.mjs.map +1 -0
  276. package/dist/utils/countries.mjs.map +1 -1
  277. package/dist/utils/format/currency.mjs.map +1 -1
  278. package/dist/utils/intl/cookie-domain.mjs.map +1 -1
  279. package/dist/utils/intl/locale-cookie.mjs.map +1 -1
  280. package/dist/utils/next-navigation.mjs.map +1 -1
  281. package/dist/utils/redirect.mjs.map +1 -1
  282. package/dist/utils/safeMutationAction.mjs.map +1 -1
  283. package/dist/utils/safeServerAction.mjs.map +1 -1
  284. package/dist/utils/withAction.mjs.map +1 -1
  285. package/package.json +115 -115
  286. package/src/components/account/ConfigurationsMyAccountModal.tsx +179 -179
  287. package/src/components/account/ConfirmDeleteAccountModal.tsx +110 -110
  288. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +68 -68
  289. package/src/components/account/DeleteAccountModal.tsx +160 -160
  290. package/src/components/account/DisableTwoFactorAuthModal.tsx +92 -92
  291. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +51 -51
  292. package/src/components/account/TwoFactorAuthModal.tsx +220 -220
  293. package/src/components/account/hooks/useChangePhoneForm.tsx +113 -113
  294. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +116 -116
  295. package/src/components/account/sections/ChangeEmailModal.tsx +239 -239
  296. package/src/components/account/sections/ChangePasswordSection.tsx +68 -68
  297. package/src/components/account/sections/ChangePhoneModal.tsx +273 -273
  298. package/src/components/account/sections/MyProfileSection.tsx +276 -276
  299. package/src/components/account/sections/PreferencesSection.tsx +278 -278
  300. package/src/components/account/sections/SecuritySection.tsx +102 -102
  301. package/src/components/account/sections/TokenSection.tsx +85 -85
  302. package/src/components/embeds/ClarityEmbed.tsx +70 -70
  303. package/src/components/embeds/CrispEmbed.tsx +195 -195
  304. package/src/components/embeds/EmbedWidgets.tsx +62 -62
  305. package/src/components/embeds/FrillEmbed.tsx +146 -146
  306. package/src/components/layouts/AppMobileNavBar.tsx +214 -214
  307. package/src/components/layouts/AppNavBar.tsx +40 -40
  308. package/src/components/layouts/MdSideBarNavigation.tsx +56 -56
  309. package/src/components/layouts/NavBar.tsx +228 -228
  310. package/src/components/layouts/NotificationsPopover.tsx +120 -120
  311. package/src/components/layouts/ProfilePopover.tsx +191 -191
  312. package/src/components/layouts/SideBarNavigation.tsx +65 -65
  313. package/src/components/layouts/UsersSelectorPopover.tsx +236 -236
  314. package/src/components/layouts/WhitelabelCodes.tsx +59 -59
  315. package/src/components/modals/BuyCreditsModal.tsx +390 -390
  316. package/src/components/modals/CreditsDisabledModal.tsx +62 -62
  317. package/src/components/modals/HexaPromoModal.tsx +212 -0
  318. package/src/components/modals/HexaPromoModalGate.tsx +80 -0
  319. package/src/components/modals/Modals.tsx +25 -25
  320. package/src/components/modals/PaidPlanRequiredModal.tsx +60 -60
  321. package/src/components/modals/cards/AddCardModal.tsx +420 -420
  322. package/src/components/modals/cards/CannotDeleteCardModal.tsx +124 -124
  323. package/src/components/modals/cards/CardFormFields.tsx +363 -363
  324. package/src/components/modals/cards/DeleteCardModal.tsx +136 -136
  325. package/src/components/navigation/CancelledSubscriptionBanner.tsx +62 -62
  326. package/src/components/navigation/NavItemsContext.ts +20 -20
  327. package/src/components/navigation/OverdueInvoiceBanner.tsx +51 -51
  328. package/src/components/navigation/PendingCancellationBanner.tsx +60 -60
  329. package/src/components/navigation/ProjectSelectorPopover.tsx +180 -180
  330. package/src/components/navigation/SubscriptionBanner.tsx +94 -94
  331. package/src/components/navigation/TrialBanner.tsx +54 -54
  332. package/src/components/navigation/UpcomingInvoiceBanner.tsx +55 -55
  333. package/src/components/navigation/shells/TabsMobileShell.tsx +74 -74
  334. package/src/components/navigation/subcomponents/BottomLinks.tsx +85 -85
  335. package/src/components/navigation/subcomponents/ProjectSelector.tsx +184 -184
  336. package/src/components/pages/NotFoundPage.tsx +75 -75
  337. package/src/components/pages/notifications/Notifications.tsx +190 -190
  338. package/src/components/ui/buttons/Button.tsx +77 -77
  339. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  340. package/src/components/ui/buttons/CopyButton.tsx +59 -59
  341. package/src/components/ui/data-display/Accordion.tsx +81 -81
  342. package/src/components/ui/data-display/Badge.tsx +47 -47
  343. package/src/components/ui/data-display/Card.tsx +93 -93
  344. package/src/components/ui/data-display/CardBrandIcons.tsx +336 -336
  345. package/src/components/ui/data-display/CardItem.tsx +135 -135
  346. package/src/components/ui/data-display/Pagination.tsx +126 -126
  347. package/src/components/ui/data-display/PaymentInfoCard.tsx +193 -193
  348. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  349. package/src/components/ui/data-display/Separator.tsx +29 -29
  350. package/src/components/ui/data-display/Table.tsx +117 -117
  351. package/src/components/ui/data-display/Tabs.tsx +67 -67
  352. package/src/components/ui/feedback/CircularProgress.tsx +79 -79
  353. package/src/components/ui/feedback/DefaultCircularProgress.tsx +67 -67
  354. package/src/components/ui/feedback/LoadingOverlay.tsx +30 -30
  355. package/src/components/ui/feedback/Progress.tsx +40 -40
  356. package/src/components/ui/feedback/Skeleton.tsx +5 -5
  357. package/src/components/ui/feedback/Toast.tsx +104 -104
  358. package/src/components/ui/form/Calendar.tsx +228 -228
  359. package/src/components/ui/form/Checkbox.tsx +31 -31
  360. package/src/components/ui/form/ComboboxField.tsx +159 -159
  361. package/src/components/ui/form/DatePicker.tsx +100 -100
  362. package/src/components/ui/form/DateRangePicker.tsx +111 -111
  363. package/src/components/ui/form/FormField.tsx +133 -133
  364. package/src/components/ui/form/Input.tsx +20 -20
  365. package/src/components/ui/form/InputOtp.tsx +80 -80
  366. package/src/components/ui/form/PhoneInput.tsx +210 -210
  367. package/src/components/ui/form/RadioGroup.tsx +45 -45
  368. package/src/components/ui/form/Select.tsx +200 -200
  369. package/src/components/ui/form/Switch.tsx +32 -32
  370. package/src/components/ui/form/Textarea.tsx +19 -19
  371. package/src/components/ui/overlay/Command.tsx +185 -185
  372. package/src/components/ui/overlay/Dialog.tsx +153 -153
  373. package/src/components/ui/overlay/Popover.tsx +49 -49
  374. package/src/components/ui/overlay/Sheet.tsx +170 -170
  375. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  376. package/src/components/widgets/ImageUpload/ImageCropModal.tsx +392 -392
  377. package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +62 -62
  378. package/src/components/widgets/ImageUpload/ImageUpload.tsx +131 -131
  379. package/src/components/widgets/ImageUpload/index.ts +3 -3
  380. package/src/components/widgets/notifications/NotificationCard.tsx +73 -73
  381. package/src/handlers.ts +22 -22
  382. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  383. package/src/hooks/useAuthQueryKey.ts +32 -32
  384. package/src/hooks/useBrandLoadingIcon.tsx +18 -18
  385. package/src/hooks/useRouter.ts +38 -38
  386. package/src/http.ts +1 -1
  387. package/src/i18n/config.ts +17 -17
  388. package/src/i18n/country-language.ts +60 -60
  389. package/src/i18n/messages/en-us.ts +519 -519
  390. package/src/i18n/messages/es-es.ts +520 -520
  391. package/src/i18n/messages/index.ts +24 -24
  392. package/src/i18n/messages/pt-br.ts +543 -543
  393. package/src/i18n/normalize.ts +15 -15
  394. package/src/i18n/resolve-locale.ts +77 -77
  395. package/src/i18n.ts +10 -10
  396. package/src/index.ts +587 -584
  397. package/src/infra/http/api-fetch.ts +39 -39
  398. package/src/infra/route/parse-id.ts +9 -9
  399. package/src/infra/route/parse-numeric.ts +16 -16
  400. package/src/infra/route/safe-route-handler.ts +16 -16
  401. package/src/infra/route/search-params.ts +9 -9
  402. package/src/infra/utils/array.ts +167 -167
  403. package/src/infra/utils/date.ts +59 -59
  404. package/src/middleware.ts +4 -4
  405. package/src/modules/accounts/actions/account-management.action.ts +109 -109
  406. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  407. package/src/modules/accounts/actions/get-account-token.action.ts +8 -8
  408. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  409. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  410. package/src/modules/accounts/hooks/current-account.hook.tsx +26 -26
  411. package/src/modules/accounts/hooks/use-account-token.hook.tsx +14 -14
  412. package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -32
  413. package/src/modules/accounts/hooks/useAccountManagement.ts +95 -95
  414. package/src/modules/accounts/hooks/useCurrencies.ts +18 -18
  415. package/src/modules/accounts/hooks/useTimezones.ts +18 -18
  416. package/src/modules/accounts/hooks/useViaCep.ts +25 -25
  417. package/src/modules/accounts/services/account-token.service.ts +52 -52
  418. package/src/modules/accounts/services/account.service.ts +243 -243
  419. package/src/modules/accounts/types.ts +230 -230
  420. package/src/modules/auth/actions/social-google-login.action.ts +12 -12
  421. package/src/modules/auth/actions/social-google-onboarding.action.ts +13 -13
  422. package/src/modules/auth/actions/unlink-google.action.ts +8 -8
  423. package/src/modules/auth/actions/validate-session.action.ts +70 -70
  424. package/src/modules/auth/actions/verify-two-factor.action.ts +19 -19
  425. package/src/modules/auth/hooks/login.hook.tsx +13 -13
  426. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  427. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  428. package/src/modules/auth/hooks/social-google-login.hook.tsx +13 -13
  429. package/src/modules/auth/hooks/social-google-onboarding.hook.tsx +13 -13
  430. package/src/modules/auth/hooks/unlink-google.hook.tsx +13 -13
  431. package/src/modules/auth/hooks/useManagementPermissions.ts +52 -52
  432. package/src/modules/auth/hooks/useUserQuery.ts +103 -103
  433. package/src/modules/auth/types/management-permission.type.ts +14 -14
  434. package/src/modules/auth/utils/assert-management-permission.ts +56 -56
  435. package/src/modules/auth/utils/assert-management-subscription.ts +38 -38
  436. package/src/modules/auth/utils/assert-paid-subscription.ts +47 -47
  437. package/src/modules/auth/utils/assert-subscription-addon.ts +42 -42
  438. package/src/modules/auth/utils/build-wl-override.ts +43 -43
  439. package/src/modules/auth/utils/require-token-not-expired.ts +53 -53
  440. package/src/modules/auth/utils/require-valid-session.ts +35 -35
  441. package/src/modules/cards/actions/create-card.action.ts +9 -9
  442. package/src/modules/cards/actions/create-setup-intent.action.ts +8 -8
  443. package/src/modules/cards/actions/delete-card.action.ts +8 -8
  444. package/src/modules/cards/actions/set-default-card.action.ts +8 -8
  445. package/src/modules/cards/handlers/find-card-by-id.handler.ts +15 -15
  446. package/src/modules/cards/handlers/list-cards.handler.ts +10 -10
  447. package/src/modules/cards/hooks/card-by-id.hook.ts +17 -17
  448. package/src/modules/cards/hooks/cards.hook.ts +22 -22
  449. package/src/modules/cards/hooks/create-card.hook.ts +30 -30
  450. package/src/modules/cards/hooks/create-setup-intent.hook.ts +11 -11
  451. package/src/modules/cards/hooks/delete-card.hook.ts +52 -52
  452. package/src/modules/cards/hooks/delete-confirmation.hook.ts +40 -40
  453. package/src/modules/cards/hooks/handle-delete-card.hook.ts +47 -47
  454. package/src/modules/cards/hooks/set-default-card.hook.ts +55 -55
  455. package/src/modules/cards/services/cards.service.ts +136 -136
  456. package/src/modules/cards/types.ts +52 -52
  457. package/src/modules/charges/actions/charge-action.action.ts +13 -13
  458. package/src/modules/charges/handlers/find-charge-by-id.handler.ts +14 -14
  459. package/src/modules/charges/handlers/list-charges.handler.ts +15 -15
  460. package/src/modules/charges/hooks/charge-action.hook.ts +24 -24
  461. package/src/modules/charges/hooks/charge-by-id.hook.ts +19 -19
  462. package/src/modules/charges/hooks/charges.hook.ts +19 -19
  463. package/src/modules/charges/services/charges.service.ts +63 -63
  464. package/src/modules/charges/types/charge.type.ts +68 -68
  465. package/src/modules/ia-credits/handlers/list-ia-credits.handler.ts +14 -14
  466. package/src/modules/ia-credits/hooks/ia-credits.hook.ts +103 -103
  467. package/src/modules/images/actions/process-image.action.ts +40 -40
  468. package/src/modules/images/constants/image.constants.ts +11 -11
  469. package/src/modules/images/hooks/use-image-upload.hook.ts +153 -153
  470. package/src/modules/images/services/image-processing.service.ts +75 -75
  471. package/src/modules/images/types/image.type.ts +54 -54
  472. package/src/modules/images/utils/base64.ts +26 -26
  473. package/src/modules/images/utils/compress-image.ts +20 -20
  474. package/src/modules/images/utils/crop-image.ts +68 -68
  475. package/src/modules/images/utils/validate-image.ts +86 -86
  476. package/src/modules/pages/constants/query-keys.constants.ts +1 -1
  477. package/src/modules/pages/handlers/count-pages.handler.ts +12 -12
  478. package/src/modules/pages/hooks/count-pages.hook.ts +21 -21
  479. package/src/modules/pages/services/pages.service.ts +27 -27
  480. package/src/modules/plans/handlers/find-plan-by-id.handler.ts +14 -14
  481. package/src/modules/plans/handlers/list-plans.handler.ts +22 -22
  482. package/src/modules/plans/hooks/list-plans.hook.ts +23 -23
  483. package/src/modules/plans/hooks/use-has-plan-addon.hook.ts +14 -14
  484. package/src/modules/plans/hooks/use-plan-by-id.hook.ts +39 -39
  485. package/src/modules/plans/services/plans.service.ts +136 -136
  486. package/src/modules/plans/types/plan.type.ts +79 -79
  487. package/src/modules/plans/utils/map-api-plan-to-ui.ts +167 -167
  488. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  489. package/src/modules/projects/actions/create-project.action.ts +9 -9
  490. package/src/modules/projects/actions/delete-project.action.ts +8 -8
  491. package/src/modules/projects/actions/find-project.action.ts +8 -8
  492. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  493. package/src/modules/projects/actions/list-projects.action.ts +16 -16
  494. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  495. package/src/modules/projects/actions/update-project.action.ts +9 -9
  496. package/src/modules/projects/handlers/find-project.handler.ts +15 -15
  497. package/src/modules/projects/handlers/list-all-account-users.handler.ts +23 -23
  498. package/src/modules/projects/handlers/list-available-users.handler.ts +26 -26
  499. package/src/modules/projects/handlers/list-project-users.handler.ts +26 -26
  500. package/src/modules/projects/handlers/list-projects.handler.ts +23 -23
  501. package/src/modules/projects/hooks/add-project-user.hook.ts +72 -72
  502. package/src/modules/projects/hooks/create-project.hook.ts +120 -120
  503. package/src/modules/projects/hooks/delete-project.hook.ts +58 -58
  504. package/src/modules/projects/hooks/find-project.hook.ts +18 -18
  505. package/src/modules/projects/hooks/list-all-account-users.hook.ts +40 -40
  506. package/src/modules/projects/hooks/list-available-users.hook.ts +39 -39
  507. package/src/modules/projects/hooks/list-infinite-projects.hook.ts +44 -44
  508. package/src/modules/projects/hooks/list-project-users.hook.ts +39 -39
  509. package/src/modules/projects/hooks/list-projects.hook.ts +23 -23
  510. package/src/modules/projects/hooks/remove-project-user.hook.ts +72 -72
  511. package/src/modules/projects/hooks/update-project.hook.ts +86 -86
  512. package/src/modules/projects/services/projects.service.ts +156 -156
  513. package/src/modules/subscriptions/actions/calculate-subscription.action.ts +9 -9
  514. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  515. package/src/modules/subscriptions/actions/update-subscription-payment.action.ts +13 -13
  516. package/src/modules/subscriptions/actions/update-subscription-plan.action.ts +14 -14
  517. package/src/modules/subscriptions/constants/query-keys.constants.ts +3 -3
  518. package/src/modules/subscriptions/constants/subscription.constants.ts +1 -1
  519. package/src/modules/subscriptions/handlers/list-subscriptions.handler.ts +17 -17
  520. package/src/modules/subscriptions/hooks/calculate-subscription.hook.ts +13 -13
  521. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +22 -22
  522. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +22 -22
  523. package/src/modules/subscriptions/hooks/update-subscription-payment.hook.ts +25 -25
  524. package/src/modules/subscriptions/hooks/update-subscription-plan.hook.ts +28 -28
  525. package/src/modules/subscriptions/hooks/use-cancelled-subscription-guard.ts +44 -44
  526. package/src/modules/subscriptions/types/billing-period.type.ts +1 -1
  527. package/src/modules/subscriptions/types/calculate-subscription.type.ts +116 -116
  528. package/src/modules/subscriptions/types/pix-pending.type.ts +38 -38
  529. package/src/modules/subscriptions/utils/build-plan-extras.ts +56 -56
  530. package/src/modules/subscriptions/utils/get-subscription-cancellation-state.ts +37 -37
  531. package/src/modules/subscriptions/utils/get-subscription-expiry-date.ts +33 -33
  532. package/src/modules/subscriptions/utils/has-subscription-expired.ts +11 -11
  533. package/src/modules/subscriptions/utils/periodicity.ts +79 -79
  534. package/src/modules/subscriptions/utils/resolve-plan-extras-prices.ts +23 -23
  535. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  536. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  537. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  538. package/src/modules/users/handlers/list-messages.handler.ts +39 -39
  539. package/src/modules/users/hooks/messages.hook.ts +69 -69
  540. package/src/modules/users/services/messages.service.ts +49 -49
  541. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  542. package/src/modules/whitelabel/actions/revalidate-whitelabel.action.ts +19 -19
  543. package/src/modules/whitelabel/schema.ts +84 -84
  544. package/src/modules/whitelabel/utils/normalize-hostname.ts +26 -26
  545. package/src/providers/auth.provider.tsx +267 -264
  546. package/src/providers/navigation.provider.tsx +99 -99
  547. package/src/providers/whitelabel.provider.tsx +90 -90
  548. package/src/route.ts +4 -4
  549. package/src/store/useAccountModals.ts +85 -85
  550. package/src/store/useBuyCreditsModal.ts +21 -21
  551. package/src/store/useCreditsDisabledModal.ts +11 -11
  552. package/src/store/useDesktopSidebarStore.ts +47 -47
  553. package/src/store/useHexaPromoModal.ts +13 -0
  554. package/src/store/useMdSidebarStore.ts +34 -34
  555. package/src/store/usePaidPlanRequiredModal.ts +19 -19
  556. package/src/utils/constants/br-states.ts +29 -29
  557. package/src/utils/cookies/hexa-promo.ts +114 -0
  558. package/src/utils/countries.ts +224 -224
  559. package/src/utils/format/currency.ts +70 -70
  560. package/src/utils/intl/cookie-domain.ts +29 -29
  561. package/src/utils/intl/locale-cookie.ts +18 -18
  562. package/src/utils/next-navigation.ts +7 -7
  563. package/src/utils/redirect.ts +78 -78
  564. package/src/utils/safeMutationAction.ts +24 -24
  565. package/src/utils/safeServerAction.ts +21 -21
  566. 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
+ }