@greatapps/common 1.1.439 → 1.1.440
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/modals/cards/AddCardModal.mjs +2 -5
- package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
- package/dist/index.mjs +7 -0
- package/dist/index.mjs.map +1 -1
- package/dist/modules/plans/actions/list-plans.action.mjs +26 -0
- package/dist/modules/plans/actions/list-plans.action.mjs.map +1 -0
- package/dist/modules/plans/hooks/list-plans.hook.mjs +22 -0
- package/dist/modules/plans/hooks/list-plans.hook.mjs.map +1 -0
- package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs +18 -2
- package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
- package/dist/modules/plans/services/plans.service.mjs +60 -4
- package/dist/modules/plans/services/plans.service.mjs.map +1 -1
- package/dist/modules/plans/types/plan.type.mjs +1 -0
- package/dist/modules/plans/types/plan.type.mjs.map +1 -1
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs +58 -0
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -0
- package/dist/server.mjs +2 -0
- package/dist/server.mjs.map +1 -1
- package/dist/utils/format/currency.mjs +13 -0
- package/dist/utils/format/currency.mjs.map +1 -0
- package/package.json +1 -1
- package/src/components/modals/cards/AddCardModal.tsx +1 -2
- package/src/index.ts +5 -1
- package/src/modules/plans/actions/list-plans.action.ts +28 -0
- package/src/modules/plans/hooks/list-plans.hook.ts +21 -0
- package/src/modules/plans/hooks/use-plan-by-id.hook.ts +26 -5
- package/src/modules/plans/services/plans.service.ts +87 -4
- package/src/modules/plans/types/plan.type.ts +46 -0
- package/src/modules/plans/utils/map-api-plan-to-ui.ts +89 -0
- package/src/server.ts +1 -0
- package/src/utils/format/currency.ts +15 -0
|
@@ -8,7 +8,7 @@ import { useModalManager } from "../../../store/useModalManager";
|
|
|
8
8
|
import { useCreateCard } from "../../../modules/cards/hooks/create-card.hook";
|
|
9
9
|
import { useUpdateAccount } from "../../../modules/accounts/hooks/useAccountManagement";
|
|
10
10
|
import { CardFormFields, BillingFormFields, cardFormSchema } from "./CardFormFields";
|
|
11
|
-
import {
|
|
11
|
+
import { IconX } from "@tabler/icons-react";
|
|
12
12
|
import { useForm } from "react-hook-form";
|
|
13
13
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
14
14
|
import { CardNumberElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
@@ -200,10 +200,7 @@ function AddCardModal() {
|
|
|
200
200
|
)
|
|
201
201
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
202
202
|
/* @__PURE__ */ jsx(Button, { variant: "secondary", type: "button", onClick: handleBack, className: "h-10!", children: "Voltar" }),
|
|
203
|
-
/* @__PURE__ */
|
|
204
|
-
isSubmitting && /* @__PURE__ */ jsx(IconLoader2, { className: "size-4 animate-spin" }),
|
|
205
|
-
isSubmitting ? "Adicionando cart\xE3o..." : "Adicionar cart\xE3o"
|
|
206
|
-
] })
|
|
203
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", className: "h-10!", disabled: isSubmitting || !isStep2Valid, children: isSubmitting ? "Adicionando cart\xE3o..." : "Adicionar cart\xE3o" })
|
|
207
204
|
] }) })
|
|
208
205
|
]
|
|
209
206
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/modals/cards/AddCardModal.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useState } from 'react';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';\nimport { Button } from '../../ui/buttons/Button';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { useModalManager } from '../../../store/useModalManager';\nimport { useCreateCard } from '../../../modules/cards/hooks/create-card.hook';\nimport { useUpdateAccount } from '../../../modules/accounts/hooks/useAccountManagement';\nimport { CardFormFields, BillingFormFields, cardFormSchema } from './CardFormFields';\nimport type { CardFormData, StripeElementsStatus } from './CardFormFields';\nimport { IconLoader2, IconX } from '@tabler/icons-react';\nimport { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { CardNumberElement, useElements, useStripe } from '@stripe/react-stripe-js';\nimport { toast } from 'sonner';\n\nconst INITIAL_STRIPE_STATUS: StripeElementsStatus = {\n cardNumber: false,\n cardExpiry: false,\n cardCvc: false,\n};\n\nexport default function AddCardModal() {\n const { activeModal, modalData, closeModal } = useModalManager();\n const isOpen = activeModal === 'addCardModal';\n const [currentStep, setCurrentStep] = useState(1);\n const [stripeStatus, setStripeStatus] = useState<StripeElementsStatus>(INITIAL_STRIPE_STATUS);\n const [stripeErrors, setStripeErrors] = useState<Record<string, string | undefined>>({});\n\n const onCardAdded = modalData.onCardAdded as ((cardId: string) => void) | undefined;\n\n const createCardMutation = useCreateCard();\n const updateAccountMutation = useUpdateAccount();\n const elements = useElements();\n const stripe = useStripe();\n\n const form = useForm<CardFormData>({\n resolver: zodResolver(cardFormSchema),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n country: 'BR',\n personType: 'pf',\n },\n });\n\n const handleClose = useCallback(() => {\n form.reset();\n setCurrentStep(1);\n setStripeStatus(INITIAL_STRIPE_STATUS);\n setStripeErrors({});\n closeModal();\n }, [form, closeModal]);\n\n const handleStripeChange = useCallback(\n (field: keyof StripeElementsStatus, complete: boolean) => {\n setStripeStatus((prev) => ({ ...prev, [field]: complete }));\n if (complete) {\n setStripeErrors((prev) => ({ ...prev, [field]: undefined }));\n }\n },\n []\n );\n\n const handleContinue = useCallback(async () => {\n const rhfValid = await form.trigger(['name', 'country', 'personType', 'cpf', 'cnpj']);\n\n const newStripeErrors: Record<string, string | undefined> = {};\n if (!stripeStatus.cardNumber) newStripeErrors.cardNumber = 'Número do cartão é obrigatório';\n if (!stripeStatus.cardExpiry) newStripeErrors.cardExpiry = 'Data de validade é obrigatória';\n if (!stripeStatus.cardCvc) newStripeErrors.cardCvc = 'Código de segurança é obrigatório';\n setStripeErrors(newStripeErrors);\n\n const stripeValid = stripeStatus.cardNumber && stripeStatus.cardExpiry && stripeStatus.cardCvc;\n\n if (rhfValid && stripeValid) {\n form.clearErrors(['fullName', 'cep', 'street', 'streetNumber', 'city', 'state']);\n setCurrentStep(2);\n }\n }, [form, stripeStatus]);\n\n const handleBack = useCallback(() => {\n setCurrentStep(1);\n }, []);\n\n async function handleSubmit(data: CardFormData) {\n if (!stripe || !elements) return;\n\n const cardElement = elements.getElement(CardNumberElement);\n if (!cardElement) return;\n\n const { error, paymentMethod } = await stripe.createPaymentMethod({\n type: 'card',\n card: cardElement,\n billing_details: {\n name: data.fullName,\n address: {\n country: data.country,\n postal_code: data.cep,\n line1: `${data.street}, ${data.streetNumber}`,\n line2: data.complement || undefined,\n city: data.city,\n state: data.state,\n },\n },\n });\n\n if (error) {\n toast.custom(\n (t) => (\n <Toast\n variant=\"error\"\n message=\"Não foi possível adicionar o cartão na Stripe, tente novamente.\"\n toastId={t}\n />\n ),\n { duration: 5000 }\n );\n return;\n }\n\n try {\n const [cardResult] = await Promise.all([\n createCardMutation.mutateAsync({ payment_method_id: paymentMethod.id }),\n updateAccountMutation.mutateAsync({\n financial_document_type: data.personType === 'pf' ? 1 : 2,\n financial_document: data.personType === 'pf' ? data.cpf : data.cnpj,\n financial_name: data.fullName,\n zipcode: data.cep,\n address: data.street,\n address_number: data.streetNumber,\n address_complement: data.complement || '',\n city: data.city,\n state: data.state,\n }),\n ]);\n\n if (cardResult.success && cardResult.data?.id != null) {\n onCardAdded?.(cardResult.data.id.toString());\n }\n\n toast.custom(\n (t) => <Toast variant=\"success\" message=\"Cartão adicionado com sucesso.\" toastId={t} />,\n { duration: 5000 }\n );\n handleClose();\n } catch {\n toast.custom(\n (t) => (\n <Toast\n variant=\"error\"\n message=\"Não foi possível salvar o seu novo cartão, tente novamente.\"\n toastId={t}\n />\n ),\n { duration: 5000 }\n );\n }\n }\n\n const isSubmitting =\n createCardMutation.isPending ||\n updateAccountMutation.isPending ||\n form.formState.isSubmitting;\n\n const watchedValues = form.watch(['name', 'country', 'personType', 'cpf', 'cnpj', 'fullName', 'cep', 'street', 'streetNumber', 'city', 'state']);\n const [name, country, personType, cpf, cnpj, fullName, cep, street, streetNumber, city, state] = watchedValues;\n const isStep1Valid =\n !!name &&\n !!country &&\n !!personType &&\n (personType === 'pf' ? !!cpf && cpf.length >= 14 : !!cnpj && cnpj.length >= 18) &&\n stripeStatus.cardNumber &&\n stripeStatus.cardExpiry &&\n stripeStatus.cardCvc;\n const isStep2Valid =\n !!fullName &&\n !!cep && cep.length >= 9 &&\n !!street &&\n !!streetNumber &&\n !!city &&\n !!state;\n\n return (\n <Dialog open={isOpen} onOpenChange={handleClose}>\n <DialogContent\n showCloseButton={false}\n 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-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%] overflow-y-auto\"\n >\n <DialogHeader className=\"p-0\">\n <div className=\"flex items-center justify-center px-4 py-3 relative border-b border-zinc-200 lg:border-b-0\">\n <DialogTitle className=\"paragraph-medium-semibold text-zinc-950 text-center\">\n {currentStep === 1 ? 'Adicionar cartão' : 'Dados de cobrança'}\n </DialogTitle>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"size-8! p-0 absolute right-4\"\n onClick={handleClose}\n >\n <IconX size={18} />\n </Button>\n </div>\n </DialogHeader>\n\n {/* Progress bar */}\n <div className=\"h-1 bg-zinc-100 w-full\">\n <div\n className=\"h-full bg-cyan-400 transition-all duration-300 ease-in-out\"\n style={{ width: currentStep === 1 ? '50%' : '100%' }}\n />\n </div>\n\n <form\n onSubmit={form.handleSubmit(handleSubmit)}\n className=\"flex flex-col flex-1 lg:flex-none\"\n >\n <div className={`flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none ${currentStep !== 1 ? 'hidden' : ''}`}>\n <CardFormFields\n form={form}\n onStripeChange={handleStripeChange}\n stripeErrors={stripeErrors}\n />\n </div>\n <div className={`flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none ${currentStep !== 2 ? 'hidden' : ''}`}>\n <BillingFormFields form={form} />\n </div>\n\n <div className=\"flex justify-between items-center p-4 lg:p-5 border-t border-zinc-200 gap-2 mt-auto lg:mt-0\">\n {currentStep === 1 ? (\n <>\n <Button variant=\"secondary\" type=\"button\" onClick={handleClose} className=\"h-10!\">\n Cancelar\n </Button>\n <Button\n type=\"button\"\n className=\"h-10!\"\n onClick={handleContinue}\n disabled={!isStep1Valid}\n >\n Continuar\n </Button>\n </>\n ) : (\n <>\n <Button variant=\"secondary\" type=\"button\" onClick={handleBack} className=\"h-10!\">\n Voltar\n </Button>\n <Button type=\"submit\" className=\"h-10!\" disabled={isSubmitting || !isStep2Valid}>\n {isSubmitting && <IconLoader2 className=\"size-4 animate-spin\" />}\n {isSubmitting ? 'Adicionando cartão...' : 'Adicionar cartão'}\n </Button>\n </>\n )}\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/modals/cards/AddCardModal.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useState } from 'react';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';\nimport { Button } from '../../ui/buttons/Button';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { useModalManager } from '../../../store/useModalManager';\nimport { useCreateCard } from '../../../modules/cards/hooks/create-card.hook';\nimport { useUpdateAccount } from '../../../modules/accounts/hooks/useAccountManagement';\nimport { CardFormFields, BillingFormFields, cardFormSchema } from './CardFormFields';\nimport type { CardFormData, StripeElementsStatus } from './CardFormFields';\nimport { IconX } from '@tabler/icons-react';\nimport { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { CardNumberElement, useElements, useStripe } from '@stripe/react-stripe-js';\nimport { toast } from 'sonner';\n\nconst INITIAL_STRIPE_STATUS: StripeElementsStatus = {\n cardNumber: false,\n cardExpiry: false,\n cardCvc: false,\n};\n\nexport default function AddCardModal() {\n const { activeModal, modalData, closeModal } = useModalManager();\n const isOpen = activeModal === 'addCardModal';\n const [currentStep, setCurrentStep] = useState(1);\n const [stripeStatus, setStripeStatus] = useState<StripeElementsStatus>(INITIAL_STRIPE_STATUS);\n const [stripeErrors, setStripeErrors] = useState<Record<string, string | undefined>>({});\n\n const onCardAdded = modalData.onCardAdded as ((cardId: string) => void) | undefined;\n\n const createCardMutation = useCreateCard();\n const updateAccountMutation = useUpdateAccount();\n const elements = useElements();\n const stripe = useStripe();\n\n const form = useForm<CardFormData>({\n resolver: zodResolver(cardFormSchema),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n country: 'BR',\n personType: 'pf',\n },\n });\n\n const handleClose = useCallback(() => {\n form.reset();\n setCurrentStep(1);\n setStripeStatus(INITIAL_STRIPE_STATUS);\n setStripeErrors({});\n closeModal();\n }, [form, closeModal]);\n\n const handleStripeChange = useCallback(\n (field: keyof StripeElementsStatus, complete: boolean) => {\n setStripeStatus((prev) => ({ ...prev, [field]: complete }));\n if (complete) {\n setStripeErrors((prev) => ({ ...prev, [field]: undefined }));\n }\n },\n []\n );\n\n const handleContinue = useCallback(async () => {\n const rhfValid = await form.trigger(['name', 'country', 'personType', 'cpf', 'cnpj']);\n\n const newStripeErrors: Record<string, string | undefined> = {};\n if (!stripeStatus.cardNumber) newStripeErrors.cardNumber = 'Número do cartão é obrigatório';\n if (!stripeStatus.cardExpiry) newStripeErrors.cardExpiry = 'Data de validade é obrigatória';\n if (!stripeStatus.cardCvc) newStripeErrors.cardCvc = 'Código de segurança é obrigatório';\n setStripeErrors(newStripeErrors);\n\n const stripeValid = stripeStatus.cardNumber && stripeStatus.cardExpiry && stripeStatus.cardCvc;\n\n if (rhfValid && stripeValid) {\n form.clearErrors(['fullName', 'cep', 'street', 'streetNumber', 'city', 'state']);\n setCurrentStep(2);\n }\n }, [form, stripeStatus]);\n\n const handleBack = useCallback(() => {\n setCurrentStep(1);\n }, []);\n\n async function handleSubmit(data: CardFormData) {\n if (!stripe || !elements) return;\n\n const cardElement = elements.getElement(CardNumberElement);\n if (!cardElement) return;\n\n const { error, paymentMethod } = await stripe.createPaymentMethod({\n type: 'card',\n card: cardElement,\n billing_details: {\n name: data.fullName,\n address: {\n country: data.country,\n postal_code: data.cep,\n line1: `${data.street}, ${data.streetNumber}`,\n line2: data.complement || undefined,\n city: data.city,\n state: data.state,\n },\n },\n });\n\n if (error) {\n toast.custom(\n (t) => (\n <Toast\n variant=\"error\"\n message=\"Não foi possível adicionar o cartão na Stripe, tente novamente.\"\n toastId={t}\n />\n ),\n { duration: 5000 }\n );\n return;\n }\n\n try {\n const [cardResult] = await Promise.all([\n createCardMutation.mutateAsync({ payment_method_id: paymentMethod.id }),\n updateAccountMutation.mutateAsync({\n financial_document_type: data.personType === 'pf' ? 1 : 2,\n financial_document: data.personType === 'pf' ? data.cpf : data.cnpj,\n financial_name: data.fullName,\n zipcode: data.cep,\n address: data.street,\n address_number: data.streetNumber,\n address_complement: data.complement || '',\n city: data.city,\n state: data.state,\n }),\n ]);\n\n if (cardResult.success && cardResult.data?.id != null) {\n onCardAdded?.(cardResult.data.id.toString());\n }\n\n toast.custom(\n (t) => <Toast variant=\"success\" message=\"Cartão adicionado com sucesso.\" toastId={t} />,\n { duration: 5000 }\n );\n handleClose();\n } catch {\n toast.custom(\n (t) => (\n <Toast\n variant=\"error\"\n message=\"Não foi possível salvar o seu novo cartão, tente novamente.\"\n toastId={t}\n />\n ),\n { duration: 5000 }\n );\n }\n }\n\n const isSubmitting =\n createCardMutation.isPending ||\n updateAccountMutation.isPending ||\n form.formState.isSubmitting;\n\n const watchedValues = form.watch(['name', 'country', 'personType', 'cpf', 'cnpj', 'fullName', 'cep', 'street', 'streetNumber', 'city', 'state']);\n const [name, country, personType, cpf, cnpj, fullName, cep, street, streetNumber, city, state] = watchedValues;\n const isStep1Valid =\n !!name &&\n !!country &&\n !!personType &&\n (personType === 'pf' ? !!cpf && cpf.length >= 14 : !!cnpj && cnpj.length >= 18) &&\n stripeStatus.cardNumber &&\n stripeStatus.cardExpiry &&\n stripeStatus.cardCvc;\n const isStep2Valid =\n !!fullName &&\n !!cep && cep.length >= 9 &&\n !!street &&\n !!streetNumber &&\n !!city &&\n !!state;\n\n return (\n <Dialog open={isOpen} onOpenChange={handleClose}>\n <DialogContent\n showCloseButton={false}\n 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-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%] overflow-y-auto\"\n >\n <DialogHeader className=\"p-0\">\n <div className=\"flex items-center justify-center px-4 py-3 relative border-b border-zinc-200 lg:border-b-0\">\n <DialogTitle className=\"paragraph-medium-semibold text-zinc-950 text-center\">\n {currentStep === 1 ? 'Adicionar cartão' : 'Dados de cobrança'}\n </DialogTitle>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"size-8! p-0 absolute right-4\"\n onClick={handleClose}\n >\n <IconX size={18} />\n </Button>\n </div>\n </DialogHeader>\n\n {/* Progress bar */}\n <div className=\"h-1 bg-zinc-100 w-full\">\n <div\n className=\"h-full bg-cyan-400 transition-all duration-300 ease-in-out\"\n style={{ width: currentStep === 1 ? '50%' : '100%' }}\n />\n </div>\n\n <form\n onSubmit={form.handleSubmit(handleSubmit)}\n className=\"flex flex-col flex-1 lg:flex-none\"\n >\n <div className={`flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none ${currentStep !== 1 ? 'hidden' : ''}`}>\n <CardFormFields\n form={form}\n onStripeChange={handleStripeChange}\n stripeErrors={stripeErrors}\n />\n </div>\n <div className={`flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none ${currentStep !== 2 ? 'hidden' : ''}`}>\n <BillingFormFields form={form} />\n </div>\n\n <div className=\"flex justify-between items-center p-4 lg:p-5 border-t border-zinc-200 gap-2 mt-auto lg:mt-0\">\n {currentStep === 1 ? (\n <>\n <Button variant=\"secondary\" type=\"button\" onClick={handleClose} className=\"h-10!\">\n Cancelar\n </Button>\n <Button\n type=\"button\"\n className=\"h-10!\"\n onClick={handleContinue}\n disabled={!isStep1Valid}\n >\n Continuar\n </Button>\n </>\n ) : (\n <>\n <Button variant=\"secondary\" type=\"button\" onClick={handleBack} className=\"h-10!\">\n Voltar\n </Button>\n <Button type=\"submit\" className=\"h-10!\" disabled={isSubmitting || !isStep2Valid}>\n {isSubmitting ? 'Adicionando cartão...' : 'Adicionar cartão'}\n </Button>\n </>\n )}\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -41,6 +41,8 @@ import {
|
|
|
41
41
|
} from "./modules/subscriptions/types/subscription.type";
|
|
42
42
|
import { ADDON_IDS, AI_CREDIT_OPTIONS, AI_CREDIT_VALUES } from "./modules/subscriptions/constants/addons.constants";
|
|
43
43
|
import { PlanSchema, PlanItemSchema } from "./modules/plans/types/plan.type";
|
|
44
|
+
import { mapApiPlanToUiPlan } from "./modules/plans/utils/map-api-plan-to-ui";
|
|
45
|
+
import { usePlans, PLANS_QUERY_KEY } from "./modules/plans/hooks/list-plans.hook";
|
|
44
46
|
import { CardSchema, CreateCardRequestSchema } from "./modules/cards/types";
|
|
45
47
|
import { buildPlanExtras } from "./modules/subscriptions/utils/build-plan-extras";
|
|
46
48
|
import { hasSubscriptionExpired } from "./modules/subscriptions/utils/has-subscription-expired";
|
|
@@ -235,6 +237,7 @@ import {
|
|
|
235
237
|
formatCNPJ,
|
|
236
238
|
formatCardNumber
|
|
237
239
|
} from "./utils/format/masks";
|
|
240
|
+
import { formatCurrencyNumber } from "./utils/format/currency";
|
|
238
241
|
import { BR_STATE_OPTIONS } from "./utils/constants/br-states";
|
|
239
242
|
import {
|
|
240
243
|
buildLocaleOptions,
|
|
@@ -378,6 +381,7 @@ export {
|
|
|
378
381
|
default5 as NotificationCard,
|
|
379
382
|
NotificationPageContent,
|
|
380
383
|
NotificationsPopover,
|
|
384
|
+
PLANS_QUERY_KEY,
|
|
381
385
|
Pagination,
|
|
382
386
|
PaginationContent,
|
|
383
387
|
PaginationEllipsis,
|
|
@@ -470,6 +474,7 @@ export {
|
|
|
470
474
|
formatCNPJ,
|
|
471
475
|
formatCPF,
|
|
472
476
|
formatCardNumber,
|
|
477
|
+
formatCurrencyNumber,
|
|
473
478
|
formatFullName,
|
|
474
479
|
formatPhone,
|
|
475
480
|
formatShortDate,
|
|
@@ -477,6 +482,7 @@ export {
|
|
|
477
482
|
getPriceFromCalculatedData,
|
|
478
483
|
hasSubscriptionExpired,
|
|
479
484
|
hideCrisp,
|
|
485
|
+
mapApiPlanToUiPlan,
|
|
480
486
|
openCrispHelpdesk,
|
|
481
487
|
parseResult,
|
|
482
488
|
parseSchema,
|
|
@@ -515,6 +521,7 @@ export {
|
|
|
515
521
|
usePaidPlanRequiredModal,
|
|
516
522
|
default11 as usePasswordVisibility,
|
|
517
523
|
usePlanById,
|
|
524
|
+
usePlans,
|
|
518
525
|
useSetUserData,
|
|
519
526
|
useSubscriptions,
|
|
520
527
|
useTwoFactorVerify,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from \"./modules/auth/schema\";\nexport * from \"./modules/users/schema\";\nexport * from \"./modules/whitelabel/schema\";\n// Style types now come from whitelabel schema directly\nexport * from \"./infra/api/types\";\n\n// Contexts\nexport * from \"./providers/query.provider\";\nexport * from \"./providers/auth.provider\";\nexport * from \"./providers/whitelabel.provider\";\n\n// Hooks\nexport {\n useListProjectUsers,\n LIST_PROJECT_USERS_QUERY_KEY,\n LIST_PROJECT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-project-users.hook\";\nexport {\n useListAvailableUsers,\n LIST_AVAILABLE_USERS_QUERY_KEY,\n LIST_AVAILABLE_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-available-users.hook\";\nexport type {\n ProjectUser,\n AccountUser,\n AddRemoveProjectUsersParams,\n ListUsersParams,\n UsersPage,\n} from \"./modules/projects/types\";\nexport {\n useUserQuery,\n useUserValidateSession,\n useInvalidateUser,\n useSetUserData,\n useTwoFactorVerify,\n USER_QUERY_KEY,\n} from \"./modules/auth/hooks/useUserQuery\";\nexport { useManagementPermissions } from \"./modules/auth/hooks/useManagementPermissions\";\nexport type { ManagementPermission } from \"./modules/auth/types/management-permission.type\";\nexport { useSubscriptions } from \"./modules/subscriptions/hooks/list-subscriptions.hook\";\nexport { SUBSCRIPTIONS_QUERY_KEY } from \"./modules/subscriptions/constants/query-keys.constants\";\nexport { useActiveSubscription } from \"./modules/subscriptions/hooks/find-active-subscription.hook\";\nexport { useCancelledSubscriptionGuard } from \"./modules/subscriptions/hooks/use-cancelled-subscription-guard\";\nexport { usePlanById } from \"./modules/plans/hooks/use-plan-by-id.hook\";\nexport { useHasPlanAddon } from \"./modules/plans/hooks/use-has-plan-addon.hook\";\nexport { useCalculateSubscription } from \"./modules/subscriptions/hooks/calculate-subscription.hook\";\nexport { useUpdateSubscriptionPlan } from \"./modules/subscriptions/hooks/update-subscription-plan.hook\";\nexport { useCards, CARDS_QUERY_KEY } from \"./modules/cards/hooks/cards.hook\";\nexport { useCreateCard } from \"./modules/cards/hooks/create-card.hook\";\nexport { useIaCredits } from \"./modules/ia-credits/hooks/ia-credits.hook\";\nexport type {\n IaCreditsSummary,\n IaCreditOperation,\n} from \"./modules/ia-credits/types\";\nexport type {\n Subscription,\n SubscriptionItem,\n FindSubscriptionsParams,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport {\n SubscriptionSchema,\n SubscriptionItemSchema,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport { ADDON_IDS, AI_CREDIT_OPTIONS, AI_CREDIT_VALUES } from \"./modules/subscriptions/constants/addons.constants\";\nexport type { AddonKindEnum, AiCreditOption } from \"./modules/subscriptions/constants/addons.constants\";\nexport type { Plan, PlanItem } from \"./modules/plans/types/plan.type\";\nexport { PlanSchema, PlanItemSchema } from \"./modules/plans/types/plan.type\";\nexport type { BillingPeriod } from \"./modules/subscriptions/types/billing-period.type\";\nexport type {\n CalculateSubscriptionRequest,\n CalculateSubscriptionResponse,\n UpdateSubscriptionPlanRequest,\n} from \"./modules/subscriptions/types/calculate-subscription.type\";\nexport type { Card as PaymentCard, CreateCardRequest } from \"./modules/cards/types\";\nexport { CardSchema as PaymentCardSchema, CreateCardRequestSchema } from \"./modules/cards/types\";\nexport { buildPlanExtras } from \"./modules/subscriptions/utils/build-plan-extras\";\nexport { hasSubscriptionExpired } from \"./modules/subscriptions/utils/has-subscription-expired\";\nexport { getPriceFromCalculatedData, periodicityToBillingPeriod } from \"./modules/subscriptions/utils/periodicity\";\nexport { useBuyCreditsModal } from \"./store/useBuyCreditsModal\";\nexport { usePaidPlanRequiredModal } from \"./store/usePaidPlanRequiredModal\";\nexport { default as BuyCreditsModal } from \"./components/modals/BuyCreditsModal\";\nexport { default as PaidPlanRequiredModal } from \"./components/modals/PaidPlanRequiredModal\";\nexport { default as AddCardModal } from \"./components/modals/cards/AddCardModal\";\nexport { CardFormFields, cardFormSchema } from \"./components/modals/cards/CardFormFields\";\nexport type { CardFormData } from \"./components/modals/cards/CardFormFields\";\nexport { Skeleton } from \"./components/ui/feedback/Skeleton\";\nexport { PaymentInfoCard } from \"./components/ui/data-display/PaymentInfoCard\";\nexport { CardBrandIcon } from \"./components/ui/data-display/CardBrandIcons\";\nexport { CardItem } from \"./components/ui/data-display/CardItem\";\n\n// Providers\nexport { QueryProvider } from \"./providers/query.provider\";\n\n// Middleware\nexport { createAuthMiddleware } from \"./middlewares/create-auth-middleware\";\nexport { createMiddlewareChain } from \"./middlewares/chain\";\nexport { continueChain, stopChain } from \"./middlewares/types\";\nexport type {\n MiddlewareFunction,\n MiddlewareConfig,\n MiddlewareResult,\n} from \"./middlewares/types\";\n\n// Utils\nexport { cn } from \"./infra/utils/clsx\";\nexport { formatShortDate } from \"./infra/utils/date\";\nexport { buildQueryParams } from \"./infra/utils/params\";\nexport { parseSchema, parseResult } from \"./infra/utils/parser\";\nexport { withAction } from \"./utils/withAction\";\n\n// Layout\nexport {\n MainLayout,\n MainLayoutContent,\n MainLayoutSpacer,\n MainLayoutMain,\n} from \"./components/layouts/MainLayout\";\nexport { NavBar } from \"./components/layouts/NavBar\";\nexport type { NavBarProps } from \"./components/layouts/NavBar\";\nexport { AppNavBar } from \"./components/layouts/AppNavBar\";\nexport type { AppNavBarProps } from \"./components/layouts/AppNavBar\";\nexport { AppMobileNavBar } from \"./components/layouts/AppMobileNavBar\";\nexport type { AppMobileNavBarProps } from \"./components/layouts/AppMobileNavBar\";\nexport { SideBarNavigation } from \"./components/layouts/SideBarNavigation\";\nexport { MdSideBarNavigation } from \"./components/layouts/MdSideBarNavigation\";\nexport { default as NotificationCard } from \"./components/widgets/notifications/NotificationCard\";\nexport type { NotificationCardProps } from \"./components/widgets/notifications/NotificationCard\";\nexport { NotificationsPopover } from \"./components/layouts/NotificationsPopover\";\nexport type { NotificationsPopoverProps } from \"./components/layouts/NotificationsPopover\";\nexport { NotificationPageContent } from \"./components/pages/notifications/Notifications\";\nexport { NotFoundPage } from \"./components/pages/NotFoundPage\";\nexport { UsersSelectorPopover } from \"./components/layouts/UsersSelectorPopover\";\nexport type { UsersSelectorPopoverProps } from \"./components/layouts/UsersSelectorPopover\";\nexport { ProfilePopover } from \"./components/layouts/ProfilePopover\";\nexport type {\n ProfilePopoverProps,\n ProfileMenuItem,\n} from \"./components/layouts/ProfilePopover\";\nexport { default as WhitelabelCodes } from \"./components/layouts/WhitelabelCodes\";\nexport { NavBarItem } from \"./components/layouts/NavBarItem\";\nexport type { NavBarItemProps } from \"./components/layouts/NavBarItem\";\n\n// Navigation\nexport { AppNavigation } from './components/navigation/AppNavigation';\nexport { CancelledSubscriptionBanner } from './components/navigation/CancelledSubscriptionBanner';\nexport type { NavItemConfig } from './components/navigation/subcomponents/NavItems';\nexport type { NavigationProject } from './components/navigation/types';\nexport { useMobileNavbarSheet } from './store/useMobileNavbarSheet';\n\n// Hooks\nexport { default as useCopyToClipboard } from \"./hooks/copy-to-clipboard.hook\";\n\n// UI - Buttons\nexport { Button, buttonVariants } from \"./components/ui/buttons/Button\";\nexport { CopyButton } from \"./components/ui/buttons/CopyButton\";\nexport { default as CancelButton } from \"./components/ui/buttons/CancelButton\";\n\n// UI - Data Display\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from \"./components/ui/data-display/Accordion\";\nexport { Badge, badgeVariants } from \"./components/ui/data-display/Badge\";\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n} from \"./components/ui/data-display/Card\";\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"./components/ui/data-display/Pagination\";\nexport { ScrollArea, ScrollBar } from \"./components/ui/data-display/ScrollArea\";\nexport { Separator } from \"./components/ui/data-display/Separator\";\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} from \"./components/ui/data-display/Table\";\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n} from \"./components/ui/data-display/Tabs\";\nexport { UserAvatar } from \"./components/ui/data-display/UserAvatar\";\nexport type { UserAvatarProps } from \"./components/ui/data-display/UserAvatar\";\n\n// UI - Feedback\nexport { default as CircularProgress } from \"./components/ui/feedback/CircularProgress\";\nexport { default as DefaultCircularProgress } from \"./components/ui/feedback/DefaultCircularProgress\";\nexport { Progress } from \"./components/ui/feedback/Progress\";\nexport { LoadingOverlay } from \"./components/ui/feedback/LoadingOverlay\";\nexport {\n Toast,\n toastVariants,\n toastIconContainerVariants,\n} from \"./components/ui/feedback/Toast\";\nexport type { ToastProps } from \"./components/ui/feedback/Toast\";\n\n// UI - Form\nexport { Calendar, CalendarDayButton } from \"./components/ui/form/Calendar\";\nexport { Checkbox } from \"./components/ui/form/Checkbox\";\nexport { DatePicker } from \"./components/ui/form/DatePicker\";\nexport { DateRangePicker } from \"./components/ui/form/DateRangePicker\";\nexport { Input } from \"./components/ui/form/Input\";\nexport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n InputOTPSeparator,\n} from \"./components/ui/form/InputOtp\";\nexport { RadioGroup, RadioGroupItem } from \"./components/ui/form/RadioGroup\";\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"./components/ui/form/Select\";\nexport { Switch } from \"./components/ui/form/Switch\";\nexport { Textarea } from \"./components/ui/form/Textarea\";\n\n// UI - Overlay\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n} from \"./components/ui/overlay/Command\";\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n} from \"./components/ui/overlay/Dialog\";\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverAnchor,\n} from \"./components/ui/overlay/Popover\";\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n} from \"./components/ui/overlay/Sheet\";\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n} from \"./components/ui/overlay/Tooltip\";\n\n// Embeds\nexport { FrillEmbed } from \"./components/embeds/FrillEmbed\";\nexport { CrispEmbed, openCrispHelpdesk, hideCrisp, showCrisp } from \"./components/embeds/CrispEmbed\";\nexport { EmbedWidgets } from \"./components/embeds/EmbedWidgets\";\n\n// Store\nexport { useMdSidebarStore } from \"./store/useMdSidebarStore\";\nexport { useDesktopSidebarStore } from \"./store/useDesktopSidebarStore\";\nexport { useModalManager } from \"./store/useModalManager\";\nexport type { ModalData } from \"./store/useModalManager\";\n\n// Enums\nexport { AccountSectionType } from \"./enums/AccountSectionType\";\n\n// Hooks\nexport { default as usePasswordVisibility } from \"./hooks/usePasswordVisibility\";\nexport { default as useCountdownTimer } from \"./hooks/useCountdownTimer\";\nexport { default as useIsMobile } from \"./hooks/useIsMobile\";\nexport { useDebounce } from \"./hooks/useDebounce\";\nexport { useDebouncedEffect } from \"./hooks/useDebouncedEffect\";\nexport { useDebounceState } from \"./hooks/useDebounceState\";\n\n// Utils\nexport {\n formatPhone,\n formatTimer,\n formatFullName,\n formatCPF,\n formatCNPJ,\n formatCardNumber,\n} from \"./utils/format/masks\";\nexport { BR_STATE_OPTIONS } from \"./utils/constants/br-states\";\nexport type { TimezoneOption } from \"./modules/accounts/services/timezone.service\";\nexport {\n buildLocaleOptions,\n LANGUAGE_OPTIONS as LOCALE_LANGUAGE_OPTIONS,\n} from \"./utils/intl/locales\";\nexport type { LocaleOption } from \"./utils/intl/locales\";\nexport { copyToClipboard, readFromClipboard } from \"./utils/browser/clipboard\";\n\n// UI - Form (new widgets)\nexport { FormField } from \"./components/ui/form/FormField\";\nexport { SelectField } from \"./components/ui/form/SelectField\";\nexport { ComboboxField } from \"./components/ui/form/ComboboxField\";\nexport type { ComboboxOption } from \"./components/ui/form/ComboboxField\";\nexport { default as PhoneInput } from \"./components/ui/form/PhoneInput\";\nexport { default as SwitchOptionFieldWithIcon } from \"./components/ui/form/SwitchOptionFieldWithIcon\";\nexport { TextAreaField } from \"./components/ui/form/TextAreaField\";\n\n// Account Module - Hooks\nexport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"./modules/accounts/hooks/current-account.hook\";\nexport {\n useUpdateAccount,\n useUpdateAccountUser,\n useUpdateAccountUserById,\n useDeleteAccountUser,\n useDeleteAccount,\n} from \"./modules/accounts/hooks/useAccountManagement\";\nexport { useViaCep } from \"./modules/accounts/hooks/useViaCep\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateAccountUserRequest,\n ChangePasswordRequest,\n DeleteAccountActionResult,\n DeleteUserActionResult,\n UpdateAccountActionResult,\n UpdateUserActionResult,\n TwoFactorGenerateResult,\n TwoFactorActionResult,\n ContactResetResult,\n} from \"./modules/accounts/types\";\n\nexport { default as AccountModals } from \"./components/account/AccountModals\";\nexport { useAccountModals } from \"./store/useAccountModals\";\nexport type { AccountModalsConfig } from \"./store/useAccountModals\";\n\nexport { ModalManager } from \"./components/modals/ModalManager\";\nexport { Modals } from \"./components/modals/Modals\";\n\nexport { default as TwoFactorAuthModal } from \"./components/account/TwoFactorAuthModal\";\nexport { default as DisableTwoFactorAuthModal } from \"./components/account/DisableTwoFactorAuthModal\";\nexport { default as ConfirmGlobalPreferencesModal } from \"./components/account/ConfirmGlobalPreferencesModal\";\nexport { MyProfileSection } from \"./components/account/sections/MyProfileSection\";\nexport { PreferencesSection } from \"./components/account/sections/PreferencesSection\";\nexport { SecuritySection } from \"./components/account/sections/SecuritySection\";\nexport { ChangePasswordSection } from \"./components/account/sections/ChangePasswordSection\";\nexport { ChangeEmailModal } from \"./components/account/sections/ChangeEmailModal\";\nexport { ChangePhoneModal } from \"./components/account/sections/ChangePhoneModal\";\n\n// Account Constants\nexport {\n GENDER_OPTIONS,\n CURRENCY_OPTIONS,\n TIME_FORMAT_OPTIONS,\n NOTIFICATION_TYPES,\n LANGUAGE_OPTIONS,\n} from \"./components/account/constants\";\n"],"mappings":"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","names":["default","LANGUAGE_OPTIONS"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from \"./modules/auth/schema\";\nexport * from \"./modules/users/schema\";\nexport * from \"./modules/whitelabel/schema\";\n// Style types now come from whitelabel schema directly\nexport * from \"./infra/api/types\";\n\n// Contexts\nexport * from \"./providers/query.provider\";\nexport * from \"./providers/auth.provider\";\nexport * from \"./providers/whitelabel.provider\";\n\n// Hooks\nexport {\n useListProjectUsers,\n LIST_PROJECT_USERS_QUERY_KEY,\n LIST_PROJECT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-project-users.hook\";\nexport {\n useListAvailableUsers,\n LIST_AVAILABLE_USERS_QUERY_KEY,\n LIST_AVAILABLE_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-available-users.hook\";\nexport type {\n ProjectUser,\n AccountUser,\n AddRemoveProjectUsersParams,\n ListUsersParams,\n UsersPage,\n} from \"./modules/projects/types\";\nexport {\n useUserQuery,\n useUserValidateSession,\n useInvalidateUser,\n useSetUserData,\n useTwoFactorVerify,\n USER_QUERY_KEY,\n} from \"./modules/auth/hooks/useUserQuery\";\nexport { useManagementPermissions } from \"./modules/auth/hooks/useManagementPermissions\";\nexport type { ManagementPermission } from \"./modules/auth/types/management-permission.type\";\nexport { useSubscriptions } from \"./modules/subscriptions/hooks/list-subscriptions.hook\";\nexport { SUBSCRIPTIONS_QUERY_KEY } from \"./modules/subscriptions/constants/query-keys.constants\";\nexport { useActiveSubscription } from \"./modules/subscriptions/hooks/find-active-subscription.hook\";\nexport { useCancelledSubscriptionGuard } from \"./modules/subscriptions/hooks/use-cancelled-subscription-guard\";\nexport { usePlanById } from \"./modules/plans/hooks/use-plan-by-id.hook\";\nexport { useHasPlanAddon } from \"./modules/plans/hooks/use-has-plan-addon.hook\";\nexport { useCalculateSubscription } from \"./modules/subscriptions/hooks/calculate-subscription.hook\";\nexport { useUpdateSubscriptionPlan } from \"./modules/subscriptions/hooks/update-subscription-plan.hook\";\nexport { useCards, CARDS_QUERY_KEY } from \"./modules/cards/hooks/cards.hook\";\nexport { useCreateCard } from \"./modules/cards/hooks/create-card.hook\";\nexport { useIaCredits } from \"./modules/ia-credits/hooks/ia-credits.hook\";\nexport type {\n IaCreditsSummary,\n IaCreditOperation,\n} from \"./modules/ia-credits/types\";\nexport type {\n Subscription,\n SubscriptionItem,\n FindSubscriptionsParams,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport {\n SubscriptionSchema,\n SubscriptionItemSchema,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport { ADDON_IDS, AI_CREDIT_OPTIONS, AI_CREDIT_VALUES } from \"./modules/subscriptions/constants/addons.constants\";\nexport type { AddonKindEnum, AiCreditOption } from \"./modules/subscriptions/constants/addons.constants\";\nexport type { Plan, PlanItem, UiPlan, PlanFeature, PlanMainFeatures, PlanPricingByPeriod, PlanTooltips } from \"./modules/plans/types/plan.type\";\nexport { PlanSchema, PlanItemSchema } from \"./modules/plans/types/plan.type\";\nexport { mapApiPlanToUiPlan } from \"./modules/plans/utils/map-api-plan-to-ui\";\nexport type { PlanBillingPeriod } from \"./modules/plans/utils/map-api-plan-to-ui\";\nexport { usePlans, PLANS_QUERY_KEY } from \"./modules/plans/hooks/list-plans.hook\";\nexport type { BillingPeriod } from \"./modules/subscriptions/types/billing-period.type\";\nexport type {\n CalculateSubscriptionRequest,\n CalculateSubscriptionResponse,\n UpdateSubscriptionPlanRequest,\n} from \"./modules/subscriptions/types/calculate-subscription.type\";\nexport type { Card as PaymentCard, CreateCardRequest } from \"./modules/cards/types\";\nexport { CardSchema as PaymentCardSchema, CreateCardRequestSchema } from \"./modules/cards/types\";\nexport { buildPlanExtras } from \"./modules/subscriptions/utils/build-plan-extras\";\nexport { hasSubscriptionExpired } from \"./modules/subscriptions/utils/has-subscription-expired\";\nexport { getPriceFromCalculatedData, periodicityToBillingPeriod } from \"./modules/subscriptions/utils/periodicity\";\nexport { useBuyCreditsModal } from \"./store/useBuyCreditsModal\";\nexport { usePaidPlanRequiredModal } from \"./store/usePaidPlanRequiredModal\";\nexport { default as BuyCreditsModal } from \"./components/modals/BuyCreditsModal\";\nexport { default as PaidPlanRequiredModal } from \"./components/modals/PaidPlanRequiredModal\";\nexport { default as AddCardModal } from \"./components/modals/cards/AddCardModal\";\nexport { CardFormFields, cardFormSchema } from \"./components/modals/cards/CardFormFields\";\nexport type { CardFormData } from \"./components/modals/cards/CardFormFields\";\nexport { Skeleton } from \"./components/ui/feedback/Skeleton\";\nexport { PaymentInfoCard } from \"./components/ui/data-display/PaymentInfoCard\";\nexport { CardBrandIcon } from \"./components/ui/data-display/CardBrandIcons\";\nexport { CardItem } from \"./components/ui/data-display/CardItem\";\n\n// Providers\nexport { QueryProvider } from \"./providers/query.provider\";\n\n// Middleware\nexport { createAuthMiddleware } from \"./middlewares/create-auth-middleware\";\nexport { createMiddlewareChain } from \"./middlewares/chain\";\nexport { continueChain, stopChain } from \"./middlewares/types\";\nexport type {\n MiddlewareFunction,\n MiddlewareConfig,\n MiddlewareResult,\n} from \"./middlewares/types\";\n\n// Utils\nexport { cn } from \"./infra/utils/clsx\";\nexport { formatShortDate } from \"./infra/utils/date\";\nexport { buildQueryParams } from \"./infra/utils/params\";\nexport { parseSchema, parseResult } from \"./infra/utils/parser\";\nexport { withAction } from \"./utils/withAction\";\n\n// Layout\nexport {\n MainLayout,\n MainLayoutContent,\n MainLayoutSpacer,\n MainLayoutMain,\n} from \"./components/layouts/MainLayout\";\nexport { NavBar } from \"./components/layouts/NavBar\";\nexport type { NavBarProps } from \"./components/layouts/NavBar\";\nexport { AppNavBar } from \"./components/layouts/AppNavBar\";\nexport type { AppNavBarProps } from \"./components/layouts/AppNavBar\";\nexport { AppMobileNavBar } from \"./components/layouts/AppMobileNavBar\";\nexport type { AppMobileNavBarProps } from \"./components/layouts/AppMobileNavBar\";\nexport { SideBarNavigation } from \"./components/layouts/SideBarNavigation\";\nexport { MdSideBarNavigation } from \"./components/layouts/MdSideBarNavigation\";\nexport { default as NotificationCard } from \"./components/widgets/notifications/NotificationCard\";\nexport type { NotificationCardProps } from \"./components/widgets/notifications/NotificationCard\";\nexport { NotificationsPopover } from \"./components/layouts/NotificationsPopover\";\nexport type { NotificationsPopoverProps } from \"./components/layouts/NotificationsPopover\";\nexport { NotificationPageContent } from \"./components/pages/notifications/Notifications\";\nexport { NotFoundPage } from \"./components/pages/NotFoundPage\";\nexport { UsersSelectorPopover } from \"./components/layouts/UsersSelectorPopover\";\nexport type { UsersSelectorPopoverProps } from \"./components/layouts/UsersSelectorPopover\";\nexport { ProfilePopover } from \"./components/layouts/ProfilePopover\";\nexport type {\n ProfilePopoverProps,\n ProfileMenuItem,\n} from \"./components/layouts/ProfilePopover\";\nexport { default as WhitelabelCodes } from \"./components/layouts/WhitelabelCodes\";\nexport { NavBarItem } from \"./components/layouts/NavBarItem\";\nexport type { NavBarItemProps } from \"./components/layouts/NavBarItem\";\n\n// Navigation\nexport { AppNavigation } from './components/navigation/AppNavigation';\nexport { CancelledSubscriptionBanner } from './components/navigation/CancelledSubscriptionBanner';\nexport type { NavItemConfig } from './components/navigation/subcomponents/NavItems';\nexport type { NavigationProject } from './components/navigation/types';\nexport { useMobileNavbarSheet } from './store/useMobileNavbarSheet';\n\n// Hooks\nexport { default as useCopyToClipboard } from \"./hooks/copy-to-clipboard.hook\";\n\n// UI - Buttons\nexport { Button, buttonVariants } from \"./components/ui/buttons/Button\";\nexport { CopyButton } from \"./components/ui/buttons/CopyButton\";\nexport { default as CancelButton } from \"./components/ui/buttons/CancelButton\";\n\n// UI - Data Display\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from \"./components/ui/data-display/Accordion\";\nexport { Badge, badgeVariants } from \"./components/ui/data-display/Badge\";\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n} from \"./components/ui/data-display/Card\";\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"./components/ui/data-display/Pagination\";\nexport { ScrollArea, ScrollBar } from \"./components/ui/data-display/ScrollArea\";\nexport { Separator } from \"./components/ui/data-display/Separator\";\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} from \"./components/ui/data-display/Table\";\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n} from \"./components/ui/data-display/Tabs\";\nexport { UserAvatar } from \"./components/ui/data-display/UserAvatar\";\nexport type { UserAvatarProps } from \"./components/ui/data-display/UserAvatar\";\n\n// UI - Feedback\nexport { default as CircularProgress } from \"./components/ui/feedback/CircularProgress\";\nexport { default as DefaultCircularProgress } from \"./components/ui/feedback/DefaultCircularProgress\";\nexport { Progress } from \"./components/ui/feedback/Progress\";\nexport { LoadingOverlay } from \"./components/ui/feedback/LoadingOverlay\";\nexport {\n Toast,\n toastVariants,\n toastIconContainerVariants,\n} from \"./components/ui/feedback/Toast\";\nexport type { ToastProps } from \"./components/ui/feedback/Toast\";\n\n// UI - Form\nexport { Calendar, CalendarDayButton } from \"./components/ui/form/Calendar\";\nexport { Checkbox } from \"./components/ui/form/Checkbox\";\nexport { DatePicker } from \"./components/ui/form/DatePicker\";\nexport { DateRangePicker } from \"./components/ui/form/DateRangePicker\";\nexport { Input } from \"./components/ui/form/Input\";\nexport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n InputOTPSeparator,\n} from \"./components/ui/form/InputOtp\";\nexport { RadioGroup, RadioGroupItem } from \"./components/ui/form/RadioGroup\";\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"./components/ui/form/Select\";\nexport { Switch } from \"./components/ui/form/Switch\";\nexport { Textarea } from \"./components/ui/form/Textarea\";\n\n// UI - Overlay\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n} from \"./components/ui/overlay/Command\";\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n} from \"./components/ui/overlay/Dialog\";\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverAnchor,\n} from \"./components/ui/overlay/Popover\";\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n} from \"./components/ui/overlay/Sheet\";\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n} from \"./components/ui/overlay/Tooltip\";\n\n// Embeds\nexport { FrillEmbed } from \"./components/embeds/FrillEmbed\";\nexport { CrispEmbed, openCrispHelpdesk, hideCrisp, showCrisp } from \"./components/embeds/CrispEmbed\";\nexport { EmbedWidgets } from \"./components/embeds/EmbedWidgets\";\n\n// Store\nexport { useMdSidebarStore } from \"./store/useMdSidebarStore\";\nexport { useDesktopSidebarStore } from \"./store/useDesktopSidebarStore\";\nexport { useModalManager } from \"./store/useModalManager\";\nexport type { ModalData } from \"./store/useModalManager\";\n\n// Enums\nexport { AccountSectionType } from \"./enums/AccountSectionType\";\n\n// Hooks\nexport { default as usePasswordVisibility } from \"./hooks/usePasswordVisibility\";\nexport { default as useCountdownTimer } from \"./hooks/useCountdownTimer\";\nexport { default as useIsMobile } from \"./hooks/useIsMobile\";\nexport { useDebounce } from \"./hooks/useDebounce\";\nexport { useDebouncedEffect } from \"./hooks/useDebouncedEffect\";\nexport { useDebounceState } from \"./hooks/useDebounceState\";\n\n// Utils\nexport {\n formatPhone,\n formatTimer,\n formatFullName,\n formatCPF,\n formatCNPJ,\n formatCardNumber,\n} from \"./utils/format/masks\";\nexport { formatCurrencyNumber } from \"./utils/format/currency\";\nexport { BR_STATE_OPTIONS } from \"./utils/constants/br-states\";\nexport type { TimezoneOption } from \"./modules/accounts/services/timezone.service\";\nexport {\n buildLocaleOptions,\n LANGUAGE_OPTIONS as LOCALE_LANGUAGE_OPTIONS,\n} from \"./utils/intl/locales\";\nexport type { LocaleOption } from \"./utils/intl/locales\";\nexport { copyToClipboard, readFromClipboard } from \"./utils/browser/clipboard\";\n\n// UI - Form (new widgets)\nexport { FormField } from \"./components/ui/form/FormField\";\nexport { SelectField } from \"./components/ui/form/SelectField\";\nexport { ComboboxField } from \"./components/ui/form/ComboboxField\";\nexport type { ComboboxOption } from \"./components/ui/form/ComboboxField\";\nexport { default as PhoneInput } from \"./components/ui/form/PhoneInput\";\nexport { default as SwitchOptionFieldWithIcon } from \"./components/ui/form/SwitchOptionFieldWithIcon\";\nexport { TextAreaField } from \"./components/ui/form/TextAreaField\";\n\n// Account Module - Hooks\nexport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"./modules/accounts/hooks/current-account.hook\";\nexport {\n useUpdateAccount,\n useUpdateAccountUser,\n useUpdateAccountUserById,\n useDeleteAccountUser,\n useDeleteAccount,\n} from \"./modules/accounts/hooks/useAccountManagement\";\nexport { useViaCep } from \"./modules/accounts/hooks/useViaCep\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateAccountUserRequest,\n ChangePasswordRequest,\n DeleteAccountActionResult,\n DeleteUserActionResult,\n UpdateAccountActionResult,\n UpdateUserActionResult,\n TwoFactorGenerateResult,\n TwoFactorActionResult,\n ContactResetResult,\n} from \"./modules/accounts/types\";\n\nexport { default as AccountModals } from \"./components/account/AccountModals\";\nexport { useAccountModals } from \"./store/useAccountModals\";\nexport type { AccountModalsConfig } from \"./store/useAccountModals\";\n\nexport { ModalManager } from \"./components/modals/ModalManager\";\nexport { Modals } from \"./components/modals/Modals\";\n\nexport { default as TwoFactorAuthModal } from \"./components/account/TwoFactorAuthModal\";\nexport { default as DisableTwoFactorAuthModal } from \"./components/account/DisableTwoFactorAuthModal\";\nexport { default as ConfirmGlobalPreferencesModal } from \"./components/account/ConfirmGlobalPreferencesModal\";\nexport { MyProfileSection } from \"./components/account/sections/MyProfileSection\";\nexport { PreferencesSection } from \"./components/account/sections/PreferencesSection\";\nexport { SecuritySection } from \"./components/account/sections/SecuritySection\";\nexport { ChangePasswordSection } from \"./components/account/sections/ChangePasswordSection\";\nexport { ChangeEmailModal } from \"./components/account/sections/ChangeEmailModal\";\nexport { ChangePhoneModal } from \"./components/account/sections/ChangePhoneModal\";\n\n// Account Constants\nexport {\n GENDER_OPTIONS,\n CURRENCY_OPTIONS,\n TIME_FORMAT_OPTIONS,\n NOTIFICATION_TYPES,\n LANGUAGE_OPTIONS,\n} from \"./components/account/constants\";\n"],"mappings":"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","names":["default","LANGUAGE_OPTIONS"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import { plansService, safeServerAction } from "@greatapps/common/server";
|
|
3
|
+
import { mapApiPlanToUiPlan } from "../utils/map-api-plan-to-ui";
|
|
4
|
+
async function listPlansAction() {
|
|
5
|
+
return safeServerAction(async () => {
|
|
6
|
+
const { data: apiPlans } = await plansService.listPlans({
|
|
7
|
+
active: true,
|
|
8
|
+
search: "client",
|
|
9
|
+
sort: "id:ASC"
|
|
10
|
+
});
|
|
11
|
+
if (!apiPlans?.length) return [];
|
|
12
|
+
const sorted = [...apiPlans].sort((a, b) => a.value - b.value);
|
|
13
|
+
return sorted.map((plan) => {
|
|
14
|
+
const popular = plan.id === 2 || plan.id_plan === 2;
|
|
15
|
+
return mapApiPlanToUiPlan(plan, {
|
|
16
|
+
planId: plan.id_plan ?? plan.id,
|
|
17
|
+
isPopular: popular,
|
|
18
|
+
buttonVariant: popular ? "brand" : void 0
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
listPlansAction
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=list-plans.action.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/actions/list-plans.action.ts"],"sourcesContent":["'use server';\n\nimport { plansService, safeServerAction } from '@greatapps/common/server';\nimport type { UiPlan } from '../types/plan.type';\nimport { mapApiPlanToUiPlan } from '../utils/map-api-plan-to-ui';\n\nexport async function listPlansAction() {\n return safeServerAction(async () => {\n const { data: apiPlans } = await plansService.listPlans({\n active: true,\n search: 'client',\n sort: 'id:ASC',\n });\n\n if (!apiPlans?.length) return [] as UiPlan[];\n\n const sorted = [...apiPlans].sort((a, b) => a.value - b.value);\n\n return sorted.map((plan) => {\n const popular = plan.id === 2 || plan.id_plan === 2;\n return mapApiPlanToUiPlan(plan, {\n planId: plan.id_plan ?? plan.id,\n isPopular: popular,\n buttonVariant: popular ? 'brand' : undefined,\n });\n });\n });\n}\n"],"mappings":";AAEA,SAAS,cAAc,wBAAwB;AAE/C,SAAS,0BAA0B;AAEnC,eAAsB,kBAAkB;AACtC,SAAO,iBAAiB,YAAY;AAClC,UAAM,EAAE,MAAM,SAAS,IAAI,MAAM,aAAa,UAAU;AAAA,MACtD,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAED,QAAI,CAAC,UAAU,OAAQ,QAAO,CAAC;AAE/B,UAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAE7D,WAAO,OAAO,IAAI,CAAC,SAAS;AAC1B,YAAM,UAAU,KAAK,OAAO,KAAK,KAAK,YAAY;AAClD,aAAO,mBAAmB,MAAM;AAAA,QAC9B,QAAQ,KAAK,WAAW,KAAK;AAAA,QAC7B,WAAW;AAAA,QACX,eAAe,UAAU,UAAU;AAAA,MACrC,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { withAction } from "@greatapps/common";
|
|
4
|
+
import { listPlansAction } from "../actions/list-plans.action";
|
|
5
|
+
const PLANS_QUERY_KEY = ["plans"];
|
|
6
|
+
function usePlans() {
|
|
7
|
+
return useQuery({
|
|
8
|
+
queryKey: [...PLANS_QUERY_KEY],
|
|
9
|
+
queryFn: withAction(listPlansAction),
|
|
10
|
+
staleTime: Infinity,
|
|
11
|
+
gcTime: Infinity,
|
|
12
|
+
refetchOnWindowFocus: false,
|
|
13
|
+
refetchOnReconnect: false,
|
|
14
|
+
refetchOnMount: false,
|
|
15
|
+
retry: 1
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
PLANS_QUERY_KEY,
|
|
20
|
+
usePlans
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=list-plans.hook.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/hooks/list-plans.hook.ts"],"sourcesContent":["'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { withAction } from '@greatapps/common';\nimport { listPlansAction } from '../actions/list-plans.action';\nimport type { UiPlan } from '../types/plan.type';\n\nexport const PLANS_QUERY_KEY = ['plans'];\n\nexport function usePlans() {\n return useQuery<UiPlan[]>({\n queryKey: [...PLANS_QUERY_KEY],\n queryFn: withAction(listPlansAction),\n staleTime: Infinity,\n gcTime: Infinity,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n refetchOnMount: false,\n retry: 1,\n });\n}\n"],"mappings":";AAEA,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAGzB,MAAM,kBAAkB,CAAC,OAAO;AAEhC,SAAS,WAAW;AACzB,SAAO,SAAmB;AAAA,IACxB,UAAU,CAAC,GAAG,eAAe;AAAA,IAC7B,SAAS,WAAW,eAAe;AAAA,IACnC,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,OAAO;AAAA,EACT,CAAC;AACH;","names":[]}
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
3
3
|
import { withAction } from "../../../utils/withAction";
|
|
4
4
|
import { findPlanByIdAction } from "../actions/find-plan-by-id.action";
|
|
5
|
+
import { PLANS_QUERY_KEY } from "./list-plans.hook";
|
|
5
6
|
function usePlanById(idPlan) {
|
|
7
|
+
const queryClient = useQueryClient();
|
|
6
8
|
return useQuery({
|
|
7
|
-
queryKey: [
|
|
9
|
+
queryKey: [...PLANS_QUERY_KEY, idPlan],
|
|
8
10
|
queryFn: withAction(() => findPlanByIdAction(idPlan)),
|
|
11
|
+
initialData: () => {
|
|
12
|
+
const queries = queryClient.getQueriesData({
|
|
13
|
+
queryKey: [...PLANS_QUERY_KEY]
|
|
14
|
+
});
|
|
15
|
+
for (const [, data] of queries) {
|
|
16
|
+
if (!data) continue;
|
|
17
|
+
const plan = (Array.isArray(data) ? data : data.data)?.find((p) => p.idPlan === idPlan);
|
|
18
|
+
if (plan) {
|
|
19
|
+
return plan;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return void 0;
|
|
23
|
+
},
|
|
24
|
+
initialDataUpdatedAt: 0,
|
|
9
25
|
enabled: !!idPlan
|
|
10
26
|
});
|
|
11
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/plans/hooks/use-plan-by-id.hook.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/hooks/use-plan-by-id.hook.ts"],"sourcesContent":["\"use client\";\n\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { withAction } from \"../../../utils/withAction\";\nimport { findPlanByIdAction } from \"../actions/find-plan-by-id.action\";\nimport { Plan } from \"../types/plan.type\";\nimport { PLANS_QUERY_KEY } from \"./list-plans.hook\";\nimport { PaginatedSuccessResult } from \"../../../infra/api/types\";\n\nexport function usePlanById(idPlan: number | string | undefined) {\n const queryClient = useQueryClient();\n \n return useQuery({\n queryKey: [...PLANS_QUERY_KEY, idPlan],\n queryFn: withAction(() => findPlanByIdAction(idPlan!)),\n initialData: () => {\n const queries = queryClient.getQueriesData<PaginatedSuccessResult<Plan>>({\n queryKey: [...PLANS_QUERY_KEY],\n });\n\n for (const [, data] of queries) {\n if (!data) continue;\n const plan = (Array.isArray(data) ? data : data.data)?.find((p) => p.idPlan === idPlan);\n if (plan) {\n return plan;\n }\n }\n\n return undefined;\n },\n initialDataUpdatedAt: 0,\n enabled: !!idPlan,\n });\n}\n"],"mappings":";AAEA,SAAS,UAAU,sBAAsB;AACzC,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AAEnC,SAAS,uBAAuB;AAGzB,SAAS,YAAY,QAAqC;AAC/D,QAAM,cAAc,eAAe;AAEnC,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,GAAG,iBAAiB,MAAM;AAAA,IACrC,SAAS,WAAW,MAAM,mBAAmB,MAAO,CAAC;AAAA,IACrD,aAAa,MAAM;AACjB,YAAM,UAAU,YAAY,eAA6C;AAAA,QACvE,UAAU,CAAC,GAAG,eAAe;AAAA,MAC/B,CAAC;AAED,iBAAW,CAAC,EAAE,IAAI,KAAK,SAAS;AAC9B,YAAI,CAAC,KAAM;AACX,cAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AACtF,YAAI,MAAM;AACR,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IACA,sBAAsB;AAAA,IACtB,SAAS,CAAC,CAAC;AAAA,EACb,CAAC;AACH;","names":[]}
|
|
@@ -1,9 +1,63 @@
|
|
|
1
1
|
import "server-only";
|
|
2
|
-
import { api } from "
|
|
3
|
-
import { ApiError } from "
|
|
4
|
-
import
|
|
2
|
+
import { api, apiClient } from "@greatapps/common/server";
|
|
3
|
+
import { ApiError, buildQueryParams, PlanSchema } from "@greatapps/common";
|
|
4
|
+
import greatCache from "@greatapps/cache";
|
|
5
|
+
const PLANS_CACHE_TTL = 604800;
|
|
5
6
|
class PlansService {
|
|
7
|
+
cache = new greatCache({
|
|
8
|
+
service: "plans-service",
|
|
9
|
+
version: "1.0.1",
|
|
10
|
+
domain: "whitelabel-cache.greatapps.com.br",
|
|
11
|
+
ambient: process.env.NODE_ENV || "development"
|
|
12
|
+
});
|
|
13
|
+
buildCacheKey(key, params) {
|
|
14
|
+
const sort = params?.sort ?? "id:ASC";
|
|
15
|
+
const active = params?.active ?? "";
|
|
16
|
+
const search = params?.search ?? "";
|
|
17
|
+
return `${key}-${sort}-${active}-${search}`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Lista planos do whitelabel.
|
|
21
|
+
* Exemplo:
|
|
22
|
+
* GET /{id_wl}/plans?active=true&search=client&sort=id:ASC
|
|
23
|
+
*/
|
|
24
|
+
async listPlans(params) {
|
|
25
|
+
const cacheKey = this.buildCacheKey("plans", params);
|
|
26
|
+
const cachedData = await this.cache.select(cacheKey);
|
|
27
|
+
if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
|
|
28
|
+
const data2 = JSON.parse(cachedData.data);
|
|
29
|
+
return { data: data2, total: data2.length, success: true };
|
|
30
|
+
}
|
|
31
|
+
const query = buildQueryParams({
|
|
32
|
+
sort: params?.sort ?? "id:ASC",
|
|
33
|
+
active: params?.active,
|
|
34
|
+
search: params?.search
|
|
35
|
+
});
|
|
36
|
+
const url = `/plans${query ? `?${query}` : ""}`;
|
|
37
|
+
const response = await apiClient.get(url);
|
|
38
|
+
if (response.status === 0) {
|
|
39
|
+
throw new ApiError(
|
|
40
|
+
response.message || "Erro ao listar planos",
|
|
41
|
+
"LIST_PLANS_FAILED",
|
|
42
|
+
400
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
const rawData = response.data;
|
|
46
|
+
const data = Array.isArray(rawData) ? rawData.map((item) => PlanSchema.parse(item)) : [];
|
|
47
|
+
await this.cache.insert(cacheKey, JSON.stringify(data), PLANS_CACHE_TTL);
|
|
48
|
+
return {
|
|
49
|
+
data,
|
|
50
|
+
total: response.total,
|
|
51
|
+
success: true
|
|
52
|
+
};
|
|
53
|
+
}
|
|
6
54
|
async findById(idPlan) {
|
|
55
|
+
const cacheKey = this.buildCacheKey(`plan-${idPlan}`);
|
|
56
|
+
const cachedData = await this.cache.select(cacheKey);
|
|
57
|
+
if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
|
|
58
|
+
const data = JSON.parse(cachedData.data);
|
|
59
|
+
return { data, success: true };
|
|
60
|
+
}
|
|
7
61
|
const response = await api.apps.get(
|
|
8
62
|
`/plans/${idPlan}?type=client`
|
|
9
63
|
);
|
|
@@ -21,9 +75,11 @@ class PlansService {
|
|
|
21
75
|
404
|
|
22
76
|
);
|
|
23
77
|
}
|
|
78
|
+
const plan = PlanSchema.parse(response.data[0]);
|
|
79
|
+
await this.cache.insert(cacheKey, JSON.stringify(plan), PLANS_CACHE_TTL);
|
|
24
80
|
return {
|
|
25
81
|
success: true,
|
|
26
|
-
data:
|
|
82
|
+
data: plan
|
|
27
83
|
};
|
|
28
84
|
}
|
|
29
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/plans/services/plans.service.ts"],"sourcesContent":["import 'server-only';\n\nimport { api } from '
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/services/plans.service.ts"],"sourcesContent":["import 'server-only';\n\nimport { api, apiClient } from '@greatapps/common/server';\nimport { ApiError, buildQueryParams, PlanSchema } from '@greatapps/common';\nimport type { ApiPaginatedActionResult, PaginatedSuccessResult, Plan, SuccessResult } from '@greatapps/common';\nimport greatCache from '@greatapps/cache';\n\nexport type ListPlansParams = {\n sort?: string;\n active?: boolean;\n search?: string;\n};\n\nconst PLANS_CACHE_TTL = 604800;\n\nclass PlansService {\n private cache = new greatCache({\n service: 'plans-service',\n version: '1.0.1',\n domain: 'whitelabel-cache.greatapps.com.br',\n ambient: process.env.NODE_ENV || 'development',\n });\n\n private buildCacheKey(key: string, params?: ListPlansParams): string {\n const sort = params?.sort ?? 'id:ASC';\n const active = params?.active ?? '';\n const search = params?.search ?? '';\n return `${key}-${sort}-${active}-${search}`;\n }\n\n /**\n * Lista planos do whitelabel.\n * Exemplo:\n * GET /{id_wl}/plans?active=true&search=client&sort=id:ASC\n */\n async listPlans(params?: ListPlansParams): Promise<PaginatedSuccessResult<Plan>> {\n const cacheKey = this.buildCacheKey('plans', params);\n\n const cachedData = await this.cache.select(cacheKey);\n\n if (cachedData.status == 1 && 'data' in cachedData && cachedData.data) {\n const data = JSON.parse(cachedData.data) as Plan[];\n return { data, total: data.length, success: true };\n }\n\n const query = buildQueryParams({\n sort: params?.sort ?? 'id:ASC',\n active: params?.active,\n search: params?.search,\n });\n const url = `/plans${query ? `?${query}` : ''}`;\n\n const response = await apiClient.get<ApiPaginatedActionResult<Plan[]>>(url);\n\n if (response.status === 0) {\n throw new ApiError(\n (response as { message?: string }).message || 'Erro ao listar planos',\n 'LIST_PLANS_FAILED',\n 400\n );\n }\n\n const rawData = (response as { data?: unknown }).data;\n const data = Array.isArray(rawData)\n ? rawData.map((item) => PlanSchema.parse(item))\n : [];\n\n await this.cache.insert(cacheKey, JSON.stringify(data), PLANS_CACHE_TTL);\n\n return {\n data,\n total: response.total,\n success: true,\n } satisfies PaginatedSuccessResult<Plan>;\n }\n\n\n async findById(idPlan: number | string): Promise<SuccessResult<Plan>> {\n const cacheKey = this.buildCacheKey(`plan-${idPlan}`);\n\n const cachedData = await this.cache.select(cacheKey);\n \n if (cachedData.status == 1 && 'data' in cachedData && cachedData.data) {\n const data = JSON.parse(cachedData.data) as Plan;\n return { data, success: true };\n }\n\n const response = await api.apps.get<ApiPaginatedActionResult<Plan>>(\n `/plans/${idPlan}?type=client`\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao buscar plano',\n 'FIND_PLAN_FAILED',\n 400\n );\n }\n\n if (!response.data?.length) {\n throw new ApiError(\n 'Plano não encontrado',\n 'PLAN_NOT_FOUND',\n 404\n );\n }\n\n const plan = PlanSchema.parse(response.data[0]);\n\n await this.cache.insert(cacheKey, JSON.stringify(plan), PLANS_CACHE_TTL);\n\n return {\n success: true,\n data: plan,\n };\n }\n}\n\nexport const plansService = new PlansService();\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,KAAK,iBAAiB;AAC/B,SAAS,UAAU,kBAAkB,kBAAkB;AAEvD,OAAO,gBAAgB;AAQvB,MAAM,kBAAkB;AAExB,MAAM,aAAa;AAAA,EACT,QAAQ,IAAI,WAAW;AAAA,IAC7B,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS,QAAQ,IAAI,YAAY;AAAA,EACnC,CAAC;AAAA,EAEO,cAAc,KAAa,QAAkC;AACnE,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,SAAS,QAAQ,UAAU;AACjC,UAAM,SAAS,QAAQ,UAAU;AACjC,WAAO,GAAG,GAAG,IAAI,IAAI,IAAI,MAAM,IAAI,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,QAAiE;AAC/E,UAAM,WAAW,KAAK,cAAc,SAAS,MAAM;AAEnD,UAAM,aAAa,MAAM,KAAK,MAAM,OAAO,QAAQ;AAEnD,QAAI,WAAW,UAAU,KAAK,UAAU,cAAc,WAAW,MAAM;AACrE,YAAMA,QAAO,KAAK,MAAM,WAAW,IAAI;AACvC,aAAO,EAAE,MAAAA,OAAM,OAAOA,MAAK,QAAQ,SAAS,KAAK;AAAA,IACnD;AAEA,UAAM,QAAQ,iBAAiB;AAAA,MAC7B,MAAM,QAAQ,QAAQ;AAAA,MACtB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,UAAM,MAAM,SAAS,QAAQ,IAAI,KAAK,KAAK,EAAE;AAE7C,UAAM,WAAW,MAAM,UAAU,IAAsC,GAAG;AAE1E,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACP,SAAkC,WAAW;AAAA,QAC9C;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAW,SAAgC;AACjD,UAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,IAAI,CAAC,SAAS,WAAW,MAAM,IAAI,CAAC,IAC5C,CAAC;AAEL,UAAM,KAAK,MAAM,OAAO,UAAU,KAAK,UAAU,IAAI,GAAG,eAAe;AAEvE,WAAO;AAAA,MACL;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAGA,MAAM,SAAS,QAAuD;AACpE,UAAM,WAAW,KAAK,cAAc,QAAQ,MAAM,EAAE;AAEpD,UAAM,aAAa,MAAM,KAAK,MAAM,OAAO,QAAQ;AAEnD,QAAI,WAAW,UAAU,KAAK,UAAU,cAAc,WAAW,MAAM;AACrE,YAAM,OAAO,KAAK,MAAM,WAAW,IAAI;AACvC,aAAO,EAAE,MAAM,SAAS,KAAK;AAAA,IAC/B;AAEA,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,UAAU,MAAM;AAAA,IAClB;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,MAAM,QAAQ;AAC1B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC;AAE9C,UAAM,KAAK,MAAM,OAAO,UAAU,KAAK,UAAU,IAAI,GAAG,eAAe;AAEvE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,MAAM,eAAe,IAAI,aAAa;","names":["data"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/plans/types/plan.type.ts"],"sourcesContent":["import z from 'zod';\n\nexport const PlanItemSchema = z.object({\n id_addon: z.number(),\n quantity: z.number(),\n value: z.number(),\n});\n\nexport type PlanItem = z.infer<typeof PlanItemSchema>;\n\nexport const PlanSchema = z.object({\n id: z.number(),\n name: z.string(),\n value: z.number().default(0),\n type: z.string().optional(),\n discount_semester: z.number().default(0),\n discount_annual: z.number().default(0),\n items: z.array(PlanItemSchema).optional().default([]),\n});\n\nexport type Plan = z.infer<typeof PlanSchema>;\n"],"mappings":"AAAA,OAAO,OAAO;
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/types/plan.type.ts"],"sourcesContent":["import z from 'zod';\nimport type { BillingPeriod } from '../../subscriptions/types/billing-period.type';\n\nexport const PlanItemSchema = z.object({\n id_addon: z.number(),\n quantity: z.number(),\n value: z.number(),\n});\n\nexport type PlanItem = z.infer<typeof PlanItemSchema>;\n\nexport const PlanSchema = z.object({\n id: z.number(),\n id_plan: z.number().optional(),\n name: z.string(),\n value: z.number().default(0),\n type: z.string().optional(),\n discount_semester: z.number().default(0),\n discount_annual: z.number().default(0),\n items: z.array(PlanItemSchema).optional().default([]),\n});\n\nexport type Plan = z.infer<typeof PlanSchema>;\n\n// ── UI Plan types (used by list-plans action and consumers) ──\n\nexport type PlanFeature = {\n icon: 'check' | 'x';\n text: string;\n disabled?: boolean;\n tooltip?: keyof PlanTooltips;\n};\n\nexport type PlanMainFeatures = {\n pages: string;\n domains: string;\n users: string;\n};\n\n/** Preços mensais equivalentes por período de cobrança (já com desconto aplicado). */\nexport type PlanPricingByPeriod = {\n monthly: number;\n semiannual: number;\n annual: number;\n};\n\nexport type UiPlan = {\n idPlan: number;\n name: string;\n isPopular?: boolean;\n isCurrentPlan?: boolean;\n currentPeriodicity?: BillingPeriod | null;\n mainFeatures: PlanMainFeatures;\n features: PlanFeature[];\n originalPrice: string;\n price: string;\n pricingByPeriod?: PlanPricingByPeriod;\n buttonVariant?: 'brand' | 'default';\n items: PlanItem[];\n};\n\nexport type PlanTooltips = {\n domains: string;\n users: string;\n sharePages: string;\n projectManagement: string;\n};\n"],"mappings":"AAAA,OAAO,OAAO;AAGP,MAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,UAAU,EAAE,OAAO;AAAA,EACnB,UAAU,EAAE,OAAO;AAAA,EACnB,OAAO,EAAE,OAAO;AAClB,CAAC;AAIM,MAAM,aAAa,EAAE,OAAO;AAAA,EACjC,IAAI,EAAE,OAAO;AAAA,EACb,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,MAAM,EAAE,OAAO;AAAA,EACf,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EAC3B,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,mBAAmB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EACvC,iBAAiB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EACrC,OAAO,EAAE,MAAM,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;","names":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ADDON_IDS } from "../../subscriptions/constants/addons.constants";
|
|
2
|
+
import { formatCurrencyNumber } from "../../../utils/format/currency";
|
|
3
|
+
const BASE_FEATURES = [
|
|
4
|
+
{ icon: "check", text: "Visitas ilimitadas" },
|
|
5
|
+
{ icon: "check", text: "Leads ilimitadas" },
|
|
6
|
+
{ icon: "check", text: "Compartilhar p\xE1ginas", tooltip: "sharePages" },
|
|
7
|
+
{ icon: "check", text: "Hospedagem inclusa" },
|
|
8
|
+
{ icon: "check", text: "SSL (HTTPS) + CDN" },
|
|
9
|
+
{ icon: "check", text: "Templates Free" }
|
|
10
|
+
];
|
|
11
|
+
function buildMainFeaturesFromItems(items) {
|
|
12
|
+
const pagesItem = items.find((i) => i.id_addon === ADDON_IDS.PAGES);
|
|
13
|
+
const domainsItem = items.find((i) => i.id_addon === ADDON_IDS.DOMAINS);
|
|
14
|
+
const pagesQty = pagesItem?.quantity ?? 0;
|
|
15
|
+
const domainsQty = domainsItem?.quantity ?? 1;
|
|
16
|
+
return {
|
|
17
|
+
pages: pagesQty === 0 ? "P\xE1ginas ilimitadas" : pagesQty === 1 ? "1 p\xE1gina" : `${pagesQty} p\xE1ginas`,
|
|
18
|
+
domains: domainsQty >= 999 ? "Dom\xEDnios ilimitados" : domainsQty === 1 ? "1 dom\xEDnio externo" : `${domainsQty} dom\xEDnios externos`,
|
|
19
|
+
users: "Usu\xE1rios ilimitados"
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function computePricingByPeriod(apiPlan) {
|
|
23
|
+
const monthly = apiPlan.value;
|
|
24
|
+
const round2 = (n) => Math.round(n * 100) / 100;
|
|
25
|
+
return {
|
|
26
|
+
monthly,
|
|
27
|
+
semiannual: round2(monthly * (1 - apiPlan.discount_semester / 100)),
|
|
28
|
+
annual: round2(monthly * (1 - apiPlan.discount_annual / 100))
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function mapApiPlanToUiPlan(apiPlan, options) {
|
|
32
|
+
const { planId, isPopular, buttonVariant } = options;
|
|
33
|
+
const pricingByPeriod = computePricingByPeriod(apiPlan);
|
|
34
|
+
const monthlyFinal = pricingByPeriod.monthly;
|
|
35
|
+
const lowerName = apiPlan.name.toLowerCase();
|
|
36
|
+
const hasProjectAndOnboarding = lowerName.includes("ag\xEAncia") || lowerName.includes("agencia");
|
|
37
|
+
const features = [
|
|
38
|
+
...BASE_FEATURES,
|
|
39
|
+
hasProjectAndOnboarding ? { icon: "check", text: "Reuni\xE3o de Onboarding" } : { icon: "x", text: "Reuni\xE3o de Onboarding", disabled: true },
|
|
40
|
+
hasProjectAndOnboarding ? { icon: "check", text: "Gest\xE3o de projetos", tooltip: "projectManagement" } : { icon: "x", text: "Gest\xE3o de projetos", disabled: true, tooltip: "projectManagement" }
|
|
41
|
+
];
|
|
42
|
+
return {
|
|
43
|
+
idPlan: planId,
|
|
44
|
+
name: apiPlan.name,
|
|
45
|
+
isPopular,
|
|
46
|
+
buttonVariant,
|
|
47
|
+
mainFeatures: buildMainFeaturesFromItems(apiPlan.items),
|
|
48
|
+
features,
|
|
49
|
+
originalPrice: formatCurrencyNumber(monthlyFinal),
|
|
50
|
+
price: formatCurrencyNumber(monthlyFinal),
|
|
51
|
+
pricingByPeriod,
|
|
52
|
+
items: apiPlan.items
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
mapApiPlanToUiPlan
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=map-api-plan-to-ui.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/utils/map-api-plan-to-ui.ts"],"sourcesContent":["import type { Plan, PlanFeature, PlanMainFeatures, PlanPricingByPeriod, UiPlan } from '../types/plan.type';\nimport { ADDON_IDS } from '../../subscriptions/constants/addons.constants';\nimport { formatCurrencyNumber } from '../../../utils/format/currency';\n\nexport type PlanBillingPeriod = 'monthly' | 'semiannual' | 'annual';\n\nconst BASE_FEATURES: PlanFeature[] = [\n { icon: 'check', text: 'Visitas ilimitadas' },\n { icon: 'check', text: 'Leads ilimitadas' },\n { icon: 'check', text: 'Compartilhar páginas', tooltip: 'sharePages' },\n { icon: 'check', text: 'Hospedagem inclusa' },\n { icon: 'check', text: 'SSL (HTTPS) + CDN' },\n { icon: 'check', text: 'Templates Free' },\n];\n\nfunction buildMainFeaturesFromItems(items: Plan['items']): 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 return {\n pages:\n pagesQty === 0\n ? 'Páginas ilimitadas'\n : pagesQty === 1\n ? '1 página'\n : `${pagesQty} páginas`,\n domains:\n domainsQty >= 999\n ? 'Domínios ilimitados'\n : domainsQty === 1\n ? '1 domínio externo'\n : `${domainsQty} domínios externos`,\n users: 'Usuários ilimitados',\n };\n}\n\nfunction computePricingByPeriod(apiPlan: Plan): PlanPricingByPeriod {\n const monthly = 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\nexport function mapApiPlanToUiPlan(\n apiPlan: Plan,\n options: {\n planId: number;\n isPopular?: boolean;\n buttonVariant?: 'brand' | 'default';\n }\n): UiPlan {\n const { planId, isPopular, buttonVariant } = options;\n\n const pricingByPeriod = computePricingByPeriod(apiPlan);\n const monthlyFinal = pricingByPeriod.monthly;\n\n const lowerName = apiPlan.name.toLowerCase();\n const hasProjectAndOnboarding =\n lowerName.includes('agência') || lowerName.includes('agencia');\n\n const features: PlanFeature[] = [\n ...BASE_FEATURES,\n hasProjectAndOnboarding\n ? { icon: 'check', text: 'Reunião de Onboarding' }\n : { icon: 'x', text: 'Reunião de Onboarding', disabled: true },\n hasProjectAndOnboarding\n ? { icon: 'check', text: 'Gestão de projetos', tooltip: 'projectManagement' }\n : { icon: 'x', text: 'Gestão de projetos', disabled: true, tooltip: 'projectManagement' },\n ];\n\n return {\n idPlan: planId,\n name: apiPlan.name,\n isPopular,\n buttonVariant,\n mainFeatures: buildMainFeaturesFromItems(apiPlan.items),\n features,\n originalPrice: formatCurrencyNumber(monthlyFinal),\n price: formatCurrencyNumber(monthlyFinal),\n pricingByPeriod,\n items: apiPlan.items,\n };\n}\n"],"mappings":"AACA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AAIrC,MAAM,gBAA+B;AAAA,EACnC,EAAE,MAAM,SAAS,MAAM,qBAAqB;AAAA,EAC5C,EAAE,MAAM,SAAS,MAAM,mBAAmB;AAAA,EAC1C,EAAE,MAAM,SAAS,MAAM,2BAAwB,SAAS,aAAa;AAAA,EACrE,EAAE,MAAM,SAAS,MAAM,qBAAqB;AAAA,EAC5C,EAAE,MAAM,SAAS,MAAM,oBAAoB;AAAA,EAC3C,EAAE,MAAM,SAAS,MAAM,iBAAiB;AAC1C;AAEA,SAAS,2BAA2B,OAAwC;AAC1E,QAAM,YAAY,MAAM,KAAK,CAAC,MAAM,EAAE,aAAa,UAAU,KAAK;AAClE,QAAM,cAAc,MAAM,KAAK,CAAC,MAAM,EAAE,aAAa,UAAU,OAAO;AAEtE,QAAM,WAAW,WAAW,YAAY;AACxC,QAAM,aAAa,aAAa,YAAY;AAE5C,SAAO;AAAA,IACL,OACE,aAAa,IACT,0BACA,aAAa,IACX,gBACA,GAAG,QAAQ;AAAA,IACnB,SACE,cAAc,MACV,2BACA,eAAe,IACb,yBACA,GAAG,UAAU;AAAA,IACrB,OAAO;AAAA,EACT;AACF;AAEA,SAAS,uBAAuB,SAAoC;AAClE,QAAM,UAAU,QAAQ;AACxB,QAAM,SAAS,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AACpD,SAAO;AAAA,IACL;AAAA,IACA,YAAY,OAAO,WAAW,IAAI,QAAQ,oBAAoB,IAAI;AAAA,IAClE,QAAQ,OAAO,WAAW,IAAI,QAAQ,kBAAkB,IAAI;AAAA,EAC9D;AACF;AAEO,SAAS,mBACd,SACA,SAKQ;AACR,QAAM,EAAE,QAAQ,WAAW,cAAc,IAAI;AAE7C,QAAM,kBAAkB,uBAAuB,OAAO;AACtD,QAAM,eAAe,gBAAgB;AAErC,QAAM,YAAY,QAAQ,KAAK,YAAY;AAC3C,QAAM,0BACJ,UAAU,SAAS,YAAS,KAAK,UAAU,SAAS,SAAS;AAE/D,QAAM,WAA0B;AAAA,IAC9B,GAAG;AAAA,IACH,0BACI,EAAE,MAAM,SAAS,MAAM,2BAAwB,IAC/C,EAAE,MAAM,KAAK,MAAM,4BAAyB,UAAU,KAAK;AAAA,IAC/D,0BACI,EAAE,MAAM,SAAS,MAAM,yBAAsB,SAAS,oBAAoB,IAC1E,EAAE,MAAM,KAAK,MAAM,yBAAsB,UAAU,MAAM,SAAS,oBAAoB;AAAA,EAC5F;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,MAAM,QAAQ;AAAA,IACd;AAAA,IACA;AAAA,IACA,cAAc,2BAA2B,QAAQ,KAAK;AAAA,IACtD;AAAA,IACA,eAAe,qBAAqB,YAAY;AAAA,IAChD,OAAO,qBAAqB,YAAY;AAAA,IACxC;AAAA,IACA,OAAO,QAAQ;AAAA,EACjB;AACF;","names":[]}
|
package/dist/server.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import { findUserById } from "./modules/users/action/find-user-by-id.action";
|
|
|
17
17
|
import { findCurrentAccount } from "./modules/accounts/actions/find-current-account.action";
|
|
18
18
|
import { listSubscriptionsAction } from "./modules/subscriptions/actions/list-subscriptions.action";
|
|
19
19
|
import { findPlanByIdAction } from "./modules/plans/actions/find-plan-by-id.action";
|
|
20
|
+
import { listPlansAction } from "./modules/plans/actions/list-plans.action";
|
|
20
21
|
import { calculateSubscriptionAction } from "./modules/subscriptions/actions/calculate-subscription.action";
|
|
21
22
|
import { updateSubscriptionPlanAction } from "./modules/subscriptions/actions/update-subscription-plan.action";
|
|
22
23
|
import { listCardsAction } from "./modules/cards/actions/list-cards.action";
|
|
@@ -89,6 +90,7 @@ export {
|
|
|
89
90
|
listAvailableUsersAction,
|
|
90
91
|
listCardsAction,
|
|
91
92
|
listIaCreditsAction,
|
|
93
|
+
listPlansAction,
|
|
92
94
|
listProjectUsersAction,
|
|
93
95
|
listSubscriptionsAction,
|
|
94
96
|
plansService,
|
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 { 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 { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { findPlanByIdAction } from './modules/plans/actions/find-plan-by-id.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { listCardsAction } from './modules/cards/actions/list-cards.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { listIaCreditsAction } from './modules/ia-credits/actions/list-ia-credits.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 { listAvailableUsersAction } from './modules/projects/actions/list-available-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 { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\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,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,gCAAgC;AACzC,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,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;","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 { 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 { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { findPlanByIdAction } from './modules/plans/actions/find-plan-by-id.action';\r\nexport { listPlansAction } from './modules/plans/actions/list-plans.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { listCardsAction } from './modules/cards/actions/list-cards.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { listIaCreditsAction } from './modules/ia-credits/actions/list-ia-credits.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 { listAvailableUsersAction } from './modules/projects/actions/list-available-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 { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\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,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,gCAAgC;AACzC,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,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const formatCurrencyNumber = (value, decimals = 2) => {
|
|
2
|
+
const safeValue = value ?? 0;
|
|
3
|
+
return safeValue.toLocaleString("pt-BR", {
|
|
4
|
+
style: "currency",
|
|
5
|
+
currency: "BRL",
|
|
6
|
+
minimumFractionDigits: decimals,
|
|
7
|
+
maximumFractionDigits: decimals
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
formatCurrencyNumber
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=currency.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/format/currency.ts"],"sourcesContent":["/**\n * Formata um número (opcional) para moeda BRL\n * @param value - Número a ser formatado (pode ser undefined ou null)\n * @param decimals - Casas decimais (padrão: 2)\n * @returns String formatada como \"R$ X.XXX,XX\"\n */\nexport const formatCurrencyNumber = (value?: number | null, decimals = 2): string => {\n const safeValue = value ?? 0;\n return safeValue.toLocaleString('pt-BR', {\n style: 'currency',\n currency: 'BRL',\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n};\n"],"mappings":"AAMO,MAAM,uBAAuB,CAAC,OAAuB,WAAW,MAAc;AACnF,QAAM,YAAY,SAAS;AAC3B,SAAO,UAAU,eAAe,SAAS;AAAA,IACvC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,EACzB,CAAC;AACH;","names":[]}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ import { useCreateCard } from '../../../modules/cards/hooks/create-card.hook';
|
|
|
9
9
|
import { useUpdateAccount } from '../../../modules/accounts/hooks/useAccountManagement';
|
|
10
10
|
import { CardFormFields, BillingFormFields, cardFormSchema } from './CardFormFields';
|
|
11
11
|
import type { CardFormData, StripeElementsStatus } from './CardFormFields';
|
|
12
|
-
import {
|
|
12
|
+
import { IconX } from '@tabler/icons-react';
|
|
13
13
|
import { useForm } from 'react-hook-form';
|
|
14
14
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
15
15
|
import { CardNumberElement, useElements, useStripe } from '@stripe/react-stripe-js';
|
|
@@ -248,7 +248,6 @@ export default function AddCardModal() {
|
|
|
248
248
|
Voltar
|
|
249
249
|
</Button>
|
|
250
250
|
<Button type="submit" className="h-10!" disabled={isSubmitting || !isStep2Valid}>
|
|
251
|
-
{isSubmitting && <IconLoader2 className="size-4 animate-spin" />}
|
|
252
251
|
{isSubmitting ? 'Adicionando cartão...' : 'Adicionar cartão'}
|
|
253
252
|
</Button>
|
|
254
253
|
</>
|
package/src/index.ts
CHANGED
|
@@ -64,8 +64,11 @@ export {
|
|
|
64
64
|
} from "./modules/subscriptions/types/subscription.type";
|
|
65
65
|
export { ADDON_IDS, AI_CREDIT_OPTIONS, AI_CREDIT_VALUES } from "./modules/subscriptions/constants/addons.constants";
|
|
66
66
|
export type { AddonKindEnum, AiCreditOption } from "./modules/subscriptions/constants/addons.constants";
|
|
67
|
-
export type { Plan, PlanItem } from "./modules/plans/types/plan.type";
|
|
67
|
+
export type { Plan, PlanItem, UiPlan, PlanFeature, PlanMainFeatures, PlanPricingByPeriod, PlanTooltips } from "./modules/plans/types/plan.type";
|
|
68
68
|
export { PlanSchema, PlanItemSchema } from "./modules/plans/types/plan.type";
|
|
69
|
+
export { mapApiPlanToUiPlan } from "./modules/plans/utils/map-api-plan-to-ui";
|
|
70
|
+
export type { PlanBillingPeriod } from "./modules/plans/utils/map-api-plan-to-ui";
|
|
71
|
+
export { usePlans, PLANS_QUERY_KEY } from "./modules/plans/hooks/list-plans.hook";
|
|
69
72
|
export type { BillingPeriod } from "./modules/subscriptions/types/billing-period.type";
|
|
70
73
|
export type {
|
|
71
74
|
CalculateSubscriptionRequest,
|
|
@@ -321,6 +324,7 @@ export {
|
|
|
321
324
|
formatCNPJ,
|
|
322
325
|
formatCardNumber,
|
|
323
326
|
} from "./utils/format/masks";
|
|
327
|
+
export { formatCurrencyNumber } from "./utils/format/currency";
|
|
324
328
|
export { BR_STATE_OPTIONS } from "./utils/constants/br-states";
|
|
325
329
|
export type { TimezoneOption } from "./modules/accounts/services/timezone.service";
|
|
326
330
|
export {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
|
|
3
|
+
import { plansService, safeServerAction } from '@greatapps/common/server';
|
|
4
|
+
import type { UiPlan } from '../types/plan.type';
|
|
5
|
+
import { mapApiPlanToUiPlan } from '../utils/map-api-plan-to-ui';
|
|
6
|
+
|
|
7
|
+
export async function listPlansAction() {
|
|
8
|
+
return safeServerAction(async () => {
|
|
9
|
+
const { data: apiPlans } = await plansService.listPlans({
|
|
10
|
+
active: true,
|
|
11
|
+
search: 'client',
|
|
12
|
+
sort: 'id:ASC',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
if (!apiPlans?.length) return [] as UiPlan[];
|
|
16
|
+
|
|
17
|
+
const sorted = [...apiPlans].sort((a, b) => a.value - b.value);
|
|
18
|
+
|
|
19
|
+
return sorted.map((plan) => {
|
|
20
|
+
const popular = plan.id === 2 || plan.id_plan === 2;
|
|
21
|
+
return mapApiPlanToUiPlan(plan, {
|
|
22
|
+
planId: plan.id_plan ?? plan.id,
|
|
23
|
+
isPopular: popular,
|
|
24
|
+
buttonVariant: popular ? 'brand' : undefined,
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useQuery } from '@tanstack/react-query';
|
|
4
|
+
import { withAction } from '@greatapps/common';
|
|
5
|
+
import { listPlansAction } from '../actions/list-plans.action';
|
|
6
|
+
import type { UiPlan } from '../types/plan.type';
|
|
7
|
+
|
|
8
|
+
export const PLANS_QUERY_KEY = ['plans'];
|
|
9
|
+
|
|
10
|
+
export function usePlans() {
|
|
11
|
+
return useQuery<UiPlan[]>({
|
|
12
|
+
queryKey: [...PLANS_QUERY_KEY],
|
|
13
|
+
queryFn: withAction(listPlansAction),
|
|
14
|
+
staleTime: Infinity,
|
|
15
|
+
gcTime: Infinity,
|
|
16
|
+
refetchOnWindowFocus: false,
|
|
17
|
+
refetchOnReconnect: false,
|
|
18
|
+
refetchOnMount: false,
|
|
19
|
+
retry: 1,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -1,13 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import { useQuery } from
|
|
4
|
-
import { withAction } from
|
|
5
|
-
import { findPlanByIdAction } from
|
|
3
|
+
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
|
+
import { withAction } from "../../../utils/withAction";
|
|
5
|
+
import { findPlanByIdAction } from "../actions/find-plan-by-id.action";
|
|
6
|
+
import { Plan } from "../types/plan.type";
|
|
7
|
+
import { PLANS_QUERY_KEY } from "./list-plans.hook";
|
|
8
|
+
import { PaginatedSuccessResult } from "../../../infra/api/types";
|
|
6
9
|
|
|
7
10
|
export function usePlanById(idPlan: number | string | undefined) {
|
|
11
|
+
const queryClient = useQueryClient();
|
|
12
|
+
|
|
8
13
|
return useQuery({
|
|
9
|
-
queryKey: [
|
|
14
|
+
queryKey: [...PLANS_QUERY_KEY, idPlan],
|
|
10
15
|
queryFn: withAction(() => findPlanByIdAction(idPlan!)),
|
|
16
|
+
initialData: () => {
|
|
17
|
+
const queries = queryClient.getQueriesData<PaginatedSuccessResult<Plan>>({
|
|
18
|
+
queryKey: [...PLANS_QUERY_KEY],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
for (const [, data] of queries) {
|
|
22
|
+
if (!data) continue;
|
|
23
|
+
const plan = (Array.isArray(data) ? data : data.data)?.find((p) => p.idPlan === idPlan);
|
|
24
|
+
if (plan) {
|
|
25
|
+
return plan;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return undefined;
|
|
30
|
+
},
|
|
31
|
+
initialDataUpdatedAt: 0,
|
|
11
32
|
enabled: !!idPlan,
|
|
12
33
|
});
|
|
13
34
|
}
|
|
@@ -1,11 +1,90 @@
|
|
|
1
1
|
import 'server-only';
|
|
2
2
|
|
|
3
|
-
import { api } from '
|
|
4
|
-
import { ApiError,
|
|
5
|
-
import { Plan,
|
|
3
|
+
import { api, apiClient } from '@greatapps/common/server';
|
|
4
|
+
import { ApiError, buildQueryParams, PlanSchema } from '@greatapps/common';
|
|
5
|
+
import type { ApiPaginatedActionResult, PaginatedSuccessResult, Plan, SuccessResult } from '@greatapps/common';
|
|
6
|
+
import greatCache from '@greatapps/cache';
|
|
7
|
+
|
|
8
|
+
export type ListPlansParams = {
|
|
9
|
+
sort?: string;
|
|
10
|
+
active?: boolean;
|
|
11
|
+
search?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const PLANS_CACHE_TTL = 604800;
|
|
6
15
|
|
|
7
16
|
class PlansService {
|
|
17
|
+
private cache = new greatCache({
|
|
18
|
+
service: 'plans-service',
|
|
19
|
+
version: '1.0.1',
|
|
20
|
+
domain: 'whitelabel-cache.greatapps.com.br',
|
|
21
|
+
ambient: process.env.NODE_ENV || 'development',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
private buildCacheKey(key: string, params?: ListPlansParams): string {
|
|
25
|
+
const sort = params?.sort ?? 'id:ASC';
|
|
26
|
+
const active = params?.active ?? '';
|
|
27
|
+
const search = params?.search ?? '';
|
|
28
|
+
return `${key}-${sort}-${active}-${search}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Lista planos do whitelabel.
|
|
33
|
+
* Exemplo:
|
|
34
|
+
* GET /{id_wl}/plans?active=true&search=client&sort=id:ASC
|
|
35
|
+
*/
|
|
36
|
+
async listPlans(params?: ListPlansParams): Promise<PaginatedSuccessResult<Plan>> {
|
|
37
|
+
const cacheKey = this.buildCacheKey('plans', params);
|
|
38
|
+
|
|
39
|
+
const cachedData = await this.cache.select(cacheKey);
|
|
40
|
+
|
|
41
|
+
if (cachedData.status == 1 && 'data' in cachedData && cachedData.data) {
|
|
42
|
+
const data = JSON.parse(cachedData.data) as Plan[];
|
|
43
|
+
return { data, total: data.length, success: true };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const query = buildQueryParams({
|
|
47
|
+
sort: params?.sort ?? 'id:ASC',
|
|
48
|
+
active: params?.active,
|
|
49
|
+
search: params?.search,
|
|
50
|
+
});
|
|
51
|
+
const url = `/plans${query ? `?${query}` : ''}`;
|
|
52
|
+
|
|
53
|
+
const response = await apiClient.get<ApiPaginatedActionResult<Plan[]>>(url);
|
|
54
|
+
|
|
55
|
+
if (response.status === 0) {
|
|
56
|
+
throw new ApiError(
|
|
57
|
+
(response as { message?: string }).message || 'Erro ao listar planos',
|
|
58
|
+
'LIST_PLANS_FAILED',
|
|
59
|
+
400
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const rawData = (response as { data?: unknown }).data;
|
|
64
|
+
const data = Array.isArray(rawData)
|
|
65
|
+
? rawData.map((item) => PlanSchema.parse(item))
|
|
66
|
+
: [];
|
|
67
|
+
|
|
68
|
+
await this.cache.insert(cacheKey, JSON.stringify(data), PLANS_CACHE_TTL);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
data,
|
|
72
|
+
total: response.total,
|
|
73
|
+
success: true,
|
|
74
|
+
} satisfies PaginatedSuccessResult<Plan>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
8
78
|
async findById(idPlan: number | string): Promise<SuccessResult<Plan>> {
|
|
79
|
+
const cacheKey = this.buildCacheKey(`plan-${idPlan}`);
|
|
80
|
+
|
|
81
|
+
const cachedData = await this.cache.select(cacheKey);
|
|
82
|
+
|
|
83
|
+
if (cachedData.status == 1 && 'data' in cachedData && cachedData.data) {
|
|
84
|
+
const data = JSON.parse(cachedData.data) as Plan;
|
|
85
|
+
return { data, success: true };
|
|
86
|
+
}
|
|
87
|
+
|
|
9
88
|
const response = await api.apps.get<ApiPaginatedActionResult<Plan>>(
|
|
10
89
|
`/plans/${idPlan}?type=client`
|
|
11
90
|
);
|
|
@@ -26,9 +105,13 @@ class PlansService {
|
|
|
26
105
|
);
|
|
27
106
|
}
|
|
28
107
|
|
|
108
|
+
const plan = PlanSchema.parse(response.data[0]);
|
|
109
|
+
|
|
110
|
+
await this.cache.insert(cacheKey, JSON.stringify(plan), PLANS_CACHE_TTL);
|
|
111
|
+
|
|
29
112
|
return {
|
|
30
113
|
success: true,
|
|
31
|
-
data:
|
|
114
|
+
data: plan,
|
|
32
115
|
};
|
|
33
116
|
}
|
|
34
117
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
|
+
import type { BillingPeriod } from '../../subscriptions/types/billing-period.type';
|
|
2
3
|
|
|
3
4
|
export const PlanItemSchema = z.object({
|
|
4
5
|
id_addon: z.number(),
|
|
@@ -10,6 +11,7 @@ export type PlanItem = z.infer<typeof PlanItemSchema>;
|
|
|
10
11
|
|
|
11
12
|
export const PlanSchema = z.object({
|
|
12
13
|
id: z.number(),
|
|
14
|
+
id_plan: z.number().optional(),
|
|
13
15
|
name: z.string(),
|
|
14
16
|
value: z.number().default(0),
|
|
15
17
|
type: z.string().optional(),
|
|
@@ -19,3 +21,47 @@ export const PlanSchema = z.object({
|
|
|
19
21
|
});
|
|
20
22
|
|
|
21
23
|
export type Plan = z.infer<typeof PlanSchema>;
|
|
24
|
+
|
|
25
|
+
// ── UI Plan types (used by list-plans action and consumers) ──
|
|
26
|
+
|
|
27
|
+
export type PlanFeature = {
|
|
28
|
+
icon: 'check' | 'x';
|
|
29
|
+
text: string;
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
tooltip?: keyof PlanTooltips;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type PlanMainFeatures = {
|
|
35
|
+
pages: string;
|
|
36
|
+
domains: string;
|
|
37
|
+
users: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** Preços mensais equivalentes por período de cobrança (já com desconto aplicado). */
|
|
41
|
+
export type PlanPricingByPeriod = {
|
|
42
|
+
monthly: number;
|
|
43
|
+
semiannual: number;
|
|
44
|
+
annual: number;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type UiPlan = {
|
|
48
|
+
idPlan: number;
|
|
49
|
+
name: string;
|
|
50
|
+
isPopular?: boolean;
|
|
51
|
+
isCurrentPlan?: boolean;
|
|
52
|
+
currentPeriodicity?: BillingPeriod | null;
|
|
53
|
+
mainFeatures: PlanMainFeatures;
|
|
54
|
+
features: PlanFeature[];
|
|
55
|
+
originalPrice: string;
|
|
56
|
+
price: string;
|
|
57
|
+
pricingByPeriod?: PlanPricingByPeriod;
|
|
58
|
+
buttonVariant?: 'brand' | 'default';
|
|
59
|
+
items: PlanItem[];
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type PlanTooltips = {
|
|
63
|
+
domains: string;
|
|
64
|
+
users: string;
|
|
65
|
+
sharePages: string;
|
|
66
|
+
projectManagement: string;
|
|
67
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Plan, PlanFeature, PlanMainFeatures, PlanPricingByPeriod, UiPlan } from '../types/plan.type';
|
|
2
|
+
import { ADDON_IDS } from '../../subscriptions/constants/addons.constants';
|
|
3
|
+
import { formatCurrencyNumber } from '../../../utils/format/currency';
|
|
4
|
+
|
|
5
|
+
export type PlanBillingPeriod = 'monthly' | 'semiannual' | 'annual';
|
|
6
|
+
|
|
7
|
+
const BASE_FEATURES: PlanFeature[] = [
|
|
8
|
+
{ icon: 'check', text: 'Visitas ilimitadas' },
|
|
9
|
+
{ icon: 'check', text: 'Leads ilimitadas' },
|
|
10
|
+
{ icon: 'check', text: 'Compartilhar páginas', tooltip: 'sharePages' },
|
|
11
|
+
{ icon: 'check', text: 'Hospedagem inclusa' },
|
|
12
|
+
{ icon: 'check', text: 'SSL (HTTPS) + CDN' },
|
|
13
|
+
{ icon: 'check', text: 'Templates Free' },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
function buildMainFeaturesFromItems(items: Plan['items']): PlanMainFeatures {
|
|
17
|
+
const pagesItem = items.find((i) => i.id_addon === ADDON_IDS.PAGES);
|
|
18
|
+
const domainsItem = items.find((i) => i.id_addon === ADDON_IDS.DOMAINS);
|
|
19
|
+
|
|
20
|
+
const pagesQty = pagesItem?.quantity ?? 0;
|
|
21
|
+
const domainsQty = domainsItem?.quantity ?? 1;
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
pages:
|
|
25
|
+
pagesQty === 0
|
|
26
|
+
? 'Páginas ilimitadas'
|
|
27
|
+
: pagesQty === 1
|
|
28
|
+
? '1 página'
|
|
29
|
+
: `${pagesQty} páginas`,
|
|
30
|
+
domains:
|
|
31
|
+
domainsQty >= 999
|
|
32
|
+
? 'Domínios ilimitados'
|
|
33
|
+
: domainsQty === 1
|
|
34
|
+
? '1 domínio externo'
|
|
35
|
+
: `${domainsQty} domínios externos`,
|
|
36
|
+
users: 'Usuários ilimitados',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function computePricingByPeriod(apiPlan: Plan): PlanPricingByPeriod {
|
|
41
|
+
const monthly = apiPlan.value;
|
|
42
|
+
const round2 = (n: number) => Math.round(n * 100) / 100;
|
|
43
|
+
return {
|
|
44
|
+
monthly,
|
|
45
|
+
semiannual: round2(monthly * (1 - apiPlan.discount_semester / 100)),
|
|
46
|
+
annual: round2(monthly * (1 - apiPlan.discount_annual / 100)),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function mapApiPlanToUiPlan(
|
|
51
|
+
apiPlan: Plan,
|
|
52
|
+
options: {
|
|
53
|
+
planId: number;
|
|
54
|
+
isPopular?: boolean;
|
|
55
|
+
buttonVariant?: 'brand' | 'default';
|
|
56
|
+
}
|
|
57
|
+
): UiPlan {
|
|
58
|
+
const { planId, isPopular, buttonVariant } = options;
|
|
59
|
+
|
|
60
|
+
const pricingByPeriod = computePricingByPeriod(apiPlan);
|
|
61
|
+
const monthlyFinal = pricingByPeriod.monthly;
|
|
62
|
+
|
|
63
|
+
const lowerName = apiPlan.name.toLowerCase();
|
|
64
|
+
const hasProjectAndOnboarding =
|
|
65
|
+
lowerName.includes('agência') || lowerName.includes('agencia');
|
|
66
|
+
|
|
67
|
+
const features: PlanFeature[] = [
|
|
68
|
+
...BASE_FEATURES,
|
|
69
|
+
hasProjectAndOnboarding
|
|
70
|
+
? { icon: 'check', text: 'Reunião de Onboarding' }
|
|
71
|
+
: { icon: 'x', text: 'Reunião de Onboarding', disabled: true },
|
|
72
|
+
hasProjectAndOnboarding
|
|
73
|
+
? { icon: 'check', text: 'Gestão de projetos', tooltip: 'projectManagement' }
|
|
74
|
+
: { icon: 'x', text: 'Gestão de projetos', disabled: true, tooltip: 'projectManagement' },
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
idPlan: planId,
|
|
79
|
+
name: apiPlan.name,
|
|
80
|
+
isPopular,
|
|
81
|
+
buttonVariant,
|
|
82
|
+
mainFeatures: buildMainFeaturesFromItems(apiPlan.items),
|
|
83
|
+
features,
|
|
84
|
+
originalPrice: formatCurrencyNumber(monthlyFinal),
|
|
85
|
+
price: formatCurrencyNumber(monthlyFinal),
|
|
86
|
+
pricingByPeriod,
|
|
87
|
+
items: apiPlan.items,
|
|
88
|
+
};
|
|
89
|
+
}
|
package/src/server.ts
CHANGED
|
@@ -23,6 +23,7 @@ export { findUserById } from './modules/users/action/find-user-by-id.action';
|
|
|
23
23
|
export { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';
|
|
24
24
|
export { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';
|
|
25
25
|
export { findPlanByIdAction } from './modules/plans/actions/find-plan-by-id.action';
|
|
26
|
+
export { listPlansAction } from './modules/plans/actions/list-plans.action';
|
|
26
27
|
export { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';
|
|
27
28
|
export { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';
|
|
28
29
|
export { listCardsAction } from './modules/cards/actions/list-cards.action';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formata um número (opcional) para moeda BRL
|
|
3
|
+
* @param value - Número a ser formatado (pode ser undefined ou null)
|
|
4
|
+
* @param decimals - Casas decimais (padrão: 2)
|
|
5
|
+
* @returns String formatada como "R$ X.XXX,XX"
|
|
6
|
+
*/
|
|
7
|
+
export const formatCurrencyNumber = (value?: number | null, decimals = 2): string => {
|
|
8
|
+
const safeValue = value ?? 0;
|
|
9
|
+
return safeValue.toLocaleString('pt-BR', {
|
|
10
|
+
style: 'currency',
|
|
11
|
+
currency: 'BRL',
|
|
12
|
+
minimumFractionDigits: decimals,
|
|
13
|
+
maximumFractionDigits: decimals,
|
|
14
|
+
});
|
|
15
|
+
};
|