@greatapps/common 1.1.257 → 1.1.259

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 (301) hide show
  1. package/dist/components/account/AccountModals.mjs.map +1 -1
  2. package/dist/components/account/ConfigurationsMyAccountModal.mjs +2 -2
  3. package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -1
  4. package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
  5. package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -1
  6. package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
  7. package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
  8. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
  9. package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
  10. package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
  11. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
  12. package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
  13. package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
  14. package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
  15. package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
  16. package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
  17. package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
  18. package/dist/components/embeds/CrispEmbed.mjs.map +1 -1
  19. package/dist/components/embeds/FrillEmbed.mjs.map +1 -1
  20. package/dist/components/handlers/SearchParamsHandler.mjs.map +1 -1
  21. package/dist/components/layouts/AppMobileNavBar.mjs +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/UsersSelectorPopover.mjs +1 -1
  29. package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
  30. package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
  31. package/dist/components/modals/ModalManager.mjs.map +1 -1
  32. package/dist/components/modals/Modals.mjs.map +1 -1
  33. package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
  34. package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
  35. package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
  36. package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
  37. package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
  38. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  39. package/dist/components/ui/buttons/Button.mjs.map +1 -1
  40. package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
  41. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  42. package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
  43. package/dist/components/ui/data-display/Badge.mjs.map +1 -1
  44. package/dist/components/ui/data-display/Card.mjs.map +1 -1
  45. package/dist/components/ui/data-display/CardBrandIcons.mjs.map +1 -1
  46. package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
  47. package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
  48. package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
  49. package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
  50. package/dist/components/ui/data-display/Separator.mjs.map +1 -1
  51. package/dist/components/ui/data-display/Table.mjs.map +1 -1
  52. package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
  53. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
  54. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  55. package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
  56. package/dist/components/ui/feedback/Progress.mjs.map +1 -1
  57. package/dist/components/ui/feedback/Skeleton.mjs.map +1 -1
  58. package/dist/components/ui/feedback/Toast.mjs.map +1 -1
  59. package/dist/components/ui/form/Calendar.mjs.map +1 -1
  60. package/dist/components/ui/form/Checkbox.mjs.map +1 -1
  61. package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
  62. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  63. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  64. package/dist/components/ui/form/FormField.mjs.map +1 -1
  65. package/dist/components/ui/form/Input.mjs.map +1 -1
  66. package/dist/components/ui/form/InputOtp.mjs.map +1 -1
  67. package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
  68. package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
  69. package/dist/components/ui/form/Select.mjs +1 -1
  70. package/dist/components/ui/form/Select.mjs.map +1 -1
  71. package/dist/components/ui/form/Switch.mjs.map +1 -1
  72. package/dist/components/ui/form/Textarea.mjs.map +1 -1
  73. package/dist/components/ui/overlay/Command.mjs.map +1 -1
  74. package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
  75. package/dist/components/ui/overlay/Popover.mjs.map +1 -1
  76. package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
  77. package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
  78. package/dist/components/widgets/notifications/NotificationCard.mjs.map +1 -1
  79. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
  80. package/dist/hooks/useDebounce.mjs.map +1 -1
  81. package/dist/hooks/useDebounceState.mjs.map +1 -1
  82. package/dist/hooks/useDebouncedEffect.mjs.map +1 -1
  83. package/dist/index.mjs.map +1 -1
  84. package/dist/infra/utils/clsx.mjs.map +1 -1
  85. package/dist/infra/utils/parser.mjs.map +1 -1
  86. package/dist/infra/utils/percentage.mjs.map +1 -1
  87. package/dist/middleware.mjs.map +1 -1
  88. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  89. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  90. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  91. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  92. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  93. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  94. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  95. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  96. package/dist/modules/accounts/services/account.service.mjs.map +1 -1
  97. package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -1
  98. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  99. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  100. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  101. package/dist/modules/cards/actions/list-cards.action.mjs.map +1 -1
  102. package/dist/modules/cards/hooks/cards.hook.mjs.map +1 -1
  103. package/dist/modules/cards/services/cards.service.mjs.map +1 -1
  104. package/dist/modules/cards/types.mjs.map +1 -1
  105. package/dist/modules/ia-credits/actions/list-ia-credits.action.mjs.map +1 -1
  106. package/dist/modules/plans/actions/find-plan-by-id.action.mjs.map +1 -1
  107. package/dist/modules/plans/hooks/use-has-plan-addon.hook.mjs.map +1 -1
  108. package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
  109. package/dist/modules/plans/services/plans.service.mjs.map +1 -1
  110. package/dist/modules/plans/types/plan.type.mjs.map +1 -1
  111. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  112. package/dist/modules/projects/actions/list-all-account-users.action.mjs.map +1 -1
  113. package/dist/modules/projects/actions/list-available-users.action.mjs.map +1 -1
  114. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  115. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  116. package/dist/modules/projects/hooks/add-project-user.hook.mjs.map +1 -1
  117. package/dist/modules/projects/hooks/list-all-account-users.hook.mjs.map +1 -1
  118. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  119. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  120. package/dist/modules/projects/hooks/remove-project-user.hook.mjs.map +1 -1
  121. package/dist/modules/subscriptions/actions/calculate-subscription.action.mjs.map +1 -1
  122. package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
  123. package/dist/modules/subscriptions/actions/update-subscription-plan.action.mjs.map +1 -1
  124. package/dist/modules/subscriptions/constants/query-keys.constants.mjs.map +1 -1
  125. package/dist/modules/subscriptions/hooks/calculate-subscription.hook.mjs.map +1 -1
  126. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  127. package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
  128. package/dist/modules/subscriptions/hooks/update-subscription-plan.hook.mjs.map +1 -1
  129. package/dist/modules/subscriptions/types/calculate-subscription.type.mjs.map +1 -1
  130. package/dist/modules/subscriptions/utils/build-plan-extras.mjs.map +1 -1
  131. package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
  132. package/dist/modules/subscriptions/utils/resolve-plan-extras-prices.mjs.map +1 -1
  133. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
  134. package/dist/modules/users/action/list-messages.action.mjs.map +1 -1
  135. package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
  136. package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
  137. package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
  138. package/dist/modules/users/services/messages.service.mjs.map +1 -1
  139. package/dist/modules/whitelabel/actions/find-whitelabel-styles.action.mjs.map +1 -1
  140. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
  141. package/dist/modules/whitelabel/actions/revalidate-whitelabel-styles.action.mjs.map +1 -1
  142. package/dist/modules/whitelabel/actions/revalidate-whitelabel.action.mjs.map +1 -1
  143. package/dist/modules/whitelabel/services/whitelabel-styles.service.mjs.map +1 -1
  144. package/dist/providers/whitelabel.provider.mjs.map +1 -1
  145. package/dist/store/useAccountModals.mjs.map +1 -1
  146. package/dist/store/useBuyCreditsModal.mjs.map +1 -1
  147. package/dist/store/useModalManager.mjs.map +1 -1
  148. package/dist/utils/countries.mjs.map +1 -1
  149. package/dist/utils/safeServerAction.mjs.map +1 -1
  150. package/dist/utils/withAction.mjs.map +1 -1
  151. package/package.json +89 -89
  152. package/src/components/account/AccountModals.tsx +17 -17
  153. package/src/components/account/ConfigurationsMyAccountModal.tsx +150 -150
  154. package/src/components/account/ConfirmDeleteAccountModal.tsx +55 -55
  155. package/src/components/account/ConfirmGlobalPreferencesModal.tsx +66 -66
  156. package/src/components/account/DeleteAccountModal.tsx +130 -130
  157. package/src/components/account/DisableTwoFactorAuthModal.tsx +86 -86
  158. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +49 -49
  159. package/src/components/account/TwoFactorAuthModal.tsx +223 -223
  160. package/src/components/account/hooks/useChangePhoneForm.tsx +81 -81
  161. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +101 -101
  162. package/src/components/account/sections/ChangeEmailModal.tsx +225 -225
  163. package/src/components/account/sections/ChangePasswordSection.tsx +64 -64
  164. package/src/components/account/sections/ChangePhoneModal.tsx +231 -231
  165. package/src/components/account/sections/MyProfileSection.tsx +327 -327
  166. package/src/components/account/sections/PreferencesSection.tsx +273 -273
  167. package/src/components/account/sections/SecuritySection.tsx +160 -160
  168. package/src/components/embeds/CrispEmbed.tsx +101 -101
  169. package/src/components/embeds/FrillEmbed.tsx +119 -119
  170. package/src/components/handlers/SearchParamsHandler.tsx +61 -61
  171. package/src/components/layouts/AppMobileNavBar.tsx +118 -118
  172. package/src/components/layouts/AppNavBar.tsx +51 -51
  173. package/src/components/layouts/MdSideBarNavigation.tsx +56 -56
  174. package/src/components/layouts/NavBar.tsx +120 -120
  175. package/src/components/layouts/NotificationsPopover.tsx +115 -115
  176. package/src/components/layouts/ProfilePopover.tsx +164 -164
  177. package/src/components/layouts/UsersSelectorPopover.tsx +238 -238
  178. package/src/components/modals/BuyCreditsModal.tsx +301 -301
  179. package/src/components/modals/ModalManager.tsx +29 -29
  180. package/src/components/modals/Modals.tsx +26 -26
  181. package/src/components/navigation/CancelledSubscriptionBanner.tsx +69 -69
  182. package/src/components/navigation/NavItemsContext.ts +20 -20
  183. package/src/components/navigation/ProjectSelectorPopover.tsx +157 -157
  184. package/src/components/navigation/shells/TabsMobileShell.tsx +72 -72
  185. package/src/components/navigation/subcomponents/ProjectSelector.tsx +156 -156
  186. package/src/components/pages/notifications/Notifications.tsx +160 -160
  187. package/src/components/ui/buttons/Button.tsx +57 -57
  188. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  189. package/src/components/ui/buttons/CopyButton.tsx +54 -54
  190. package/src/components/ui/data-display/Accordion.tsx +81 -81
  191. package/src/components/ui/data-display/Badge.tsx +47 -47
  192. package/src/components/ui/data-display/Card.tsx +93 -93
  193. package/src/components/ui/data-display/CardBrandIcons.tsx +336 -336
  194. package/src/components/ui/data-display/CardItem.tsx +75 -75
  195. package/src/components/ui/data-display/Pagination.tsx +126 -126
  196. package/src/components/ui/data-display/PaymentInfoCard.tsx +186 -186
  197. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  198. package/src/components/ui/data-display/Separator.tsx +29 -29
  199. package/src/components/ui/data-display/Table.tsx +117 -117
  200. package/src/components/ui/data-display/Tabs.tsx +67 -67
  201. package/src/components/ui/feedback/CircularProgress.tsx +75 -75
  202. package/src/components/ui/feedback/DefaultCircularProgress.tsx +61 -61
  203. package/src/components/ui/feedback/LoadingOverlay.tsx +31 -31
  204. package/src/components/ui/feedback/Progress.tsx +40 -40
  205. package/src/components/ui/feedback/Skeleton.tsx +5 -5
  206. package/src/components/ui/feedback/Toast.tsx +101 -101
  207. package/src/components/ui/form/Calendar.tsx +228 -228
  208. package/src/components/ui/form/Checkbox.tsx +31 -31
  209. package/src/components/ui/form/ComboboxField.tsx +154 -154
  210. package/src/components/ui/form/DatePicker.tsx +97 -97
  211. package/src/components/ui/form/DateRangePicker.tsx +108 -108
  212. package/src/components/ui/form/FormField.tsx +131 -131
  213. package/src/components/ui/form/Input.tsx +20 -20
  214. package/src/components/ui/form/InputOtp.tsx +80 -80
  215. package/src/components/ui/form/PhoneInput.tsx +205 -205
  216. package/src/components/ui/form/RadioGroup.tsx +45 -45
  217. package/src/components/ui/form/Select.tsx +200 -200
  218. package/src/components/ui/form/Switch.tsx +32 -32
  219. package/src/components/ui/form/Textarea.tsx +19 -19
  220. package/src/components/ui/overlay/Command.tsx +185 -185
  221. package/src/components/ui/overlay/Dialog.tsx +151 -151
  222. package/src/components/ui/overlay/Popover.tsx +49 -49
  223. package/src/components/ui/overlay/Sheet.tsx +166 -166
  224. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  225. package/src/components/widgets/notifications/NotificationCard.tsx +68 -68
  226. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  227. package/src/hooks/useDebounce.ts +26 -26
  228. package/src/hooks/useDebounceState.ts +11 -11
  229. package/src/hooks/useDebouncedEffect.ts +69 -69
  230. package/src/index.ts +376 -376
  231. package/src/infra/utils/clsx.ts +6 -6
  232. package/src/infra/utils/parser.ts +52 -52
  233. package/src/infra/utils/percentage.ts +42 -42
  234. package/src/middleware.ts +4 -4
  235. package/src/modules/accounts/actions/account-management.action.ts +91 -91
  236. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  237. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  238. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  239. package/src/modules/accounts/hooks/current-account.hook.tsx +22 -22
  240. package/src/modules/accounts/hooks/useAccountManagement.ts +85 -85
  241. package/src/modules/accounts/hooks/useCurrencies.ts +15 -15
  242. package/src/modules/accounts/hooks/useTimezones.ts +15 -15
  243. package/src/modules/accounts/services/account.service.ts +236 -236
  244. package/src/modules/accounts/types.ts +214 -214
  245. package/src/modules/auth/actions/validate-session.action.ts +56 -56
  246. package/src/modules/auth/hooks/login.hook.tsx +13 -13
  247. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  248. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  249. package/src/modules/cards/actions/list-cards.action.ts +8 -8
  250. package/src/modules/cards/hooks/cards.hook.ts +14 -14
  251. package/src/modules/cards/services/cards.service.ts +32 -32
  252. package/src/modules/cards/types.ts +32 -32
  253. package/src/modules/ia-credits/actions/list-ia-credits.action.ts +8 -8
  254. package/src/modules/plans/actions/find-plan-by-id.action.ts +8 -8
  255. package/src/modules/plans/hooks/use-has-plan-addon.hook.ts +17 -17
  256. package/src/modules/plans/hooks/use-plan-by-id.hook.ts +13 -13
  257. package/src/modules/plans/services/plans.service.ts +36 -36
  258. package/src/modules/plans/types/plan.type.ts +21 -21
  259. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  260. package/src/modules/projects/actions/list-all-account-users.action.ts +9 -9
  261. package/src/modules/projects/actions/list-available-users.action.ts +9 -9
  262. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  263. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  264. package/src/modules/projects/hooks/add-project-user.hook.ts +69 -69
  265. package/src/modules/projects/hooks/list-all-account-users.hook.ts +34 -34
  266. package/src/modules/projects/hooks/list-available-users.hook.ts +33 -33
  267. package/src/modules/projects/hooks/list-project-users.hook.ts +33 -33
  268. package/src/modules/projects/hooks/remove-project-user.hook.ts +69 -69
  269. package/src/modules/subscriptions/actions/calculate-subscription.action.ts +9 -9
  270. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  271. package/src/modules/subscriptions/actions/update-subscription-plan.action.ts +26 -26
  272. package/src/modules/subscriptions/constants/query-keys.constants.ts +1 -1
  273. package/src/modules/subscriptions/hooks/calculate-subscription.hook.ts +13 -13
  274. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +19 -19
  275. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +16 -16
  276. package/src/modules/subscriptions/hooks/update-subscription-plan.hook.ts +25 -25
  277. package/src/modules/subscriptions/types/billing-period.type.ts +1 -1
  278. package/src/modules/subscriptions/types/calculate-subscription.type.ts +75 -75
  279. package/src/modules/subscriptions/utils/build-plan-extras.ts +56 -56
  280. package/src/modules/subscriptions/utils/periodicity.ts +52 -52
  281. package/src/modules/subscriptions/utils/resolve-plan-extras-prices.ts +23 -23
  282. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  283. package/src/modules/users/action/list-messages.action.ts +12 -12
  284. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  285. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  286. package/src/modules/users/hooks/messages.hook.ts +60 -60
  287. package/src/modules/users/services/messages.service.ts +48 -48
  288. package/src/modules/whitelabel/actions/find-whitelabel-styles.action.ts +14 -14
  289. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  290. package/src/modules/whitelabel/actions/revalidate-whitelabel-styles.action.ts +10 -10
  291. package/src/modules/whitelabel/actions/revalidate-whitelabel.action.ts +19 -19
  292. package/src/modules/whitelabel/schema.ts +83 -83
  293. package/src/modules/whitelabel/services/whitelabel-styles.service.ts +129 -129
  294. package/src/modules/whitelabel/styles-schema.ts +37 -37
  295. package/src/providers/whitelabel.provider.tsx +54 -54
  296. package/src/store/useAccountModals.ts +55 -55
  297. package/src/store/useBuyCreditsModal.ts +25 -25
  298. package/src/store/useModalManager.ts +104 -104
  299. package/src/utils/countries.ts +224 -224
  300. package/src/utils/safeServerAction.ts +21 -21
  301. package/src/utils/withAction.ts +13 -13
