@greatapps/common 1.1.675 → 1.1.677
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.
- package/dist/components/account/ConfigurationsMyAccountModal.mjs +8 -6
- package/dist/components/account/ConfigurationsMyAccountModal.mjs.map +1 -1
- package/dist/components/account/ConfirmDeleteAccountModal.mjs +20 -19
- package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/ConfirmGlobalPreferencesModal.mjs +10 -11
- package/dist/components/account/ConfirmGlobalPreferencesModal.mjs.map +1 -1
- package/dist/components/account/DeleteAccountModal.mjs +34 -28
- package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/DisableTwoFactorAuthModal.mjs +7 -5
- package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/IsntPossibleDeleteAccountModal.mjs +8 -9
- package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/TwoFactorAuthModal.mjs +22 -23
- package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/constants.mjs +4 -4
- package/dist/components/account/constants.mjs.map +1 -1
- package/dist/components/account/hooks/useChangeEmailForm.mjs +5 -3
- package/dist/components/account/hooks/useChangeEmailForm.mjs.map +1 -1
- package/dist/components/account/hooks/useChangePasswordForm.mjs +26 -3
- package/dist/components/account/hooks/useChangePasswordForm.mjs.map +1 -1
- package/dist/components/account/hooks/useChangePhoneForm.mjs +18 -9
- package/dist/components/account/hooks/useChangePhoneForm.mjs.map +1 -1
- package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs +26 -3
- package/dist/components/account/hooks/useDisableTwoFactorAuthForm.mjs.map +1 -1
- package/dist/components/account/hooks/useOtpVerification.mjs +19 -3
- package/dist/components/account/hooks/useOtpVerification.mjs.map +1 -1
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs +27 -4
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
- package/dist/components/account/sections/ChangeEmailModal.mjs +25 -28
- package/dist/components/account/sections/ChangeEmailModal.mjs.map +1 -1
- package/dist/components/account/sections/ChangePasswordSection.mjs +8 -6
- package/dist/components/account/sections/ChangePasswordSection.mjs.map +1 -1
- package/dist/components/account/sections/ChangePhoneModal.mjs +24 -27
- package/dist/components/account/sections/ChangePhoneModal.mjs.map +1 -1
- package/dist/components/account/sections/MyProfileSection.mjs +37 -22
- package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
- package/dist/components/account/sections/PreferencesSection.mjs +48 -24
- package/dist/components/account/sections/PreferencesSection.mjs.map +1 -1
- package/dist/components/account/sections/SecuritySection.mjs +11 -9
- package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
- package/dist/components/account/sections/TokenSection.mjs +24 -8
- package/dist/components/account/sections/TokenSection.mjs.map +1 -1
- package/dist/components/layouts/AppMobileNavBar.mjs +2 -148
- package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
- package/dist/components/layouts/NavBar.mjs +5 -3
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/components/layouts/NotificationsPopover.mjs +5 -3
- package/dist/components/layouts/NotificationsPopover.mjs.map +1 -1
- package/dist/components/layouts/ProfilePopover.mjs +6 -4
- package/dist/components/layouts/ProfilePopover.mjs.map +1 -1
- package/dist/components/layouts/UsersSelectorPopover.mjs +9 -7
- package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
- package/dist/components/modals/BuyCreditsModal.mjs +17 -18
- package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
- package/dist/components/modals/CreditsDisabledModal.mjs +6 -4
- package/dist/components/modals/CreditsDisabledModal.mjs.map +1 -1
- package/dist/components/modals/PaidPlanRequiredModal.mjs +5 -3
- package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
- package/dist/components/modals/cards/AddCardModal.mjs +64 -46
- package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CannotDeleteCardModal.mjs +9 -7
- package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CardFormFields.mjs +65 -51
- package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
- package/dist/components/modals/cards/DeleteCardModal.mjs +10 -8
- package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs +4 -2
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
- package/dist/components/navigation/OverdueInvoiceBanner.mjs +4 -2
- package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/PendingCancellationBanner.mjs +4 -6
- package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
- package/dist/components/navigation/ProjectSelectorPopover.mjs +8 -6
- package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
- package/dist/components/navigation/UpcomingInvoiceBanner.mjs +4 -6
- package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/BottomLinks.mjs +5 -3
- package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/CreditsCard.mjs +3 -1
- package/dist/components/navigation/subcomponents/CreditsCard.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/PlanCard.mjs +3 -1
- package/dist/components/navigation/subcomponents/PlanCard.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/ProjectSelector.mjs +5 -3
- package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
- package/dist/components/pages/NotFoundPage.mjs +5 -3
- package/dist/components/pages/NotFoundPage.mjs.map +1 -1
- package/dist/components/pages/notifications/Notifications.mjs +13 -10
- package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
- package/dist/components/ui/buttons/CopyButton.mjs +9 -5
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
- package/dist/components/ui/data-display/CardItem.mjs +7 -5
- package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
- package/dist/components/ui/data-display/PaymentInfoCard.mjs +10 -8
- package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
- package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs +3 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
- package/dist/components/ui/form/ComboboxField.mjs +11 -6
- package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
- package/dist/components/ui/form/DatePicker.mjs +5 -2
- package/dist/components/ui/form/DatePicker.mjs.map +1 -1
- package/dist/components/ui/form/DateRangePicker.mjs +5 -2
- package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
- package/dist/components/ui/form/PhoneInput.mjs +5 -3
- package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
- package/dist/components/ui/form/SelectField.mjs +6 -3
- package/dist/components/ui/form/SelectField.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageCropModal.mjs +11 -18
- package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs +6 -15
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
- package/dist/i18n/config.mjs +13 -0
- package/dist/i18n/config.mjs.map +1 -0
- package/dist/i18n/country-language.mjs +74 -0
- package/dist/i18n/country-language.mjs.map +1 -0
- package/dist/i18n/messages/en-us.mjs +494 -0
- package/dist/i18n/messages/en-us.mjs.map +1 -0
- package/dist/i18n/messages/es-es.mjs +494 -0
- package/dist/i18n/messages/es-es.mjs.map +1 -0
- package/dist/i18n/messages/index.mjs +16 -0
- package/dist/i18n/messages/index.mjs.map +1 -0
- package/dist/i18n/messages/pt-br.mjs +507 -0
- package/dist/i18n/messages/pt-br.mjs.map +1 -0
- package/dist/i18n/normalize.mjs +12 -0
- package/dist/i18n/normalize.mjs.map +1 -0
- package/dist/i18n/resolve-locale.mjs +42 -0
- package/dist/i18n/resolve-locale.mjs.map +1 -0
- package/dist/i18n.mjs +14 -0
- package/dist/i18n.mjs.map +1 -0
- package/dist/index.mjs +19 -3
- package/dist/index.mjs.map +1 -1
- package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs +20 -0
- package/dist/modules/accounts/hooks/use-currency-formatter.hook.mjs.map +1 -0
- package/dist/modules/cards/hooks/handle-delete-card.hook.mjs +2 -1
- package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
- package/dist/modules/images/utils/validate-image.mjs +8 -8
- package/dist/modules/images/utils/validate-image.mjs.map +1 -1
- package/dist/modules/plans/hooks/list-plans.hook.mjs +2 -2
- package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -1
- package/dist/modules/plans/types/plan.type.mjs +5 -1
- package/dist/modules/plans/types/plan.type.mjs.map +1 -1
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs +61 -35
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
- package/dist/modules/projects/services/projects.service.mjs +9 -0
- package/dist/modules/projects/services/projects.service.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/periodicity.mjs +20 -14
- package/dist/modules/subscriptions/utils/periodicity.mjs.map +1 -1
- package/dist/providers/auth.provider.mjs +9 -1
- package/dist/providers/auth.provider.mjs.map +1 -1
- package/dist/server.mjs +2 -0
- package/dist/server.mjs.map +1 -1
- package/dist/utils/format/currency.mjs +32 -4
- package/dist/utils/format/currency.mjs.map +1 -1
- package/dist/utils/intl/cookie-domain.mjs +17 -0
- package/dist/utils/intl/cookie-domain.mjs.map +1 -0
- package/dist/utils/intl/locale-cookie.mjs +13 -0
- package/dist/utils/intl/locale-cookie.mjs.map +1 -0
- package/dist/utils/intl/locales.mjs +3 -2
- package/dist/utils/intl/locales.mjs.map +1 -1
- package/package.json +7 -1
- package/src/components/account/ConfigurationsMyAccountModal.tsx +10 -6
- package/src/components/account/ConfirmDeleteAccountModal.tsx +22 -13
- package/src/components/account/ConfirmGlobalPreferencesModal.tsx +12 -10
- package/src/components/account/DeleteAccountModal.tsx +34 -24
- package/src/components/account/DisableTwoFactorAuthModal.tsx +11 -6
- package/src/components/account/IsntPossibleDeleteAccountModal.tsx +8 -6
- package/src/components/account/TwoFactorAuthModal.tsx +33 -29
- package/src/components/account/constants.ts +8 -5
- package/src/components/account/hooks/useChangeEmailForm.tsx +5 -3
- package/src/components/account/hooks/useChangePasswordForm.tsx +20 -6
- package/src/components/account/hooks/useChangePhoneForm.tsx +16 -10
- package/src/components/account/hooks/useDisableTwoFactorAuthForm.tsx +20 -6
- package/src/components/account/hooks/useOtpVerification.tsx +16 -4
- package/src/components/account/hooks/useTwoFactorAuthForm.tsx +21 -7
- package/src/components/account/sections/ChangeEmailModal.tsx +35 -21
- package/src/components/account/sections/ChangePasswordSection.tsx +10 -6
- package/src/components/account/sections/ChangePhoneModal.tsx +50 -22
- package/src/components/account/sections/MyProfileSection.tsx +37 -23
- package/src/components/account/sections/PreferencesSection.tsx +52 -25
- package/src/components/account/sections/SecuritySection.tsx +19 -10
- package/src/components/account/sections/TokenSection.tsx +22 -10
- package/src/components/layouts/AppMobileNavBar.tsx +1 -154
- package/src/components/layouts/NavBar.tsx +5 -3
- package/src/components/layouts/NotificationsPopover.tsx +5 -3
- package/src/components/layouts/ProfilePopover.tsx +6 -4
- package/src/components/layouts/UsersSelectorPopover.tsx +9 -7
- package/src/components/modals/BuyCreditsModal.tsx +18 -16
- package/src/components/modals/CreditsDisabledModal.tsx +6 -6
- package/src/components/modals/PaidPlanRequiredModal.tsx +5 -3
- package/src/components/modals/cards/AddCardModal.tsx +89 -62
- package/src/components/modals/cards/CannotDeleteCardModal.tsx +9 -8
- package/src/components/modals/cards/CardFormFields.tsx +93 -75
- package/src/components/modals/cards/DeleteCardModal.tsx +10 -8
- package/src/components/navigation/CancelledSubscriptionBanner.tsx +4 -2
- package/src/components/navigation/OverdueInvoiceBanner.tsx +4 -2
- package/src/components/navigation/PendingCancellationBanner.tsx +4 -2
- package/src/components/navigation/ProjectSelectorPopover.tsx +8 -6
- package/src/components/navigation/UpcomingInvoiceBanner.tsx +4 -2
- package/src/components/navigation/subcomponents/BottomLinks.tsx +5 -3
- package/src/components/navigation/subcomponents/CreditsCard.tsx +3 -1
- package/src/components/navigation/subcomponents/PlanCard.tsx +3 -1
- package/src/components/navigation/subcomponents/ProjectSelector.tsx +5 -3
- package/src/components/pages/NotFoundPage.tsx +5 -3
- package/src/components/pages/notifications/Notifications.tsx +13 -10
- package/src/components/ui/buttons/CopyButton.tsx +10 -5
- package/src/components/ui/data-display/CardItem.tsx +7 -5
- package/src/components/ui/data-display/PaymentInfoCard.tsx +10 -8
- package/src/components/ui/feedback/CircularProgress.tsx +4 -0
- package/src/components/ui/feedback/DefaultCircularProgress.tsx +3 -1
- package/src/components/ui/form/ComboboxField.tsx +11 -6
- package/src/components/ui/form/DatePicker.tsx +5 -2
- package/src/components/ui/form/DateRangePicker.tsx +5 -2
- package/src/components/ui/form/PhoneInput.tsx +5 -3
- package/src/components/ui/form/SelectField.tsx +6 -3
- package/src/components/widgets/ImageUpload/ImageCropModal.tsx +19 -11
- package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +6 -5
- package/src/i18n/config.ts +17 -0
- package/src/i18n/country-language.ts +60 -0
- package/src/i18n/messages/en-us.ts +514 -0
- package/src/i18n/messages/es-es.ts +515 -0
- package/src/i18n/messages/index.ts +24 -0
- package/src/i18n/messages/pt-br.ts +538 -0
- package/src/i18n/normalize.ts +15 -0
- package/src/i18n/resolve-locale.ts +77 -0
- package/src/i18n.ts +10 -0
- package/src/index.ts +13 -2
- package/src/modules/accounts/hooks/use-currency-formatter.hook.tsx +32 -0
- package/src/modules/cards/hooks/handle-delete-card.hook.ts +8 -3
- package/src/modules/images/utils/validate-image.ts +23 -8
- package/src/modules/plans/hooks/list-plans.hook.ts +2 -2
- package/src/modules/plans/types/plan.type.ts +4 -0
- package/src/modules/plans/utils/map-api-plan-to-ui.ts +109 -47
- package/src/modules/projects/services/projects.service.ts +12 -0
- package/src/modules/subscriptions/utils/periodicity.ts +29 -12
- package/src/providers/auth.provider.tsx +13 -1
- package/src/server.ts +2 -0
- package/src/utils/format/currency.ts +62 -7
- package/src/utils/intl/cookie-domain.ts +29 -0
- package/src/utils/intl/locale-cookie.ts +18 -0
- package/src/utils/intl/locales.ts +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/plans/utils/map-api-plan-to-ui.ts"],"sourcesContent":["import type {\n Plan,\n PlanFeature,\n PlanMainFeatures,\n PlanPricingByPeriod,\n UiPlan,\n} from \"../types/plan.type\";\nimport { ADDON_IDS } from \"../../subscriptions/constants/addons.constants\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/utils/map-api-plan-to-ui.ts"],"sourcesContent":["import type {\n Plan,\n PlanFeature,\n PlanMainFeatures,\n PlanPricingByPeriod,\n UiPlan,\n} from \"../types/plan.type\";\nimport { ADDON_IDS } from \"../../subscriptions/constants/addons.constants\";\nimport {\n formatCurrencyNumber,\n type CurrencyCode,\n} from \"../../../utils/format/currency\";\n\nexport type PlanBillingPeriod = \"monthly\" | \"semiannual\" | \"annual\";\n\ntype TranslateFn = (key: any, values?: Record<string, string | number>) => string;\n\nconst BASE_FEATURES_KEYS = [\n { icon: \"check\", key: \"plans.features.unlimitedVisits\", fallback: \"Visitas ilimitadas\" },\n { icon: \"check\", key: \"plans.features.unlimitedLeads\", fallback: \"Leads ilimitadas\" },\n { icon: \"check\", key: \"plans.features.sharePages\", fallback: \"Compartilhar páginas\", tooltip: \"sharePages\" },\n { icon: \"check\", key: \"plans.features.hosting\", fallback: \"Hospedagem inclusa\" },\n // SSL (HTTPS) + CDN — brand/acronym: never translated\n { icon: \"check\", key: null, fallback: \"SSL (HTTPS) + CDN\" },\n { icon: \"check\", key: \"plans.features.freeTemplates\", fallback: \"Templates gratuitos\" },\n] as const;\n\nfunction buildBaseFeatures(translate?: TranslateFn): PlanFeature[] {\n return BASE_FEATURES_KEYS.map(({ icon, key, fallback, ...rest }) => {\n const text = key && translate ? translate(`common.${key}`) : fallback;\n const feature: PlanFeature = { icon, text };\n if (\"tooltip\" in rest && rest.tooltip) feature.tooltip = rest.tooltip;\n return feature;\n });\n}\n\nfunction buildMainFeaturesFromItems(\n items: Plan[\"items\"],\n translate?: TranslateFn\n): PlanMainFeatures {\n const pagesItem = items.find((i) => i.id_addon === ADDON_IDS.PAGES);\n const domainsItem = items.find((i) => i.id_addon === ADDON_IDS.DOMAINS);\n\n const pagesQty = pagesItem?.quantity ?? 0;\n const domainsQty = domainsItem?.quantity ?? 1;\n\n let pages: string;\n if (pagesQty === 0) {\n pages = translate\n ? translate(\"common.plans.mainFeatures.pagesUnlimited\")\n : \"Páginas ilimitadas\";\n } else if (pagesQty === 1) {\n pages = translate\n ? translate(\"common.plans.mainFeatures.pageSingular\")\n : \"1 página\";\n } else {\n pages = translate\n ? translate(\"common.plans.mainFeatures.pagesPlural\", { count: pagesQty })\n : `${pagesQty} páginas`;\n }\n\n let domains: string;\n if (domainsQty >= 999) {\n domains = translate\n ? translate(\"common.plans.mainFeatures.domainsUnlimited\")\n : \"Domínios ilimitados\";\n } else if (domainsQty === 1) {\n domains = translate\n ? translate(\"common.plans.mainFeatures.domainSingular\")\n : \"1 domínio externo\";\n } else {\n domains = translate\n ? translate(\"common.plans.mainFeatures.domainsPlural\", { count: domainsQty })\n : `${domainsQty} domínios externos`;\n }\n\n const users = translate\n ? translate(\"common.plans.mainFeatures.usersUnlimited\")\n : \"Usuários ilimitados\";\n\n return { pages, domains, users };\n}\n\nfunction computePricingByPeriod(apiPlan: Plan, currency: CurrencyCode): PlanPricingByPeriod {\n // Conta USD usa value_usd; fallback pro value (BRL) evita NaN quando o operador ainda\n // não cadastrou o preço internacional. Os descontos por período são percentuais — aplicam igual.\n const monthly = currency === \"usd\" ? (apiPlan.value_usd ?? apiPlan.value) : apiPlan.value;\n const round2 = (n: number) => Math.round(n * 100) / 100;\n return {\n monthly,\n semiannual: round2(monthly * (1 - apiPlan.discount_semester / 100)),\n annual: round2(monthly * (1 - apiPlan.discount_annual / 100)),\n };\n}\n\nfunction buildUiPlan(plan: Plan, currency: CurrencyCode, translate?: TranslateFn): UiPlan {\n const popular = plan.id === 2 || plan.id_plan === 2;\n const buttonVariant = popular ? \"brand\" : \"default\";\n\n const pricingByPeriod = computePricingByPeriod(plan, currency);\n const monthlyFinal = pricingByPeriod.monthly;\n\n const lowerName = plan.name.toLowerCase();\n const hasProjectAndOnboarding =\n lowerName.includes(\"agência\") || lowerName.includes(\"agencia\");\n\n const onboardingText = translate\n ? translate(\"common.plans.features.onboarding\")\n : \"Reunião de Onboarding\";\n const projectMgmtText = translate\n ? translate(\"common.plans.features.projectManagement\")\n : \"Gestão de projetos\";\n\n const features: PlanFeature[] = [\n ...buildBaseFeatures(translate),\n hasProjectAndOnboarding\n ? { icon: \"check\", text: onboardingText }\n : { icon: \"x\", text: onboardingText, disabled: true },\n hasProjectAndOnboarding\n ? { icon: \"check\", text: projectMgmtText, tooltip: \"projectManagement\" }\n : { icon: \"x\", text: projectMgmtText, disabled: true, tooltip: \"projectManagement\" },\n ];\n\n const currencyAwareItems = plan.items.map((item) => ({\n ...item,\n value: currency === \"usd\" ? (item.value_usd ?? item.value) : item.value,\n }));\n\n return {\n planId: plan.id,\n name: plan.name,\n isPopular: popular,\n buttonVariant,\n mainFeatures: buildMainFeaturesFromItems(plan.items, translate),\n features,\n originalPrice: formatCurrencyNumber(monthlyFinal, 2, currency),\n price: formatCurrencyNumber(monthlyFinal, 2, currency),\n pricingByPeriod,\n items: currencyAwareItems,\n };\n}\n\n/**\n * Mapeia um plano da API para UiPlan em BRL.\n * Assinatura de 1 argumento — seguro em `plans.map(mapApiPlanToUiPlan)`.\n * Passa `translate` opcional para i18n; sem ele cai nos literais pt-br (back-compat).\n */\nexport function mapApiPlanToUiPlan(plan: Plan, translate?: TranslateFn): UiPlan {\n return buildUiPlan(plan, \"brl\", translate);\n}\n\n/**\n * Variante currency-aware: a moeda vem do gateway da conta (getCurrencyForGateway).\n * Fábrica para uso ergonômico em `.map`: `plans.map(mapApiPlanToUiPlanForCurrency(currency, translate))`.\n * Mantida separada de mapApiPlanToUiPlan para não quebrar callers que passam a fn direto pro `.map`.\n */\nexport const mapApiPlanToUiPlanForCurrency =\n (currency: CurrencyCode, translate?: TranslateFn) =>\n (plan: Plan): UiPlan =>\n buildUiPlan(plan, currency, translate);\n"],"mappings":"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","names":[]}
|
|
@@ -83,6 +83,15 @@ class ProjectsService {
|
|
|
83
83
|
const response = await api.apps.delete(url, {
|
|
84
84
|
body: JSON.stringify({ id_project_to_move: moveToProjectId })
|
|
85
85
|
});
|
|
86
|
+
if (response == null) {
|
|
87
|
+
console.warn("[ProjectsService.delete] null response treated as success", {
|
|
88
|
+
id_account,
|
|
89
|
+
id_user,
|
|
90
|
+
projectId,
|
|
91
|
+
moveToProjectId
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
86
95
|
if (response.status === 0) {
|
|
87
96
|
throw new ApiError(
|
|
88
97
|
response.message || "Erro ao deletar projeto",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/projects/services/projects.service.ts"],"sourcesContent":["import 'server-only';\n\nimport { api } from '../../../infra/api/client';\nimport { ApiError } from '../../../infra/api/types';\nimport { buildQueryParams } from '../../../infra/utils/params';\nimport { getUserContext } from '../../auth/utils/get-user-context';\nimport { assertManagementSubscription } from '../../auth/utils/assert-management-subscription';\nimport {\n Project,\n ProjectSchema,\n ProjectsPage,\n CreateProjectRequest,\n UpdateProjectRequest,\n} from '../types';\n\ninterface ApiListResponse<T> {\n data: T[];\n total: number;\n status: number;\n message?: string;\n}\n\ninterface ApiMutationResponse {\n status: number;\n message?: string;\n data?: Project[];\n}\n\ninterface ListProjectsParams {\n page?: number;\n limit?: number;\n sort?: string;\n search?: string;\n deleted?: number;\n}\n\nclass ProjectsService {\n async list(params: ListProjectsParams = {}): Promise<ProjectsPage> {\n const { id_account, id_user } = await getUserContext();\n const query = buildQueryParams(params as Record<string, string | number | boolean | undefined>);\n const url = `/account/${id_account}/user/${id_user}/projects${query ? `?${query}` : ''}`;\n\n const response = await api.apps.get<ApiListResponse<Project>>(url);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao listar projetos',\n 'LIST_PROJECTS_FAILED',\n 400\n );\n }\n\n return {\n data: (response.data || []).map((item) => ProjectSchema.parse(item)),\n total: response.total || 0,\n page: params.page ?? 1,\n };\n }\n\n async findById(projectId: number): Promise<Project> {\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects/${projectId}`;\n\n const response = await api.apps.get<ApiMutationResponse>(url);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao buscar projeto',\n 'FIND_PROJECT_FAILED',\n 400\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError('Projeto não encontrado', 'PROJECT_NOT_FOUND', 404);\n }\n\n return ProjectSchema.parse(response.data[0]);\n }\n\n async create(data: CreateProjectRequest): Promise<Project> {\n await assertManagementSubscription();\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects`;\n\n const response = await api.apps.post<ApiMutationResponse>(url, data);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao criar projeto',\n 'CREATE_PROJECT_FAILED',\n 400\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError('Resposta inválida ao criar projeto', 'INVALID_RESPONSE', 500);\n }\n\n return ProjectSchema.parse(response.data[0]);\n }\n\n async update(projectId: number, data: UpdateProjectRequest): Promise<Project> {\n await assertManagementSubscription();\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects/${projectId}`;\n\n const response = await api.apps.put<ApiMutationResponse>(url, data);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao atualizar projeto',\n 'UPDATE_PROJECT_FAILED',\n 400\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError('Resposta inválida ao atualizar projeto', 'INVALID_RESPONSE', 500);\n }\n\n return ProjectSchema.parse(response.data[0]);\n }\n\n async delete(projectId: number, moveToProjectId: number): Promise<void> {\n await assertManagementSubscription();\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects/${projectId}`;\n\n const response = await api.apps.delete<ApiMutationResponse>(url, {\n body: JSON.stringify({ id_project_to_move: moveToProjectId }),\n });\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao deletar projeto',\n 'DELETE_PROJECT_FAILED',\n 400\n );\n }\n }\n}\n\nexport const projectsService = new ProjectsService();\n"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/projects/services/projects.service.ts"],"sourcesContent":["import 'server-only';\n\nimport { api } from '../../../infra/api/client';\nimport { ApiError } from '../../../infra/api/types';\nimport { buildQueryParams } from '../../../infra/utils/params';\nimport { getUserContext } from '../../auth/utils/get-user-context';\nimport { assertManagementSubscription } from '../../auth/utils/assert-management-subscription';\nimport {\n Project,\n ProjectSchema,\n ProjectsPage,\n CreateProjectRequest,\n UpdateProjectRequest,\n} from '../types';\n\ninterface ApiListResponse<T> {\n data: T[];\n total: number;\n status: number;\n message?: string;\n}\n\ninterface ApiMutationResponse {\n status: number;\n message?: string;\n data?: Project[];\n}\n\ninterface ListProjectsParams {\n page?: number;\n limit?: number;\n sort?: string;\n search?: string;\n deleted?: number;\n}\n\nclass ProjectsService {\n async list(params: ListProjectsParams = {}): Promise<ProjectsPage> {\n const { id_account, id_user } = await getUserContext();\n const query = buildQueryParams(params as Record<string, string | number | boolean | undefined>);\n const url = `/account/${id_account}/user/${id_user}/projects${query ? `?${query}` : ''}`;\n\n const response = await api.apps.get<ApiListResponse<Project>>(url);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao listar projetos',\n 'LIST_PROJECTS_FAILED',\n 400\n );\n }\n\n return {\n data: (response.data || []).map((item) => ProjectSchema.parse(item)),\n total: response.total || 0,\n page: params.page ?? 1,\n };\n }\n\n async findById(projectId: number): Promise<Project> {\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects/${projectId}`;\n\n const response = await api.apps.get<ApiMutationResponse>(url);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao buscar projeto',\n 'FIND_PROJECT_FAILED',\n 400\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError('Projeto não encontrado', 'PROJECT_NOT_FOUND', 404);\n }\n\n return ProjectSchema.parse(response.data[0]);\n }\n\n async create(data: CreateProjectRequest): Promise<Project> {\n await assertManagementSubscription();\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects`;\n\n const response = await api.apps.post<ApiMutationResponse>(url, data);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao criar projeto',\n 'CREATE_PROJECT_FAILED',\n 400\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError('Resposta inválida ao criar projeto', 'INVALID_RESPONSE', 500);\n }\n\n return ProjectSchema.parse(response.data[0]);\n }\n\n async update(projectId: number, data: UpdateProjectRequest): Promise<Project> {\n await assertManagementSubscription();\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects/${projectId}`;\n\n const response = await api.apps.put<ApiMutationResponse>(url, data);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao atualizar projeto',\n 'UPDATE_PROJECT_FAILED',\n 400\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError('Resposta inválida ao atualizar projeto', 'INVALID_RESPONSE', 500);\n }\n\n return ProjectSchema.parse(response.data[0]);\n }\n\n async delete(projectId: number, moveToProjectId: number): Promise<void> {\n await assertManagementSubscription();\n const { id_account, id_user } = await getUserContext();\n const url = `/account/${id_account}/user/${id_user}/projects/${projectId}`;\n\n const response = await api.apps.delete<ApiMutationResponse>(url, {\n body: JSON.stringify({ id_project_to_move: moveToProjectId }),\n });\n\n // Alguns backends respondem `null` no delete quando a exclusão foi bem-sucedida.\n // Nesse caso não há payload para validar e o fluxo deve seguir sem erro.\n if (response == null) {\n console.warn('[ProjectsService.delete] null response treated as success', {\n id_account,\n id_user,\n projectId,\n moveToProjectId,\n });\n return;\n }\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao deletar projeto',\n 'DELETE_PROJECT_FAILED',\n 400\n );\n }\n }\n}\n\nexport const projectsService = new ProjectsService();\n"],"mappings":"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","names":[]}
|
|
@@ -9,21 +9,27 @@ function billingPeriodToNumeric(billingPeriod) {
|
|
|
9
9
|
if (billingPeriod === "annual") return 365;
|
|
10
10
|
return 30;
|
|
11
11
|
}
|
|
12
|
-
function getPeriodicityLabel(periodicity) {
|
|
12
|
+
function getPeriodicityLabel(periodicity, translate) {
|
|
13
13
|
const period = periodicityToBillingPeriod(periodicity);
|
|
14
|
-
if (period === "semiannual")
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
14
|
+
if (period === "semiannual")
|
|
15
|
+
return translate ? translate("common.periodicity.semiannual") : "Semestral";
|
|
16
|
+
if (period === "annual")
|
|
17
|
+
return translate ? translate("common.periodicity.annual") : "Anual";
|
|
18
|
+
return translate ? translate("common.periodicity.monthly") : "Mensal";
|
|
19
|
+
}
|
|
20
|
+
function getBillingPeriodSuffix(billingPeriod, translate) {
|
|
21
|
+
if (billingPeriod === "semiannual")
|
|
22
|
+
return translate ? translate("common.periodicity.suffixSemiannual") : "/semestre";
|
|
23
|
+
if (billingPeriod === "annual")
|
|
24
|
+
return translate ? translate("common.periodicity.suffixAnnual") : "/ano";
|
|
25
|
+
return translate ? translate("common.periodicity.suffixMonthly") : "/m\xEAs";
|
|
26
|
+
}
|
|
27
|
+
function getBillingPeriodLabel(billingPeriod, translate) {
|
|
28
|
+
if (billingPeriod === "semiannual")
|
|
29
|
+
return translate ? translate("common.periodicity.labelSemiannual") : "semestral";
|
|
30
|
+
if (billingPeriod === "annual")
|
|
31
|
+
return translate ? translate("common.periodicity.labelAnnual") : "anual";
|
|
32
|
+
return translate ? translate("common.periodicity.labelMonthly") : "mensal";
|
|
27
33
|
}
|
|
28
34
|
function getBillingPeriodMonths(billingPeriod) {
|
|
29
35
|
if (billingPeriod === "semiannual") return 6;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/subscriptions/utils/periodicity.ts"],"sourcesContent":["import type { BillingPeriod } from '../types/billing-period.type';\nimport type { CalculateSubscriptionResponse } from '../types/calculate-subscription.type';\n\nexport function periodicityToBillingPeriod(\n periodicity: number | string | null | undefined\n): BillingPeriod | null {\n if (periodicity === 30 || periodicity === 1 || periodicity === 'monthly') return 'monthly';\n if (periodicity === 180 || periodicity === 3 || periodicity === 'semiannual') return 'semiannual';\n if (periodicity === 365 || periodicity === 2 || periodicity === 'annual') return 'annual';\n return null;\n}\n\nexport function billingPeriodToNumeric(billingPeriod: BillingPeriod): 30 | 180 | 365 {\n if (billingPeriod === 'semiannual') return 180;\n if (billingPeriod === 'annual') return 365;\n return 30;\n}\n\nexport function getPeriodicityLabel(periodicity: number | string | null | undefined): string {\n const period = periodicityToBillingPeriod(periodicity);\n if (period === 'semiannual')
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/subscriptions/utils/periodicity.ts"],"sourcesContent":["import type { BillingPeriod } from '../types/billing-period.type';\nimport type { CalculateSubscriptionResponse } from '../types/calculate-subscription.type';\n\ntype TranslateFn = (key: any, values?: Record<string, string | number>) => string;\n\nexport function periodicityToBillingPeriod(\n periodicity: number | string | null | undefined\n): BillingPeriod | null {\n if (periodicity === 30 || periodicity === 1 || periodicity === 'monthly') return 'monthly';\n if (periodicity === 180 || periodicity === 3 || periodicity === 'semiannual') return 'semiannual';\n if (periodicity === 365 || periodicity === 2 || periodicity === 'annual') return 'annual';\n return null;\n}\n\nexport function billingPeriodToNumeric(billingPeriod: BillingPeriod): 30 | 180 | 365 {\n if (billingPeriod === 'semiannual') return 180;\n if (billingPeriod === 'annual') return 365;\n return 30;\n}\n\nexport function getPeriodicityLabel(\n periodicity: number | string | null | undefined,\n translate?: TranslateFn\n): string {\n const period = periodicityToBillingPeriod(periodicity);\n if (period === 'semiannual')\n return translate ? translate('common.periodicity.semiannual') : 'Semestral';\n if (period === 'annual')\n return translate ? translate('common.periodicity.annual') : 'Anual';\n return translate ? translate('common.periodicity.monthly') : 'Mensal';\n}\n\nexport function getBillingPeriodSuffix(\n billingPeriod: BillingPeriod,\n translate?: TranslateFn\n): string {\n if (billingPeriod === 'semiannual')\n return translate ? translate('common.periodicity.suffixSemiannual') : '/semestre';\n if (billingPeriod === 'annual')\n return translate ? translate('common.periodicity.suffixAnnual') : '/ano';\n return translate ? translate('common.periodicity.suffixMonthly') : '/mês';\n}\n\nexport function getBillingPeriodLabel(\n billingPeriod: BillingPeriod,\n translate?: TranslateFn\n): string {\n if (billingPeriod === 'semiannual')\n return translate ? translate('common.periodicity.labelSemiannual') : 'semestral';\n if (billingPeriod === 'annual')\n return translate ? translate('common.periodicity.labelAnnual') : 'anual';\n return translate ? translate('common.periodicity.labelMonthly') : 'mensal';\n}\n\nexport function getBillingPeriodMonths(billingPeriod: BillingPeriod): number {\n if (billingPeriod === 'semiannual') return 6;\n if (billingPeriod === 'annual') return 12;\n return 1;\n}\n\nexport function getPriceFromCalculatedData(\n data: CalculateSubscriptionResponse,\n periodicity: number | string | null | undefined\n): number {\n const period = periodicityToBillingPeriod(periodicity);\n if (period === 'annual') return data.year;\n if (period === 'semiannual') return data.semmester;\n return data.month;\n}\n\nexport function getOriginalPriceFromCalculatedData(\n data: CalculateSubscriptionResponse,\n periodicity: number | string | null | undefined\n): number {\n const period = periodicityToBillingPeriod(periodicity);\n if (period === 'annual') return data.year_original;\n if (period === 'semiannual') return data.semmester_original;\n return data.month_original;\n}\n"],"mappings":"AAKO,SAAS,2BACd,aACsB;AACtB,MAAI,gBAAgB,MAAM,gBAAgB,KAAK,gBAAgB,UAAW,QAAO;AACjF,MAAI,gBAAgB,OAAO,gBAAgB,KAAK,gBAAgB,aAAc,QAAO;AACrF,MAAI,gBAAgB,OAAO,gBAAgB,KAAK,gBAAgB,SAAU,QAAO;AACjF,SAAO;AACT;AAEO,SAAS,uBAAuB,eAA8C;AACnF,MAAI,kBAAkB,aAAc,QAAO;AAC3C,MAAI,kBAAkB,SAAU,QAAO;AACvC,SAAO;AACT;AAEO,SAAS,oBACd,aACA,WACQ;AACR,QAAM,SAAS,2BAA2B,WAAW;AACrD,MAAI,WAAW;AACb,WAAO,YAAY,UAAU,+BAA+B,IAAI;AAClE,MAAI,WAAW;AACb,WAAO,YAAY,UAAU,2BAA2B,IAAI;AAC9D,SAAO,YAAY,UAAU,4BAA4B,IAAI;AAC/D;AAEO,SAAS,uBACd,eACA,WACQ;AACR,MAAI,kBAAkB;AACpB,WAAO,YAAY,UAAU,qCAAqC,IAAI;AACxE,MAAI,kBAAkB;AACpB,WAAO,YAAY,UAAU,iCAAiC,IAAI;AACpE,SAAO,YAAY,UAAU,kCAAkC,IAAI;AACrE;AAEO,SAAS,sBACd,eACA,WACQ;AACR,MAAI,kBAAkB;AACpB,WAAO,YAAY,UAAU,oCAAoC,IAAI;AACvE,MAAI,kBAAkB;AACpB,WAAO,YAAY,UAAU,gCAAgC,IAAI;AACnE,SAAO,YAAY,UAAU,iCAAiC,IAAI;AACpE;AAEO,SAAS,uBAAuB,eAAsC;AAC3E,MAAI,kBAAkB,aAAc,QAAO;AAC3C,MAAI,kBAAkB,SAAU,QAAO;AACvC,SAAO;AACT;AAEO,SAAS,2BACd,MACA,aACQ;AACR,QAAM,SAAS,2BAA2B,WAAW;AACrD,MAAI,WAAW,SAAU,QAAO,KAAK;AACrC,MAAI,WAAW,aAAc,QAAO,KAAK;AACzC,SAAO,KAAK;AACd;AAEO,SAAS,mCACd,MACA,aACQ;AACR,QAAM,SAAS,2BAA2B,WAAW;AACrD,MAAI,WAAW,SAAU,QAAO,KAAK;AACrC,MAAI,WAAW,aAAc,QAAO,KAAK;AACzC,SAAO,KAAK;AACd;","names":[]}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
createContext,
|
|
5
5
|
useCallback,
|
|
6
6
|
useContext,
|
|
7
|
+
useEffect,
|
|
7
8
|
useMemo
|
|
8
9
|
} from "react";
|
|
9
10
|
import { useQueryClient } from "@tanstack/react-query";
|
|
@@ -21,8 +22,10 @@ import {
|
|
|
21
22
|
useCurrentAccount,
|
|
22
23
|
ACCOUNT_QUERY_KEY
|
|
23
24
|
} from "../modules/accounts/hooks/current-account.hook";
|
|
24
|
-
import { useWhitelabelUrls } from "./whitelabel.provider";
|
|
25
|
+
import { useWhitelabelUrls, useWhitelabel } from "./whitelabel.provider";
|
|
25
26
|
import { useWlQueryKey } from "../hooks/useAuthQueryKey";
|
|
27
|
+
import { normalizeLocale } from "../i18n/normalize";
|
|
28
|
+
import { setLocaleCookie } from "../utils/intl/locale-cookie";
|
|
26
29
|
const AuthContext = createContext(
|
|
27
30
|
void 0
|
|
28
31
|
);
|
|
@@ -33,7 +36,12 @@ function AuthProvider({ children }) {
|
|
|
33
36
|
const queryClient = useQueryClient();
|
|
34
37
|
const setUserData = useSetUserData();
|
|
35
38
|
const { accountsUrl, pagesUrl } = useWhitelabelUrls();
|
|
39
|
+
const { whitelabel } = useWhitelabel();
|
|
36
40
|
const accountKey = useWlQueryKey([...ACCOUNT_QUERY_KEY]);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const locale = normalizeLocale(user?.language);
|
|
43
|
+
if (locale) setLocaleCookie(locale, whitelabel?.domain);
|
|
44
|
+
}, [user?.language, whitelabel?.domain]);
|
|
37
45
|
const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();
|
|
38
46
|
const { mutateAsync: registerMutate, isPending: isRegistering } = useRegister();
|
|
39
47
|
const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/auth.provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n useUserQuery,\n useSetUserData,\n useUserValidateSession,\n} from \"../modules/auth/hooks/useUserQuery\";\nimport { useLogin } from \"../modules/auth/hooks/login.hook\";\nimport { useRegister } from \"../modules/auth/hooks/register.hook\";\nimport { useLogout } from \"../modules/auth/hooks/logout.hook\";\nimport { useSocialGoogleLogin } from \"../modules/auth/hooks/social-google-login.hook\";\nimport { useSocialGoogleOnboarding } from \"../modules/auth/hooks/social-google-onboarding.hook\";\nimport {\n AuthState,\n LoginRequest,\n RegisterRequest,\n SocialGooglePartial,\n SocialOnboardingRequest,\n} from \"../modules/auth/schema\";\n\nexport type LoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string; twoFactorMode: \"verify\" | \"setup\" }\n | { result: \"error\"; message: string };\n\nexport type GoogleLoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string; twoFactorMode: \"verify\" | \"setup\" }\n | { result: \"needs_onboarding\"; onboardingToken: string; partial: SocialGooglePartial }\n | { result: \"link_requires_password\"; message: string }\n | { result: \"error\"; message: string };\nimport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"../modules/accounts/hooks/current-account.hook\";\nimport { useWhitelabelUrls } from \"./whitelabel.provider\";\nimport { useWlQueryKey } from \"../hooks/useAuthQueryKey\";\n\ninterface AuthContextProps extends AuthState {\n login: (credentials: LoginRequest) => Promise<LoginResult>;\n register: (data: RegisterRequest) => Promise<void>;\n logout: () => Promise<void>;\n loginWithGoogle: (code: string) => Promise<GoogleLoginResult>;\n completeGoogleOnboarding: (data: SocialOnboardingRequest) => Promise<void>;\n}\n\nexport const AuthContext = createContext<AuthContextProps | undefined>(\n undefined,\n);\n\ninterface AuthProviderProps {\n children: ReactNode;\n}\n\nexport function AuthProvider({ children }: AuthProviderProps) {\n const { data: user, isLoading: isQueryLoading } = useUserQuery();\n const { data: account, isLoading: isAccountLoading } = useCurrentAccount();\n const { isLoading: isSessionLoading } = useUserValidateSession();\n\n const queryClient = useQueryClient();\n const setUserData = useSetUserData();\n const { accountsUrl, pagesUrl } = useWhitelabelUrls();\n const accountKey = useWlQueryKey([...ACCOUNT_QUERY_KEY]);\n\n const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();\n const { mutateAsync: registerMutate, isPending: isRegistering } =\n useRegister();\n const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();\n const { mutateAsync: googleLoginMutate, isPending: isGoogleLogging } =\n useSocialGoogleLogin();\n const { mutateAsync: googleOnboardingMutate, isPending: isGoogleOnboarding } =\n useSocialGoogleOnboarding();\n\n const isAuthenticated = !!user;\n const isLoading =\n isLogging ||\n isRegistering ||\n isLoggingOut ||\n isGoogleLogging ||\n isGoogleOnboarding ||\n isQueryLoading ||\n isAccountLoading ||\n isSessionLoading;\n\n const login = useCallback(\n async (credentials: LoginRequest): Promise<LoginResult> => {\n try {\n const data = await loginMutate(credentials);\n\n if (data.result === \"two_factor_required\") {\n return { result: \"two_factor_required\", cookie: data.cookie, twoFactorMode: data.twoFactorMode };\n }\n\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n\n return { result: \"success\" };\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Ocorreu um erro ao fazer login. Tente novamente.\";\n return { result: \"error\", message };\n }\n },\n [queryClient, setUserData, accountKey],\n );\n\n const register = useCallback(\n async (data: RegisterRequest): Promise<void> => {\n await registerMutate(data, {\n onSuccess: (data) => {\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n },\n });\n },\n [queryClient, setUserData, accountKey],\n );\n\n const loginWithGoogle = useCallback(\n async (code: string): Promise<GoogleLoginResult> => {\n try {\n const data = await googleLoginMutate(code);\n\n if (data.result === \"two_factor_required\") {\n return {\n result: \"two_factor_required\",\n cookie: data.cookie,\n twoFactorMode: data.twoFactorMode,\n };\n }\n\n if (data.result === \"needs_onboarding\") {\n return {\n result: \"needs_onboarding\",\n onboardingToken: data.onboardingToken,\n partial: data.partial,\n };\n }\n\n if (data.result === \"link_requires_password\") {\n return { result: \"link_requires_password\", message: data.message };\n }\n\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n\n return { result: \"success\" };\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Ocorreu um erro ao fazer login com Google. Tente novamente.\";\n return { result: \"error\", message };\n }\n },\n [googleLoginMutate, queryClient, setUserData, accountKey],\n );\n\n const completeGoogleOnboarding = useCallback(\n async (data: SocialOnboardingRequest): Promise<void> => {\n await googleOnboardingMutate(data, {\n onSuccess: (data) => {\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n },\n });\n },\n [googleOnboardingMutate, queryClient, setUserData, accountKey],\n );\n\n const resolveLogoutRedirect = useCallback(() => {\n try {\n const currentOrigin = window.location.origin;\n const pagesOrigin = pagesUrl ? new URL(pagesUrl).origin : \"\";\n\n if (pagesOrigin && currentOrigin === pagesOrigin) {\n return `${accountsUrl}/login?redirect=${encodeURIComponent(pagesUrl)}`;\n }\n } catch {\n // fallback below\n }\n\n return `${accountsUrl}/login?redirect=${encodeURIComponent(pagesUrl || \"/\")}`;\n }, [accountsUrl, pagesUrl]);\n\n const logout = useCallback(async (): Promise<void> => {\n try {\n await logoutMutate(undefined);\n } catch {\n // cookie já removido no servidor mesmo se a API falhou\n } finally {\n queryClient.clear();\n window.location.assign(resolveLogoutRedirect());\n }\n }, [queryClient, logoutMutate, resolveLogoutRedirect]);\n\n const value: AuthContextProps = useMemo(\n () => ({\n user: user ?? null,\n account: account ?? null,\n isAuthenticated,\n isLoading,\n login,\n register,\n logout,\n loginWithGoogle,\n completeGoogleOnboarding,\n }),\n [\n user,\n account,\n isAuthenticated,\n isLoading,\n login,\n register,\n logout,\n loginWithGoogle,\n completeGoogleOnboarding,\n ],\n );\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextProps {\n const context = useContext(AuthContext);\n\n if (context === undefined) {\n throw new Error(\"useAuth deve ser usado dentro de um AuthProvider\");\n }\n\n return context;\n}\n"],"mappings":"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","names":["data"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/auth.provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n useUserQuery,\n useSetUserData,\n useUserValidateSession,\n} from \"../modules/auth/hooks/useUserQuery\";\nimport { useLogin } from \"../modules/auth/hooks/login.hook\";\nimport { useRegister } from \"../modules/auth/hooks/register.hook\";\nimport { useLogout } from \"../modules/auth/hooks/logout.hook\";\nimport { useSocialGoogleLogin } from \"../modules/auth/hooks/social-google-login.hook\";\nimport { useSocialGoogleOnboarding } from \"../modules/auth/hooks/social-google-onboarding.hook\";\nimport {\n AuthState,\n LoginRequest,\n RegisterRequest,\n SocialGooglePartial,\n SocialOnboardingRequest,\n} from \"../modules/auth/schema\";\n\nexport type LoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string; twoFactorMode: \"verify\" | \"setup\" }\n | { result: \"error\"; message: string };\n\nexport type GoogleLoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string; twoFactorMode: \"verify\" | \"setup\" }\n | { result: \"needs_onboarding\"; onboardingToken: string; partial: SocialGooglePartial }\n | { result: \"link_requires_password\"; message: string }\n | { result: \"error\"; message: string };\nimport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"../modules/accounts/hooks/current-account.hook\";\nimport { useWhitelabelUrls, useWhitelabel } from \"./whitelabel.provider\";\nimport { useWlQueryKey } from \"../hooks/useAuthQueryKey\";\nimport { normalizeLocale } from \"../i18n/normalize\";\nimport { setLocaleCookie } from \"../utils/intl/locale-cookie\";\n\ninterface AuthContextProps extends AuthState {\n login: (credentials: LoginRequest) => Promise<LoginResult>;\n register: (data: RegisterRequest) => Promise<void>;\n logout: () => Promise<void>;\n loginWithGoogle: (code: string) => Promise<GoogleLoginResult>;\n completeGoogleOnboarding: (data: SocialOnboardingRequest) => Promise<void>;\n}\n\nexport const AuthContext = createContext<AuthContextProps | undefined>(\n undefined,\n);\n\ninterface AuthProviderProps {\n children: ReactNode;\n}\n\nexport function AuthProvider({ children }: AuthProviderProps) {\n const { data: user, isLoading: isQueryLoading } = useUserQuery();\n const { data: account, isLoading: isAccountLoading } = useCurrentAccount();\n const { isLoading: isSessionLoading } = useUserValidateSession();\n\n const queryClient = useQueryClient();\n const setUserData = useSetUserData();\n const { accountsUrl, pagesUrl } = useWhitelabelUrls();\n const { whitelabel } = useWhitelabel();\n const accountKey = useWlQueryKey([...ACCOUNT_QUERY_KEY]);\n\n // Mantém o cookie NEXT_LOCALE alinhado à preferência da conta (login, sessão existente,\n // atualização). Compartilhado entre subdomínios via domínio do whitelabel. A próxima\n // navegação/requisição passa a resolver o locale pela preferência do usuário.\n useEffect(() => {\n const locale = normalizeLocale(user?.language);\n if (locale) setLocaleCookie(locale, whitelabel?.domain);\n }, [user?.language, whitelabel?.domain]);\n\n const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();\n const { mutateAsync: registerMutate, isPending: isRegistering } =\n useRegister();\n const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();\n const { mutateAsync: googleLoginMutate, isPending: isGoogleLogging } =\n useSocialGoogleLogin();\n const { mutateAsync: googleOnboardingMutate, isPending: isGoogleOnboarding } =\n useSocialGoogleOnboarding();\n\n const isAuthenticated = !!user;\n const isLoading =\n isLogging ||\n isRegistering ||\n isLoggingOut ||\n isGoogleLogging ||\n isGoogleOnboarding ||\n isQueryLoading ||\n isAccountLoading ||\n isSessionLoading;\n\n const login = useCallback(\n async (credentials: LoginRequest): Promise<LoginResult> => {\n try {\n const data = await loginMutate(credentials);\n\n if (data.result === \"two_factor_required\") {\n return { result: \"two_factor_required\", cookie: data.cookie, twoFactorMode: data.twoFactorMode };\n }\n\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n\n return { result: \"success\" };\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Ocorreu um erro ao fazer login. Tente novamente.\";\n return { result: \"error\", message };\n }\n },\n [queryClient, setUserData, accountKey],\n );\n\n const register = useCallback(\n async (data: RegisterRequest): Promise<void> => {\n await registerMutate(data, {\n onSuccess: (data) => {\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n },\n });\n },\n [queryClient, setUserData, accountKey],\n );\n\n const loginWithGoogle = useCallback(\n async (code: string): Promise<GoogleLoginResult> => {\n try {\n const data = await googleLoginMutate(code);\n\n if (data.result === \"two_factor_required\") {\n return {\n result: \"two_factor_required\",\n cookie: data.cookie,\n twoFactorMode: data.twoFactorMode,\n };\n }\n\n if (data.result === \"needs_onboarding\") {\n return {\n result: \"needs_onboarding\",\n onboardingToken: data.onboardingToken,\n partial: data.partial,\n };\n }\n\n if (data.result === \"link_requires_password\") {\n return { result: \"link_requires_password\", message: data.message };\n }\n\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n\n return { result: \"success\" };\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Ocorreu um erro ao fazer login com Google. Tente novamente.\";\n return { result: \"error\", message };\n }\n },\n [googleLoginMutate, queryClient, setUserData, accountKey],\n );\n\n const completeGoogleOnboarding = useCallback(\n async (data: SocialOnboardingRequest): Promise<void> => {\n await googleOnboardingMutate(data, {\n onSuccess: (data) => {\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n },\n });\n },\n [googleOnboardingMutate, queryClient, setUserData, accountKey],\n );\n\n const resolveLogoutRedirect = useCallback(() => {\n try {\n const currentOrigin = window.location.origin;\n const pagesOrigin = pagesUrl ? new URL(pagesUrl).origin : \"\";\n\n if (pagesOrigin && currentOrigin === pagesOrigin) {\n return `${accountsUrl}/login?redirect=${encodeURIComponent(pagesUrl)}`;\n }\n } catch {\n // fallback below\n }\n\n return `${accountsUrl}/login?redirect=${encodeURIComponent(pagesUrl || \"/\")}`;\n }, [accountsUrl, pagesUrl]);\n\n const logout = useCallback(async (): Promise<void> => {\n try {\n await logoutMutate(undefined);\n } catch {\n // cookie já removido no servidor mesmo se a API falhou\n } finally {\n queryClient.clear();\n window.location.assign(resolveLogoutRedirect());\n }\n }, [queryClient, logoutMutate, resolveLogoutRedirect]);\n\n const value: AuthContextProps = useMemo(\n () => ({\n user: user ?? null,\n account: account ?? null,\n isAuthenticated,\n isLoading,\n login,\n register,\n logout,\n loginWithGoogle,\n completeGoogleOnboarding,\n }),\n [\n user,\n account,\n isAuthenticated,\n isLoading,\n login,\n register,\n logout,\n loginWithGoogle,\n completeGoogleOnboarding,\n ],\n );\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextProps {\n const context = useContext(AuthContext);\n\n if (context === undefined) {\n throw new Error(\"useAuth deve ser usado dentro de um AuthProvider\");\n }\n\n return context;\n}\n"],"mappings":"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","names":["data"]}
|
package/dist/server.mjs
CHANGED
|
@@ -60,6 +60,7 @@ import {
|
|
|
60
60
|
} from "./modules/accounts/actions/account-management.action";
|
|
61
61
|
import { getClientInfoFromRequest } from "./infra/utils/client-info";
|
|
62
62
|
import { getUserContext } from "./modules/auth/utils/get-user-context";
|
|
63
|
+
import { resolveLocale } from "./i18n/resolve-locale";
|
|
63
64
|
import { requireValidSession } from "./modules/auth/utils/require-valid-session";
|
|
64
65
|
import { requireTokenNotExpired } from "./modules/auth/utils/require-token-not-expired";
|
|
65
66
|
import { buildWlOverride, buildWlOverrideFromJwt } from "./modules/auth/utils/build-wl-override";
|
|
@@ -120,6 +121,7 @@ export {
|
|
|
120
121
|
requestPhoneChangeAction,
|
|
121
122
|
requireTokenNotExpired,
|
|
122
123
|
requireValidSession,
|
|
124
|
+
resolveLocale,
|
|
123
125
|
resolvePlanExtrasPrices,
|
|
124
126
|
revalidateWhitelabelAction,
|
|
125
127
|
safeMutationAction,
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { socialGoogleLoginAction } from './modules/auth/actions/social-google-login.action';\r\nexport { socialGoogleOnboardingAction } from './modules/auth/actions/social-google-onboarding.action';\r\nexport { unlinkGoogleAction } from './modules/auth/actions/unlink-google.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AAGvC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { socialGoogleLoginAction } from './modules/auth/actions/social-google-login.action';\r\nexport { socialGoogleOnboardingAction } from './modules/auth/actions/social-google-onboarding.action';\r\nexport { unlinkGoogleAction } from './modules/auth/actions/unlink-google.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { resolveLocale } from './i18n/resolve-locale';\r\nexport type { ResolveLocaleOptions } from './i18n/resolve-locale';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AAGvC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAE9B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
|
|
@@ -1,13 +1,41 @@
|
|
|
1
|
-
const
|
|
1
|
+
const CURRENCY_FORMAT = {
|
|
2
|
+
brl: { locale: "pt-BR", currency: "BRL" },
|
|
3
|
+
usd: { locale: "en-US", currency: "USD" }
|
|
4
|
+
};
|
|
5
|
+
const getCurrencyForGateway = (gateway) => gateway === "stripe_usd" ? "usd" : "brl";
|
|
6
|
+
const formatCurrency = (value, currency = "brl") => {
|
|
7
|
+
const fmt = CURRENCY_FORMAT[currency];
|
|
8
|
+
if (typeof value === "number") {
|
|
9
|
+
return value.toLocaleString(fmt.locale, {
|
|
10
|
+
style: "currency",
|
|
11
|
+
currency: fmt.currency
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const numericValue = value.replace(/\D/g, "");
|
|
15
|
+
const numberValue = parseFloat(numericValue) / 100;
|
|
16
|
+
return numberValue.toLocaleString(fmt.locale, {
|
|
17
|
+
style: "currency",
|
|
18
|
+
currency: fmt.currency
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
const parseCurrencyToNumber = (value) => {
|
|
22
|
+
const numericValue = value.replace(/\D/g, "");
|
|
23
|
+
return parseFloat(numericValue) / 100;
|
|
24
|
+
};
|
|
25
|
+
const formatCurrencyNumber = (value, decimals = 2, currency = "brl") => {
|
|
2
26
|
const safeValue = value ?? 0;
|
|
3
|
-
|
|
27
|
+
const fmt = CURRENCY_FORMAT[currency];
|
|
28
|
+
return safeValue.toLocaleString(fmt.locale, {
|
|
4
29
|
style: "currency",
|
|
5
|
-
currency:
|
|
30
|
+
currency: fmt.currency,
|
|
6
31
|
minimumFractionDigits: decimals,
|
|
7
32
|
maximumFractionDigits: decimals
|
|
8
33
|
});
|
|
9
34
|
};
|
|
10
35
|
export {
|
|
11
|
-
|
|
36
|
+
formatCurrency,
|
|
37
|
+
formatCurrencyNumber,
|
|
38
|
+
getCurrencyForGateway,
|
|
39
|
+
parseCurrencyToNumber
|
|
12
40
|
};
|
|
13
41
|
//# sourceMappingURL=currency.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/format/currency.ts"],"sourcesContent":["/**\n * Formata um número (
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/format/currency.ts"],"sourcesContent":["/**\n * Moeda de exibição. Espelha getCurrencyForGateway do backend (gapps-r3-api):\n * 'stripe_usd' → USD; demais gateways → BRL.\n */\nexport type CurrencyCode = 'brl' | 'usd';\n\nconst CURRENCY_FORMAT: Record<CurrencyCode, { locale: string; currency: string }> = {\n brl: { locale: 'pt-BR', currency: 'BRL' },\n usd: { locale: 'en-US', currency: 'USD' },\n};\n\n/**\n * Deriva a moeda de exibição a partir do gateway da conta.\n * A moeda é definida pelo backend no roteamento de gateway — read-only para o usuário.\n * @param gateway - account.gateway ('stripe_usd' | 'stripe_brl' | 'vindi' | ...)\n */\nexport const getCurrencyForGateway = (gateway?: string | null): CurrencyCode =>\n gateway === 'stripe_usd' ? 'usd' : 'brl';\n\n/**\n * Formata um valor (string ou número) como moeda.\n * String: assume centavos (remove não-dígitos e divide por 100) — comportamento legado.\n * @param value - valor a formatar\n * @param currency - moeda de exibição (padrão 'brl' por retrocompatibilidade)\n * @returns String formatada (ex: \"R$ 1.234,56\" ou \"$1,234.56\")\n */\nexport const formatCurrency = (value: string | number, currency: CurrencyCode = 'brl'): string => {\n const fmt = CURRENCY_FORMAT[currency];\n if (typeof value === 'number') {\n return value.toLocaleString(fmt.locale, {\n style: 'currency',\n currency: fmt.currency,\n });\n }\n\n const numericValue = value.replace(/\\D/g, '');\n const numberValue = parseFloat(numericValue) / 100;\n return numberValue.toLocaleString(fmt.locale, {\n style: 'currency',\n currency: fmt.currency,\n });\n};\n\n/**\n * Converte uma string de moeda para número (centavos / 100). Independente de moeda.\n * @param value - String com valor de moeda\n * @returns Número decimal\n */\nexport const parseCurrencyToNumber = (value: string): number => {\n const numericValue = value.replace(/\\D/g, '');\n return parseFloat(numericValue) / 100;\n};\n\n/**\n * Formata um número (opcional) como moeda.\n * @param value - Número a formatar (pode ser undefined/null → 0)\n * @param decimals - Casas decimais (padrão 2)\n * @param currency - Moeda de exibição (padrão 'brl' por retrocompatibilidade)\n * @returns String formatada (ex: \"R$ 1.234,56\" ou \"$1,234.56\")\n */\nexport const formatCurrencyNumber = (value?: number | null, decimals = 2, currency: CurrencyCode = 'brl'): string => {\n const safeValue = value ?? 0;\n const fmt = CURRENCY_FORMAT[currency];\n return safeValue.toLocaleString(fmt.locale, {\n style: 'currency',\n currency: fmt.currency,\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n};\n"],"mappings":"AAMA,MAAM,kBAA8E;AAAA,EAClF,KAAK,EAAE,QAAQ,SAAS,UAAU,MAAM;AAAA,EACxC,KAAK,EAAE,QAAQ,SAAS,UAAU,MAAM;AAC1C;AAOO,MAAM,wBAAwB,CAAC,YACpC,YAAY,eAAe,QAAQ;AAS9B,MAAM,iBAAiB,CAAC,OAAwB,WAAyB,UAAkB;AAChG,QAAM,MAAM,gBAAgB,QAAQ;AACpC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,MAAM,eAAe,IAAI,QAAQ;AAAA,MACtC,OAAO;AAAA,MACP,UAAU,IAAI;AAAA,IAChB,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,MAAM,QAAQ,OAAO,EAAE;AAC5C,QAAM,cAAc,WAAW,YAAY,IAAI;AAC/C,SAAO,YAAY,eAAe,IAAI,QAAQ;AAAA,IAC5C,OAAO;AAAA,IACP,UAAU,IAAI;AAAA,EAChB,CAAC;AACH;AAOO,MAAM,wBAAwB,CAAC,UAA0B;AAC9D,QAAM,eAAe,MAAM,QAAQ,OAAO,EAAE;AAC5C,SAAO,WAAW,YAAY,IAAI;AACpC;AASO,MAAM,uBAAuB,CAAC,OAAuB,WAAW,GAAG,WAAyB,UAAkB;AACnH,QAAM,YAAY,SAAS;AAC3B,QAAM,MAAM,gBAAgB,QAAQ;AACpC,SAAO,UAAU,eAAe,IAAI,QAAQ;AAAA,IAC1C,OAAO;AAAA,IACP,UAAU,IAAI;AAAA,IACd,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,EACzB,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function cookieDomainFromDomain(domain) {
|
|
2
|
+
if (!domain) return void 0;
|
|
3
|
+
const normalized = domain.trim();
|
|
4
|
+
if (!normalized) return void 0;
|
|
5
|
+
let rawHost;
|
|
6
|
+
try {
|
|
7
|
+
rawHost = new URL(normalized).hostname;
|
|
8
|
+
} catch {
|
|
9
|
+
rawHost = normalized.replace(/^https?:\/\//i, "").replace(/^www\./i, "").split("/")[0].split(":")[0];
|
|
10
|
+
}
|
|
11
|
+
if (!rawHost || rawHost === "localhost") return void 0;
|
|
12
|
+
return rawHost.startsWith(".") ? rawHost : `.${rawHost}`;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
cookieDomainFromDomain
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=cookie-domain.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/intl/cookie-domain.ts"],"sourcesContent":["/**\n * Deriva o domínio de cookie compartilhável entre subdomínios a partir do domínio do\n * whitelabel (ex.: `https://app.greatpages.com.br` → `.app.greatpages.com.br`).\n *\n * Mesma normalização usada pelo cookie de auth `greatapps` (auth.service.normalizeCookieDomain),\n * para que o cookie de locale acompanhe o mesmo escopo. Pura (sem APIs de servidor) → client+server.\n * Retorna `undefined` para localhost/host inválido (cookie fica host-scoped).\n */\nexport function cookieDomainFromDomain(domain?: string | null): string | undefined {\n if (!domain) return undefined;\n\n const normalized = domain.trim();\n if (!normalized) return undefined;\n\n let rawHost: string;\n try {\n rawHost = new URL(normalized).hostname;\n } catch {\n rawHost = normalized\n .replace(/^https?:\\/\\//i, '')\n .replace(/^www\\./i, '')\n .split('/')[0]\n .split(':')[0];\n }\n\n if (!rawHost || rawHost === 'localhost') return undefined;\n\n return rawHost.startsWith('.') ? rawHost : `.${rawHost}`;\n}\n"],"mappings":"AAQO,SAAS,uBAAuB,QAA4C;AACjF,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,aAAa,OAAO,KAAK;AAC/B,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI;AACJ,MAAI;AACF,cAAU,IAAI,IAAI,UAAU,EAAE;AAAA,EAChC,QAAQ;AACN,cAAU,WACP,QAAQ,iBAAiB,EAAE,EAC3B,QAAQ,WAAW,EAAE,EACrB,MAAM,GAAG,EAAE,CAAC,EACZ,MAAM,GAAG,EAAE,CAAC;AAAA,EACjB;AAEA,MAAI,CAAC,WAAW,YAAY,YAAa,QAAO;AAEhD,SAAO,QAAQ,WAAW,GAAG,IAAI,UAAU,IAAI,OAAO;AACxD;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LOCALE_COOKIE } from "../../i18n/config";
|
|
2
|
+
import { cookieDomainFromDomain } from "./cookie-domain";
|
|
3
|
+
const ONE_YEAR = 60 * 60 * 24 * 365;
|
|
4
|
+
function setLocaleCookie(locale, whitelabelDomain) {
|
|
5
|
+
if (typeof document === "undefined") return;
|
|
6
|
+
const domain = cookieDomainFromDomain(whitelabelDomain);
|
|
7
|
+
const domainAttr = domain ? `; domain=${domain}` : "";
|
|
8
|
+
document.cookie = `${LOCALE_COOKIE}=${locale}; path=/; max-age=${ONE_YEAR}; samesite=lax${domainAttr}`;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
setLocaleCookie
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=locale-cookie.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/intl/locale-cookie.ts"],"sourcesContent":["import { LOCALE_COOKIE } from '../../i18n/config';\nimport { cookieDomainFromDomain } from './cookie-domain';\n\nconst ONE_YEAR = 60 * 60 * 24 * 365;\n\n/**\n * Persiste o locale escolhido no cookie `NEXT_LOCALE` (lido por `resolveLocale` no servidor).\n *\n * Passe `whitelabelDomain` (de `useWhitelabel().whitelabel?.domain`) para o cookie ser\n * compartilhado entre subdomínios (accounts. → pages. → apps.), no mesmo escopo do cookie\n * de auth. Sem ele, o cookie fica host-scoped.\n */\nexport function setLocaleCookie(locale: string, whitelabelDomain?: string | null): void {\n if (typeof document === 'undefined') return;\n const domain = cookieDomainFromDomain(whitelabelDomain);\n const domainAttr = domain ? `; domain=${domain}` : '';\n document.cookie = `${LOCALE_COOKIE}=${locale}; path=/; max-age=${ONE_YEAR}; samesite=lax${domainAttr}`;\n}\n"],"mappings":"AAAA,SAAS,qBAAqB;AAC9B,SAAS,8BAA8B;AAEvC,MAAM,WAAW,KAAK,KAAK,KAAK;AASzB,SAAS,gBAAgB,QAAgB,kBAAwC;AACtF,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,SAAS,uBAAuB,gBAAgB;AACtD,QAAM,aAAa,SAAS,YAAY,MAAM,KAAK;AACnD,WAAS,SAAS,GAAG,aAAa,IAAI,MAAM,qBAAqB,QAAQ,iBAAiB,UAAU;AACtG;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const LANGUAGE_OPTIONS = [
|
|
2
|
-
{ value: "pt-
|
|
3
|
-
{ value: "en-
|
|
2
|
+
{ value: "pt-br", label: "Portugu\xEAs (Brasil)", displayValue: "Portugu\xEAs (Brasil)", apiValue: "pt-br" },
|
|
3
|
+
{ value: "en-us", label: "Ingl\xEAs (EUA)", displayValue: "Ingl\xEAs (EUA)", apiValue: "en" },
|
|
4
|
+
{ value: "es-es", label: "Espanhol", displayValue: "Espanhol", apiValue: "es" }
|
|
4
5
|
];
|
|
5
6
|
function buildLocaleOptions() {
|
|
6
7
|
return LANGUAGE_OPTIONS;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/intl/locales.ts"],"sourcesContent":["export type LocaleOption = {\r\n value: string;\r\n label: string;\r\n displayValue: string;\r\n apiValue: string;\r\n};\r\n\r\nexport const LANGUAGE_OPTIONS: LocaleOption[] = [\r\n { value: 'pt-
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/intl/locales.ts"],"sourcesContent":["export type LocaleOption = {\r\n value: string;\r\n label: string;\r\n displayValue: string;\r\n apiValue: string;\r\n};\r\n\r\nexport const LANGUAGE_OPTIONS: LocaleOption[] = [\r\n { value: 'pt-br', label: 'Português (Brasil)', displayValue: 'Português (Brasil)', apiValue: 'pt-br' },\r\n { value: 'en-us', label: 'Inglês (EUA)', displayValue: 'Inglês (EUA)', apiValue: 'en' },\r\n { value: 'es-es', label: 'Espanhol', displayValue: 'Espanhol', apiValue: 'es' },\r\n];\r\n\r\nexport function buildLocaleOptions(): LocaleOption[] {\r\n return LANGUAGE_OPTIONS;\r\n}\r\n"],"mappings":"AAOO,MAAM,mBAAmC;AAAA,EAC9C,EAAE,OAAO,SAAS,OAAO,yBAAsB,cAAc,yBAAsB,UAAU,QAAQ;AAAA,EACrG,EAAE,OAAO,SAAS,OAAO,mBAAgB,cAAc,mBAAgB,UAAU,KAAK;AAAA,EACtF,EAAE,OAAO,SAAS,OAAO,YAAY,cAAc,YAAY,UAAU,KAAK;AAChF;AAEO,SAAS,qBAAqC;AACnD,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@greatapps/common",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.677",
|
|
4
4
|
"description": "Shared library for GreatApps frontend applications",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -28,6 +28,10 @@
|
|
|
28
28
|
"./handlers": {
|
|
29
29
|
"import": "./dist/handlers.mjs",
|
|
30
30
|
"types": "./src/handlers.ts"
|
|
31
|
+
},
|
|
32
|
+
"./i18n": {
|
|
33
|
+
"import": "./dist/i18n.mjs",
|
|
34
|
+
"types": "./src/i18n.ts"
|
|
31
35
|
}
|
|
32
36
|
},
|
|
33
37
|
"files": [
|
|
@@ -86,6 +90,7 @@
|
|
|
86
90
|
"@types/react-dom": "^19.2.3",
|
|
87
91
|
"glob": "^13.0.6",
|
|
88
92
|
"next": "16.2.1",
|
|
93
|
+
"next-intl": "^4.12.0",
|
|
89
94
|
"react": "19.1.4",
|
|
90
95
|
"react-dom": "19.1.4",
|
|
91
96
|
"react-hook-form": "^7.72.0",
|
|
@@ -97,6 +102,7 @@
|
|
|
97
102
|
"@hookform/resolvers": ">=3.0.0",
|
|
98
103
|
"@tanstack/react-query": ">=5.0.0",
|
|
99
104
|
"next": ">=16.0.0",
|
|
105
|
+
"next-intl": ">=4.0.0",
|
|
100
106
|
"react": ">=19.0.0",
|
|
101
107
|
"react-dom": ">=19.0.0",
|
|
102
108
|
"react-hook-form": ">=7.0.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { IconKey, IconLock, IconSettings2, IconX } from '@tabler/icons-react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';
|
|
5
6
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from '../ui/data-display/Tabs';
|
|
6
7
|
import { cn } from '../../infra/utils/clsx';
|
|
@@ -19,6 +20,7 @@ import { hasSubscriptionExpired } from '../../modules/subscriptions/utils/has-su
|
|
|
19
20
|
import { useWhitelabel } from '../../providers/whitelabel.provider';
|
|
20
21
|
|
|
21
22
|
export default function ConfigurationsMyAccountModal() {
|
|
23
|
+
const translate = useTranslations();
|
|
22
24
|
const {
|
|
23
25
|
activeModal,
|
|
24
26
|
openDeleteAccount,
|
|
@@ -85,10 +87,12 @@ export default function ConfigurationsMyAccountModal() {
|
|
|
85
87
|
lg:top-[50%] lg:bottom-auto lg:left-[50%] lg:right-auto lg:translate-x-[-50%] lg:translate-y-[-50%]"
|
|
86
88
|
>
|
|
87
89
|
<DialogHeader className="sr-only">
|
|
88
|
-
<DialogTitle>
|
|
90
|
+
<DialogTitle>{translate('common.account.configurations.title')}</DialogTitle>
|
|
89
91
|
</DialogHeader>
|
|
90
92
|
<div className="md:hidden flex items-center justify-between px-5 py-3 border-b border-gray-200">
|
|
91
|
-
<span className="text-gray-950 paragraph-medium-semibold">
|
|
93
|
+
<span className="text-gray-950 paragraph-medium-semibold">
|
|
94
|
+
{translate('common.account.configurations.title')}
|
|
95
|
+
</span>
|
|
92
96
|
<button
|
|
93
97
|
type="button"
|
|
94
98
|
className="size-8 flex items-center justify-center text-gray-500 cursor-pointer"
|
|
@@ -116,26 +120,26 @@ export default function ConfigurationsMyAccountModal() {
|
|
|
116
120
|
)}
|
|
117
121
|
>
|
|
118
122
|
<span className="hidden lg:block paragraph-medium-semibold text-gray-950 mb-0">
|
|
119
|
-
|
|
123
|
+
{translate('common.account.configurations.title')}
|
|
120
124
|
</span>
|
|
121
125
|
|
|
122
126
|
<div className="lg:flex lg:flex-col flex flex-row lg:gap-0 gap-0 lg:w-full">
|
|
123
127
|
<TabsTrigger value={AccountSectionType.PREFERENCES} className={tabTriggerClasses}>
|
|
124
128
|
<IconSettings2 size={20} className="shrink-0" />
|
|
125
|
-
<span className="paragraph-small-medium">
|
|
129
|
+
<span className="paragraph-small-medium">{translate('common.preferences.title')}</span>
|
|
126
130
|
</TabsTrigger>
|
|
127
131
|
|
|
128
132
|
{isOwner && whitelabel?.id === 1 && (
|
|
129
133
|
<TabsTrigger value={AccountSectionType.TOKEN} className={tabTriggerClasses}>
|
|
130
134
|
<IconKey size={20} className="shrink-0" />
|
|
131
|
-
<span className="paragraph-small-medium">
|
|
135
|
+
<span className="paragraph-small-medium">{translate('common.account.token.title')}</span>
|
|
132
136
|
</TabsTrigger>
|
|
133
137
|
)}
|
|
134
138
|
|
|
135
139
|
{isOwner && (
|
|
136
140
|
<TabsTrigger value={AccountSectionType.SECURITY} className={tabTriggerClasses}>
|
|
137
141
|
<IconLock size={20} className="shrink-0" />
|
|
138
|
-
<span className="paragraph-small-medium">
|
|
142
|
+
<span className="paragraph-small-medium">{translate('common.account.security.title')}</span>
|
|
139
143
|
</TabsTrigger>
|
|
140
144
|
)}
|
|
141
145
|
</div>
|