@@ -1,101 +1,101 @@
1
- 'use client';
2
-
3
- import { useState, useCallback, useEffect } from 'react';
4
- import { useMutation } from '@tanstack/react-query';
5
- import { toast } from 'sonner';
6
- import { Toast } from '../../ui/feedback/Toast';
7
- import { copyToClipboard } from '../../../utils/browser/clipboard';
8
- import {
9
- generateTwoFactorAction,
10
- confirmTwoFactorAction,
11
- } from '../../../modules/accounts/actions/account-management.action';
12
- import { withAction } from '../../../utils/withAction';
13
-
14
- type Step = 'code' | 'recovery';
15
-
16
- interface UseTwoFactorAuthFormProps {
17
- onSuccess?: () => void;
18
- open?: boolean;
19
- }
20
-
21
- export default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAuthFormProps = {}) {
22
- const [code, setCode] = useState('');
23
- const [step, setStep] = useState<Step>('code');
24
-
25
- const generateMutation = useMutation({
26
- mutationFn: withAction(generateTwoFactorAction),
27
- onError: () => {
28
- toast.custom((t) => (
29
- <Toast variant="error" message="Erro ao gerar QR Code. Tente novamente." toastId={t} />
30
- ));
31
- },
32
- });
33
-
34
- const confirmMutation = useMutation({
35
- mutationFn: withAction(confirmTwoFactorAction),
36
- onSuccess: () => {
37
- setStep('recovery');
38
- },
39
- onError: () => {
40
- toast.custom((t) => (
41
- <Toast variant="error" message="Erro ao confirmar código. Tente novamente." toastId={t} />
42
- ));
43
- },
44
- });
45
-
46
- const { mutate: triggerGenerate } = generateMutation;
47
-
48
- useEffect(() => {
49
- if (open) {
50
- triggerGenerate();
51
- }
52
- }, [open, triggerGenerate]);
53
-
54
- const generateFailed = generateMutation.isError;
55
-
56
- const isCodeComplete = code.length === 6;
57
-
58
- const handleSubmit = () => {
59
- if (!isCodeComplete) return;
60
- confirmMutation.mutate(code);
61
- };
62
-
63
- const handleFinalize = () => {
64
- onSuccess?.();
65
- setTimeout(resetForm, 300);
66
- };
67
-
68
- const handleCopyCodes = useCallback(async () => {
69
- const codes = generateMutation.data?.backupCodes ?? [];
70
- const success = await copyToClipboard(codes.join('\n'));
71
- if (success) {
72
- toast.custom((t) => (
73
- <Toast variant="success" message="Códigos copiados com sucesso" toastId={t} />
74
- ));
75
- }
76
- }, [generateMutation.data]);
77
-
78
- const resetForm = () => {
79
- setCode('');
80
- setStep('code');
81
- generateMutation.reset();
82
- confirmMutation.reset();
83
- };
84
-
85
- return {
86
- code,
87
- setCode,
88
- isCodeComplete,
89
- isGenerating: generateMutation.isPending,
90
- isConfirming: confirmMutation.isPending,
91
- generateFailed,
92
- retryGenerate: triggerGenerate,
93
- qrcode: generateMutation.data?.qrcode,
94
- backupCodes: generateMutation.data?.backupCodes ?? [],
95
- step,
96
- handleSubmit,
97
- handleFinalize,
98
- handleCopyCodes,
99
- resetForm,
100
- };
101
- }
1
+ 'use client';
2
+
3
+ import { useState, useCallback, useEffect } from 'react';
4
+ import { useMutation } from '@tanstack/react-query';
5
+ import { toast } from 'sonner';
6
+ import { Toast } from '../../ui/feedback/Toast';
7
+ import { copyToClipboard } from '../../../utils/browser/clipboard';
8
+ import {
9
+ generateTwoFactorAction,
10
+ confirmTwoFactorAction,
11
+ } from '../../../modules/accounts/actions/account-management.action';
12
+ import { withAction } from '../../../utils/withAction';
13
+
14
+ type Step = 'code' | 'recovery';
15
+
16
+ interface UseTwoFactorAuthFormProps {
17
+ onSuccess?: () => void;
18
+ open?: boolean;
19
+ }
20
+
21
+ export default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAuthFormProps = {}) {
22
+ const [code, setCode] = useState('');
23
+ const [step, setStep] = useState<Step>('code');
24
+
25
+ const generateMutation = useMutation({
26
+ mutationFn: withAction(generateTwoFactorAction),
27
+ onError: () => {
28
+ toast.custom((t) => (
29
+ <Toast variant="error" message="Erro ao gerar QR Code. Tente novamente." toastId={t} />
30
+ ));
31
+ },
32
+ });
33
+
34
+ const confirmMutation = useMutation({
35
+ mutationFn: withAction(confirmTwoFactorAction),
36
+ onSuccess: () => {
37
+ setStep('recovery');
38
+ },
39
+ onError: () => {
40
+ toast.custom((t) => (
41
+ <Toast variant="error" message="Erro ao confirmar código. Tente novamente." toastId={t} />
42
+ ));
43
+ },
44
+ });
45
+
46
+ const { mutate: triggerGenerate } = generateMutation;
47
+
48
+ useEffect(() => {
49
+ if (open) {
50
+ triggerGenerate();
51
+ }
52
+ }, [open, triggerGenerate]);
53
+
54
+ const generateFailed = generateMutation.isError;
55
+
56
+ const isCodeComplete = code.length === 6;
57
+
58
+ const handleSubmit = () => {
59
+ if (!isCodeComplete) return;
60
+ confirmMutation.mutate(code);
61
+ };
62
+
63
+ const handleFinalize = () => {
64
+ onSuccess?.();
65
+ setTimeout(resetForm, 300);
66
+ };
67
+
68
+ const handleCopyCodes = useCallback(async () => {
69
+ const codes = generateMutation.data?.backupCodes ?? [];
70
+ const success = await copyToClipboard(codes.join('\n'));
71
+ if (success) {
72
+ toast.custom((t) => (
73
+ <Toast variant="success" message="Códigos copiados com sucesso" toastId={t} />
74
+ ));
75
+ }
76
+ }, [generateMutation.data]);
77
+
78
+ const resetForm = () => {
79
+ setCode('');
80
+ setStep('code');
81
+ generateMutation.reset();
82
+ confirmMutation.reset();
83
+ };
84
+
85
+ return {
86
+ code,
87
+ setCode,
88
+ isCodeComplete,
89
+ isGenerating: generateMutation.isPending,
90
+ isConfirming: confirmMutation.isPending,
91
+ generateFailed,
92
+ retryGenerate: triggerGenerate,
93
+ qrcode: generateMutation.data?.qrcode,
94
+ backupCodes: generateMutation.data?.backupCodes ?? [],
95
+ step,
96
+ handleSubmit,
97
+ handleFinalize,
98
+ handleCopyCodes,
99
+ resetForm,
100
+ };
101
+ }
@@ -1,225 +1,225 @@
1
- 'use client';
2
-
3
- import { IconChevronLeft, IconX, IconMail } from '@tabler/icons-react';
4
- import { Button } from '../../ui/buttons/Button';
5
- import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';
6
- import { Separator } from '../../ui/data-display/Separator';
7
- import { InputOTP, InputOTPGroup, InputOTPSlot } from '../../ui/form/InputOtp';
8
- import { FormField } from '../../ui/form/FormField';
9
- import { formatTimer } from '../../../utils/format/masks';
10
- import { OTP_CODE_LENGTH } from '../../../utils/validators/account';
11
- import { useAuth } from '../../../providers/auth.provider';
12
- import { useInvalidateUser } from '../../../modules/auth/hooks/useUserQuery';
13
- import { confirmEmailChangeAction } from '../../../modules/accounts/actions/account-management.action';
14
- import useChangeEmailForm from '../hooks/useChangeEmailForm';
15
- import useOtpVerification from '../hooks/useOtpVerification';
16
-
17
- interface ChangeEmailModalProps {
18
- open: boolean;
19
- onClose: () => void;
20
- }
21
-
22
- export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
23
- const { user } = useAuth();
24
- const invalidateUser = useInvalidateUser();
25
-
26
- const {
27
- showVerification,
28
- emailToVerify,
29
- isSubmitting,
30
- errors,
31
- register,
32
- handleContinue,
33
- handleBack,
34
- resetForm,
35
- } = useChangeEmailForm();
36
-
37
- const handleSuccess = () => {
38
- invalidateUser();
39
- resetForm();
40
- onClose();
41
- };
42
-
43
- const {
44
- code,
45
- isLoading,
46
- hasError,
47
- timer,
48
- canResend,
49
- isValidLength,
50
- handleCodeChange,
51
- handleValidate,
52
- handleResend,
53
- reset: resetOtp,
54
- } = useOtpVerification({
55
- onSuccess: handleSuccess,
56
- successMessage: 'E-mail alterado com sucesso',
57
- validateFn: async (token) => {
58
- const result = await confirmEmailChangeAction(token, emailToVerify);
59
- return result.success;
60
- },
61
- resendFn: async () => {
62
- const { requestEmailChangeAction } = await import('../../../modules/accounts/actions/account-management.action');
63
- const result = await requestEmailChangeAction(emailToVerify);
64
- if (!result.success) {
65
- throw new Error(result.error);
66
- }
67
- },
68
- });
69
-
70
- const handleClose = () => {
71
- resetForm();
72
- resetOtp();
73
- onClose();
74
- };
75
-
76
- const handleBackFromVerification = () => {
77
- resetOtp();
78
- handleBack();
79
- };
80
-
81
- return (
82
- <Dialog open={open} onOpenChange={handleClose}>
83
- <DialogContent
84
- showCloseButton={false}
85
- overlayClassName="z-[1002]"
86
- className="flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-125 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%] z-[1003]"
87
- >
88
- {showVerification ? (
89
- <DialogHeader className="flex flex-row items-center justify-between px-4 py-3 border-b border-gray-200 lg:border-b-0">
90
- <Button variant="ghost" className="size-8! p-0" onClick={handleBackFromVerification}>
91
- <IconChevronLeft size={20} className="text-gray-950" />
92
- </Button>
93
- <DialogTitle className="paragraph-medium-semibold text-gray-950 text-center flex-1">
94
- Alterar e-mail
95
- </DialogTitle>
96
- <Button variant="ghost" className="size-8! p-0" onClick={handleClose}>
97
- <IconX size={18} className="text-gray-500" />
98
- </Button>
99
- </DialogHeader>
100
- ) : (
101
- <>
102
- <DialogHeader className="sr-only">
103
- <DialogTitle>Alterar e-mail</DialogTitle>
104
- </DialogHeader>
105
- <div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
106
- <span className="paragraph-medium-semibold text-gray-950 text-center">
107
- Alterar e-mail
108
- </span>
109
- <Button
110
- variant="ghost"
111
- className="absolute right-2 size-8! p-0"
112
- onClick={handleClose}
113
- >
114
- <IconX size={18} className="text-gray-500" />
115
- </Button>
116
- </div>
117
- </>
118
- )}
119
-
120
- <div className={`${showVerification ? 'w-full' : 'w-1/2'} h-0.75 bg-pages-300`} />
121
-
122
- {showVerification ? (
123
- <form
124
- onSubmit={(e) => {
125
- e.preventDefault();
126
- handleValidate();
127
- }}
128
- className="flex flex-col flex-1 lg:flex-none"
129
- >
130
- <div className="px-4 lg:px-5 py-5 lg:py-6 flex flex-col gap-4 flex-1 lg:flex-none">
131
- <div className="flex items-center justify-center size-12 bg-white rounded-lg shadow-xs border border-gray-200">
132
- <IconMail size={20} className="text-gray-950" />
133
- </div>
134
-
135
- <div className="flex flex-col gap-1">
136
- <h3 className="paragraph-medium-semibold text-gray-950">Código de validação</h3>
137
- <p className="paragraph-small-regular text-gray-600">
138
- Enviamos um código de validação para o E-mail{' '}
139
- <span className="font-semibold text-gray-950 break-all">{user?.email}.</span>
140
- </p>
141
- </div>
142
-
143
- <div className="flex flex-col gap-2">
144
- <InputOTP maxLength={OTP_CODE_LENGTH} value={code} onChange={handleCodeChange}>
145
- <InputOTPGroup className="flex flex-row gap-2">
146
- {[...Array(OTP_CODE_LENGTH)].map((_, i) => (
147
- <InputOTPSlot
148
- key={i}
149
- index={i}
150
- className={`uppercase text-2xl font-medium w-11 lg:w-12 h-13 lg:h-14 rounded-lg border bg-white shadow-none [&_div.animate-caret-blink]:bg-gray-950 ${hasError ? 'border-red-500' : 'border-gray-200'}`}
151
- />
152
- ))}
153
- </InputOTPGroup>
154
- </InputOTP>
155
- {hasError && (
156
- <p className="paragraph-small-regular text-red-500">Código incorreto</p>
157
- )}
158
- </div>
159
-
160
- {canResend ? (
161
- <button
162
- type="button"
163
- onClick={handleResend}
164
- className="paragraph-small-medium text-gray-950 underline cursor-pointer hover:text-gray-700 w-fit"
165
- >
166
- Reenviar código
167
- </button>
168
- ) : (
169
- <p className="paragraph-small-regular text-gray-500">
170
- Reenviar em{' '}
171
- <span className="paragraph-small-semibold text-gray-950">
172
- {formatTimer(timer)}
173
- </span>
174
- </p>
175
- )}
176
- </div>
177
-
178
- <Separator />
179
-
180
- <div className="flex items-center justify-between px-4 lg:px-5 py-4 lg:py-5 mt-auto lg:mt-0">
181
- <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
182
- Cancelar
183
- </Button>
184
- <Button className="h-10!" type="submit" disabled={!isValidLength || isLoading}>
185
- {isLoading ? 'Validando...' : 'Alterar e-mail'}
186
- </Button>
187
- </div>
188
- </form>
189
- ) : (
190
- <form onSubmit={handleContinue} className="flex flex-col flex-1 lg:flex-none">
191
- <div className="flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none">
192
- <div className="flex flex-col gap-1">
193
- <span className="paragraph-medium-semibold text-gray-950">
194
- Atualizar E-mail de contato
195
- </span>
196
- <span className="paragraph-small-regular text-gray-600">
197
- Informe o seu novo E-mail para manter seu contato atualizado.
198
- </span>
199
- </div>
200
-
201
- <FormField
202
- label="Novo e-mail"
203
- placeholder="Digite seu novo e-mail"
204
- type="email"
205
- {...register('email')}
206
- error={!!errors.email}
207
- errorMessage={errors.email?.message}
208
- leftIcon={IconMail}
209
- />
210
- </div>
211
-
212
- <div className="flex items-center justify-between p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0">
213
- <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
214
- Cancelar
215
- </Button>
216
- <Button className="h-10!" type="submit" disabled={isSubmitting}>
217
- {isSubmitting ? 'Enviando...' : 'Continuar'}
218
- </Button>
219
- </div>
220
- </form>
221
- )}
222
- </DialogContent>
223
- </Dialog>
224
- );
225
- }
1
+ 'use client';
2
+
3
+ import { IconChevronLeft, IconX, IconMail } from '@tabler/icons-react';
4
+ import { Button } from '../../ui/buttons/Button';
5
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';
6
+ import { Separator } from '../../ui/data-display/Separator';
7
+ import { InputOTP, InputOTPGroup, InputOTPSlot } from '../../ui/form/InputOtp';
8
+ import { FormField } from '../../ui/form/FormField';
9
+ import { formatTimer } from '../../../utils/format/masks';
10
+ import { OTP_CODE_LENGTH } from '../../../utils/validators/account';
11
+ import { useAuth } from '../../../providers/auth.provider';
12
+ import { useInvalidateUser } from '../../../modules/auth/hooks/useUserQuery';
13
+ import { confirmEmailChangeAction } from '../../../modules/accounts/actions/account-management.action';
14
+ import useChangeEmailForm from '../hooks/useChangeEmailForm';
15
+ import useOtpVerification from '../hooks/useOtpVerification';
16
+
17
+ interface ChangeEmailModalProps {
18
+ open: boolean;
19
+ onClose: () => void;
20
+ }
21
+
22
+ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
23
+ const { user } = useAuth();
24
+ const invalidateUser = useInvalidateUser();
25
+
26
+ const {
27
+ showVerification,
28
+ emailToVerify,
29
+ isSubmitting,
30
+ errors,
31
+ register,
32
+ handleContinue,
33
+ handleBack,
34
+ resetForm,
35
+ } = useChangeEmailForm();
36
+
37
+ const handleSuccess = () => {
38
+ invalidateUser();
39
+ resetForm();
40
+ onClose();
41
+ };
42
+
43
+ const {
44
+ code,
45
+ isLoading,
46
+ hasError,
47
+ timer,
48
+ canResend,
49
+ isValidLength,
50
+ handleCodeChange,
51
+ handleValidate,
52
+ handleResend,
53
+ reset: resetOtp,
54
+ } = useOtpVerification({
55
+ onSuccess: handleSuccess,
56
+ successMessage: 'E-mail alterado com sucesso',
57
+ validateFn: async (token) => {
58
+ const result = await confirmEmailChangeAction(token, emailToVerify);
59
+ return result.success;
60
+ },
61
+ resendFn: async () => {
62
+ const { requestEmailChangeAction } = await import('../../../modules/accounts/actions/account-management.action');
63
+ const result = await requestEmailChangeAction(emailToVerify);
64
+ if (!result.success) {
65
+ throw new Error(result.error);
66
+ }
67
+ },
68
+ });
69
+
70
+ const handleClose = () => {
71
+ resetForm();
72
+ resetOtp();
73
+ onClose();
74
+ };
75
+
76
+ const handleBackFromVerification = () => {
77
+ resetOtp();
78
+ handleBack();
79
+ };
80
+
81
+ return (
82
+ <Dialog open={open} onOpenChange={handleClose}>
83
+ <DialogContent
84
+ showCloseButton={false}
85
+ overlayClassName="z-[1002]"
86
+ className="flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-125 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%] z-[1003]"
87
+ >
88
+ {showVerification ? (
89
+ <DialogHeader className="flex flex-row items-center justify-between px-4 py-3 border-b border-gray-200 lg:border-b-0">
90
+ <Button variant="ghost" className="size-8! p-0" onClick={handleBackFromVerification}>
91
+ <IconChevronLeft size={20} className="text-gray-950" />
92
+ </Button>
93
+ <DialogTitle className="paragraph-medium-semibold text-gray-950 text-center flex-1">
94
+ Alterar e-mail
95
+ </DialogTitle>
96
+ <Button variant="ghost" className="size-8! p-0" onClick={handleClose}>
97
+ <IconX size={18} className="text-gray-500" />
98
+ </Button>
99
+ </DialogHeader>
100
+ ) : (
101
+ <>
102
+ <DialogHeader className="sr-only">
103
+ <DialogTitle>Alterar e-mail</DialogTitle>
104
+ </DialogHeader>
105
+ <div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
106
+ <span className="paragraph-medium-semibold text-gray-950 text-center">
107
+ Alterar e-mail
108
+ </span>
109
+ <Button
110
+ variant="ghost"
111
+ className="absolute right-2 size-8! p-0"
112
+ onClick={handleClose}
113
+ >
114
+ <IconX size={18} className="text-gray-500" />
115
+ </Button>
116
+ </div>
117
+ </>
118
+ )}
119
+
120
+ <div className={`${showVerification ? 'w-full' : 'w-1/2'} h-0.75 bg-pages-300`} />
121
+
122
+ {showVerification ? (
123
+ <form
124
+ onSubmit={(e) => {
125
+ e.preventDefault();
126
+ handleValidate();
127
+ }}
128
+ className="flex flex-col flex-1 lg:flex-none"
129
+ >
130
+ <div className="px-4 lg:px-5 py-5 lg:py-6 flex flex-col gap-4 flex-1 lg:flex-none">
131
+ <div className="flex items-center justify-center size-12 bg-white rounded-lg shadow-xs border border-gray-200">
132
+ <IconMail size={20} className="text-gray-950" />
133
+ </div>
134
+
135
+ <div className="flex flex-col gap-1">
136
+ <h3 className="paragraph-medium-semibold text-gray-950">Código de validação</h3>
137
+ <p className="paragraph-small-regular text-gray-600">
138
+ Enviamos um código de validação para o E-mail{' '}
139
+ <span className="font-semibold text-gray-950 break-all">{user?.email}.</span>
140
+ </p>
141
+ </div>
142
+
143
+ <div className="flex flex-col gap-2">
144
+ <InputOTP maxLength={OTP_CODE_LENGTH} value={code} onChange={handleCodeChange}>
145
+ <InputOTPGroup className="flex flex-row gap-2">
146
+ {[...Array(OTP_CODE_LENGTH)].map((_, i) => (
147
+ <InputOTPSlot
148
+ key={i}
149
+ index={i}
150
+ className={`uppercase text-2xl font-medium w-11 lg:w-12 h-13 lg:h-14 rounded-lg border bg-white shadow-none [&_div.animate-caret-blink]:bg-gray-950 ${hasError ? 'border-red-500' : 'border-gray-200'}`}
151
+ />
152
+ ))}
153
+ </InputOTPGroup>
154
+ </InputOTP>
155
+ {hasError && (
156
+ <p className="paragraph-small-regular text-red-500">Código incorreto</p>
157
+ )}
158
+ </div>
159
+
160
+ {canResend ? (
161
+ <button
162
+ type="button"
163
+ onClick={handleResend}
164
+ className="paragraph-small-medium text-gray-950 underline cursor-pointer hover:text-gray-700 w-fit"
165
+ >
166
+ Reenviar código
167
+ </button>
168
+ ) : (
169
+ <p className="paragraph-small-regular text-gray-500">
170
+ Reenviar em{' '}
171
+ <span className="paragraph-small-semibold text-gray-950">
172
+ {formatTimer(timer)}
173
+ </span>
174
+ </p>
175
+ )}
176
+ </div>
177
+
178
+ <Separator />
179
+
180
+ <div className="flex items-center justify-between px-4 lg:px-5 py-4 lg:py-5 mt-auto lg:mt-0">
181
+ <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
182
+ Cancelar
183
+ </Button>
184
+ <Button className="h-10!" type="submit" disabled={!isValidLength || isLoading}>
185
+ {isLoading ? 'Validando...' : 'Alterar e-mail'}
186
+ </Button>
187
+ </div>
188
+ </form>
189
+ ) : (
190
+ <form onSubmit={handleContinue} className="flex flex-col flex-1 lg:flex-none">
191
+ <div className="flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none">
192
+ <div className="flex flex-col gap-1">
193
+ <span className="paragraph-medium-semibold text-gray-950">
194
+ Atualizar E-mail de contato
195
+ </span>
196
+ <span className="paragraph-small-regular text-gray-600">
197
+ Informe o seu novo E-mail para manter seu contato atualizado.
198
+ </span>
199
+ </div>
200
+
201
+ <FormField
202
+ label="Novo e-mail"
203
+ placeholder="Digite seu novo e-mail"
204
+ type="email"
205
+ {...register('email')}
206
+ error={!!errors.email}
207
+ errorMessage={errors.email?.message}
208
+ leftIcon={IconMail}
209
+ />
210
+ </div>
211
+
212
+ <div className="flex items-center justify-between p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0">
213
+ <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
214
+ Cancelar
215
+ </Button>
216
+ <Button className="h-10!" type="submit" disabled={isSubmitting}>
217
+ {isSubmitting ? 'Enviando...' : 'Continuar'}
218
+ </Button>
219
+ </div>
220
+ </form>
221
+ )}
222
+ </DialogContent>
223
+ </Dialog>
224
+ );
225
+ }