@greatapps/common 1.1.543 → 1.1.546
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/account/ConfirmDeleteAccountModal.mjs +12 -10
- package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/DeleteAccountModal.mjs +21 -5
- package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/sections/MyProfileSection.mjs +3 -61
- package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs +5 -4
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
- package/dist/modules/accounts/actions/account-management.action.mjs +2 -2
- package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
- package/dist/modules/accounts/services/account.service.mjs +5 -2
- package/dist/modules/accounts/services/account.service.mjs.map +1 -1
- package/dist/modules/auth/hooks/useUserQuery.mjs +1 -1
- package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -1
- package/dist/modules/cards/types.mjs +13 -12
- package/dist/modules/cards/types.mjs.map +1 -1
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs +1 -1
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
- package/dist/modules/subscriptions/types/subscription.type.mjs +2 -1
- package/dist/modules/subscriptions/types/subscription.type.mjs.map +1 -1
- package/dist/store/useAccountModals.mjs +25 -4
- package/dist/store/useAccountModals.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/account/ConfirmDeleteAccountModal.tsx +16 -7
- package/src/components/account/DeleteAccountModal.tsx +24 -4
- package/src/components/account/sections/MyProfileSection.tsx +2 -68
- package/src/components/navigation/CancelledSubscriptionBanner.tsx +7 -4
- package/src/modules/accounts/actions/account-management.action.ts +3 -2
- package/src/modules/accounts/hooks/useAccountManagement.ts +2 -1
- package/src/modules/accounts/services/account.service.ts +6 -2
- package/src/modules/accounts/types.ts +4 -0
- package/src/modules/auth/hooks/useUserQuery.ts +1 -1
- package/src/modules/cards/types.ts +14 -12
- package/src/modules/plans/utils/map-api-plan-to-ui.ts +1 -1
- package/src/modules/subscriptions/types/subscription.type.ts +2 -1
- package/src/store/useAccountModals.ts +41 -8
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
|
+
import {
|
|
3
|
+
PaginationParamsSchema,
|
|
4
|
+
SearchParamsSchema,
|
|
5
|
+
SortParamsSchema
|
|
6
|
+
} from "../../infra/api/types";
|
|
2
7
|
const CardSchema = z.object({
|
|
3
8
|
id: z.union([z.number(), z.string()]),
|
|
4
|
-
id_wl: z.number()
|
|
5
|
-
id_account: z.union([z.number(), z.string()])
|
|
9
|
+
id_wl: z.number(),
|
|
10
|
+
id_account: z.union([z.number(), z.string()]),
|
|
6
11
|
id_gateway: z.union([z.number(), z.string()]).optional(),
|
|
7
|
-
gateway_account: z.string()
|
|
8
|
-
gateway_card: z.string()
|
|
12
|
+
gateway_account: z.string(),
|
|
13
|
+
gateway_card: z.string(),
|
|
9
14
|
brand: z.string(),
|
|
10
15
|
name: z.string(),
|
|
11
16
|
number: z.string().nullable(),
|
|
12
|
-
date: z.string().nullable()
|
|
17
|
+
date: z.string().nullable(),
|
|
13
18
|
deleted: z.number().transform((val) => val === 1).optional().default(false),
|
|
14
19
|
is_default: z.boolean().optional().default(false),
|
|
15
20
|
datetime_add: z.union([z.date(), z.coerce.date()]).nullable().optional(),
|
|
@@ -20,13 +25,9 @@ const CreateCardRequestSchema = z.object({
|
|
|
20
25
|
payment_method_id: z.string().min(1, "payment_method_id \xE9 obrigat\xF3rio"),
|
|
21
26
|
set_default: z.boolean().optional()
|
|
22
27
|
});
|
|
23
|
-
const FindCardsParamsSchema =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
search: z.string().optional(),
|
|
27
|
-
sort: z.string().optional(),
|
|
28
|
-
order: z.enum(["asc", "desc"]).optional()
|
|
29
|
-
});
|
|
28
|
+
const FindCardsParamsSchema = PaginationParamsSchema.extend(SearchParamsSchema.shape).extend(
|
|
29
|
+
SortParamsSchema.shape
|
|
30
|
+
);
|
|
30
31
|
export {
|
|
31
32
|
CardSchema,
|
|
32
33
|
CreateCardRequestSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/modules/cards/types.ts"],"sourcesContent":["import z from 'zod';\n\nexport const CardSchema = z.object({\n id: z.union([z.number(), z.string()]),\n id_wl: z.number()
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/cards/types.ts"],"sourcesContent":["import z from 'zod';\n\nimport {\n PaginationParamsSchema,\n SearchParamsSchema,\n SortParamsSchema,\n} from '../../infra/api/types';\n\nexport const CardSchema = z.object({\n id: z.union([z.number(), z.string()]),\n id_wl: z.number(),\n id_account: z.union([z.number(), z.string()]),\n id_gateway: z.union([z.number(), z.string()]).optional(),\n gateway_account: z.string(),\n gateway_card: z.string(),\n brand: z.string(),\n name: z.string(),\n number: z.string().nullable(),\n date: z.string().nullable(),\n deleted: z\n .number()\n .transform((val) => val === 1)\n .optional()\n .default(false),\n is_default: z.boolean().optional().default(false),\n datetime_add: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n datetime_alt: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n datetime_del: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n});\n\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const CreateCardRequestSchema = z.object({\n payment_method_id: z.string().min(1, 'payment_method_id é obrigatório'),\n set_default: z.boolean().optional(),\n});\n\nexport type CreateCardRequest = z.infer<typeof CreateCardRequestSchema>;\n\nexport const FindCardsParamsSchema = PaginationParamsSchema.extend(SearchParamsSchema.shape).extend(\n SortParamsSchema.shape\n);\n\nexport type FindCardsParams = z.infer<typeof FindCardsParamsSchema>;\n"],"mappings":"AAAA,OAAO,OAAO;AAEd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,aAAa,EAAE,OAAO;AAAA,EACjC,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EAC5C,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACvD,iBAAiB,EAAE,OAAO;AAAA,EAC1B,cAAc,EAAE,OAAO;AAAA,EACvB,OAAO,EAAE,OAAO;AAAA,EAChB,MAAM,EAAE,OAAO;AAAA,EACf,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,SAAS,EACN,OAAO,EACP,UAAU,CAAC,QAAQ,QAAQ,CAAC,EAC5B,SAAS,EACT,QAAQ,KAAK;AAAA,EAChB,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAAA,EAChD,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACvE,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACvE,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AACzE,CAAC;AAIM,MAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,mBAAmB,EAAE,OAAO,EAAE,IAAI,GAAG,uCAAiC;AAAA,EACtE,aAAa,EAAE,QAAQ,EAAE,SAAS;AACpC,CAAC;AAIM,MAAM,wBAAwB,uBAAuB,OAAO,mBAAmB,KAAK,EAAE;AAAA,EAC3F,iBAAiB;AACnB;","names":[]}
|
|
@@ -6,7 +6,7 @@ const BASE_FEATURES = [
|
|
|
6
6
|
{ icon: "check", text: "Compartilhar p\xE1ginas", tooltip: "sharePages" },
|
|
7
7
|
{ icon: "check", text: "Hospedagem inclusa" },
|
|
8
8
|
{ icon: "check", text: "SSL (HTTPS) + CDN" },
|
|
9
|
-
{ icon: "check", text: "Templates
|
|
9
|
+
{ icon: "check", text: "Templates gratuitos" }
|
|
10
10
|
];
|
|
11
11
|
function buildMainFeaturesFromItems(items) {
|
|
12
12
|
const pagesItem = items.find((i) => i.id_addon === ADDON_IDS.PAGES);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/plans/utils/map-api-plan-to-ui.ts"],"sourcesContent":["import type {\n Plan,\n PlanFeature,\n PlanMainFeatures,\n PlanPricingByPeriod,\n UiPlan,\n} from \"../types/plan.type\";\nimport { ADDON_IDS } from \"../../subscriptions/constants/addons.constants\";\nimport { 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
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/utils/map-api-plan-to-ui.ts"],"sourcesContent":["import type {\n Plan,\n PlanFeature,\n PlanMainFeatures,\n PlanPricingByPeriod,\n UiPlan,\n} from \"../types/plan.type\";\nimport { ADDON_IDS } from \"../../subscriptions/constants/addons.constants\";\nimport { 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 gratuitos\" },\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(plan: Plan): UiPlan {\n const popular = plan.id === 2 || plan.id_plan === 2;\n const buttonVariant = popular ? \"brand\" : \"default\";\n\n const pricingByPeriod = computePricingByPeriod(plan);\n const monthlyFinal = pricingByPeriod.monthly;\n\n const lowerName = plan.name.toLowerCase();\n const hasProjectAndOnboarding =\n lowerName.includes(\"agência\") || lowerName.includes(\"agencia\");\n\n const 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 ? {\n icon: \"check\",\n text: \"Gestão de projetos\",\n tooltip: \"projectManagement\",\n }\n : {\n icon: \"x\",\n text: \"Gestão de projetos\",\n disabled: true,\n tooltip: \"projectManagement\",\n },\n ];\n\n return {\n planId: plan.id,\n name: plan.name,\n isPopular: popular,\n buttonVariant,\n mainFeatures: buildMainFeaturesFromItems(plan.items),\n features,\n originalPrice: formatCurrencyNumber(monthlyFinal),\n price: formatCurrencyNumber(monthlyFinal),\n pricingByPeriod,\n items: plan.items,\n };\n}\n"],"mappings":"AAOA,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,sBAAsB;AAC/C;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,mBAAmB,MAAoB;AACrD,QAAM,UAAU,KAAK,OAAO,KAAK,KAAK,YAAY;AAClD,QAAM,gBAAgB,UAAU,UAAU;AAE1C,QAAM,kBAAkB,uBAAuB,IAAI;AACnD,QAAM,eAAe,gBAAgB;AAErC,QAAM,YAAY,KAAK,KAAK,YAAY;AACxC,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;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,IACX,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX;AAAA,EACN;AAEA,SAAO;AAAA,IACL,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX,WAAW;AAAA,IACX;AAAA,IACA,cAAc,2BAA2B,KAAK,KAAK;AAAA,IACnD;AAAA,IACA,eAAe,qBAAqB,YAAY;AAAA,IAChD,OAAO,qBAAqB,YAAY;AAAA,IACxC;AAAA,IACA,OAAO,KAAK;AAAA,EACd;AACF;","names":[]}
|
|
@@ -37,7 +37,7 @@ const SubscriptionSchema = z.object({
|
|
|
37
37
|
id_gateway: z.union([z.number(), z.string()]).nullable(),
|
|
38
38
|
gateway_account: z.string().nullable(),
|
|
39
39
|
date_hiring: z.coerce.date().nullable(),
|
|
40
|
-
date_due: z.coerce.date(),
|
|
40
|
+
date_due: z.coerce.date().nullable(),
|
|
41
41
|
date_cancellation: z.coerce.date().nullable(),
|
|
42
42
|
date_verification: z.coerce.date().nullable(),
|
|
43
43
|
cancellation_reason: z.string().nullable(),
|
|
@@ -48,6 +48,7 @@ const SubscriptionSchema = z.object({
|
|
|
48
48
|
card_name: z.string().nullable().optional(),
|
|
49
49
|
card_brand: z.string().nullable().optional(),
|
|
50
50
|
card_number: z.string().nullable().optional(),
|
|
51
|
+
card: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
51
52
|
items: z.array(SubscriptionItemSchema),
|
|
52
53
|
pending_change: z.object({
|
|
53
54
|
schedule_id: z.string(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/subscriptions/types/subscription.type.ts"],"sourcesContent":["import z from 'zod';\r\n\r\nexport const SubscriptionItemSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_subscription: z.union([z.number(), z.string()]),\r\n id_addon: z.number().nullable(),\r\n addon_name: z.string().optional(),\r\n value: z.number(),\r\n currency: z.string(),\r\n quantity: z.number(),\r\n payment_status: z.number(),\r\n id_charge: z.union([z.number(), z.string()]).nullable(),\r\n trial: z.boolean(),\r\n trial_ends_at: z.coerce.date().nullable().optional(),\r\n});\r\n\r\nexport type SubscriptionItem = z.infer<typeof SubscriptionItemSchema>;\r\n\r\nexport const SubscriptionSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_account: z.union([z.number(), z.string()]),\r\n id_card: z.union([z.number(), z.string()]).nullable(),\r\n id_coupon: z.union([z.number(), z.string()]).nullable(),\r\n type: z.string(),\r\n payment_method: z.number().nullable(),\r\n periodicity: z.coerce.number().nullable(),\r\n value: z.number().nullable(),\r\n id_product: z.number(),\r\n id_plan: z.number(),\r\n plan_name: z.string().nullable().optional(),\r\n id_gateway: z.union([z.number(), z.string()]).nullable(),\r\n gateway_account: z.string().nullable(),\r\n date_hiring: z.coerce.date().nullable(),\r\n date_due: z.coerce.date(),\r\n date_cancellation: z.coerce.date().nullable(),\r\n date_verification: z.coerce.date().nullable(),\r\n cancellation_reason: z.string().nullable(),\r\n cancellation_description: z.string().nullable(),\r\n active: z.boolean(),\r\n charged: z.boolean(),\r\n datetime_last_update_periodicity: z.coerce.date().nullable().optional(),\r\n card_name: z.string().nullable().optional(),\r\n card_brand: z.string().nullable().optional(),\r\n card_number: z.string().nullable().optional(),\r\n items: z.array(SubscriptionItemSchema),\r\n pending_change: z.object({\r\n schedule_id: z.string(),\r\n schedule_status: z.string(),\r\n kind: z.string(),\r\n takes_effect_at: z.number(),\r\n takes_effect_at_iso: z.string(),\r\n new_plan: z.object({\r\n id: z.number(),\r\n name: z.string(),\r\n periodicity: z.number(),\r\n value: z.number(),\r\n value_gross: z.number(),\r\n }),\r\n new_items: z.array(z.object({\r\n price_id: z.string(),\r\n id_addon: z.number().nullable(),\r\n addon_name: z.string(),\r\n quantity: z.number(),\r\n unit_value: z.number(),\r\n value: z.number(),\r\n is_plan_base: z.boolean(),\r\n is_ai_credit: z.boolean(),\r\n })),\r\n new_discounts: z.array(z.unknown()),\r\n changes: z.array(z.object({\r\n type: z.string(),\r\n from: z.unknown(),\r\n to: z.unknown(),\r\n })),\r\n }).nullable().optional(),\r\n});\r\n\r\nexport type Subscription = z.infer<typeof SubscriptionSchema>;\r\n\r\nexport interface FindSubscriptionsParams {\r\n active?: boolean;\r\n trial?: boolean;\r\n date_start?: string;\r\n date_end?: string;\r\n date_hiring_start?: string;\r\n date_hiring_end?: string;\r\n limit?: number;\r\n}\r\n"],"mappings":"AAAA,OAAO,OAAO;AAEP,MAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,SAAS,EAAE,OAAO;AAAA,EAClB,cAAc,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EAClD,cAAc,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EAClD,cAAc,EAAE,OAAO,KAAK;AAAA,EAC5B,OAAO,EAAE,OAAO;AAAA,EAChB,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACjD,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,OAAO,EAAE,OAAO;AAAA,EAChB,UAAU,EAAE,OAAO;AAAA,EACnB,UAAU,EAAE,OAAO;AAAA,EACnB,gBAAgB,EAAE,OAAO;AAAA,EACzB,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACtD,OAAO,EAAE,QAAQ;AAAA,EACjB,eAAe,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS;AACrD,CAAC;AAIM,MAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,SAAS,EAAE,OAAO;AAAA,EAClB,cAAc,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EAClD,cAAc,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EAClD,cAAc,EAAE,OAAO,KAAK;AAAA,EAC5B,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EAC5C,SAAS,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACpD,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACtD,MAAM,EAAE,OAAO;AAAA,EACf,gBAAgB,EAAE,OAAO,EAAE,SAAS;AAAA,EACpC,aAAa,EAAE,OAAO,OAAO,EAAE,SAAS;AAAA,EACxC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,YAAY,EAAE,OAAO;AAAA,EACrB,SAAS,EAAE,OAAO;AAAA,EAClB,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC1C,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACvD,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,aAAa,EAAE,OAAO,KAAK,EAAE,SAAS;AAAA,EACtC,UAAU,EAAE,OAAO,KAAK;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/subscriptions/types/subscription.type.ts"],"sourcesContent":["import z from 'zod';\r\n\r\nexport const SubscriptionItemSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_subscription: z.union([z.number(), z.string()]),\r\n id_addon: z.number().nullable(),\r\n addon_name: z.string().optional(),\r\n value: z.number(),\r\n currency: z.string(),\r\n quantity: z.number(),\r\n payment_status: z.number(),\r\n id_charge: z.union([z.number(), z.string()]).nullable(),\r\n trial: z.boolean(),\r\n trial_ends_at: z.coerce.date().nullable().optional(),\r\n});\r\n\r\nexport type SubscriptionItem = z.infer<typeof SubscriptionItemSchema>;\r\n\r\nexport const SubscriptionSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_account: z.union([z.number(), z.string()]),\r\n id_card: z.union([z.number(), z.string()]).nullable(),\r\n id_coupon: z.union([z.number(), z.string()]).nullable(),\r\n type: z.string(),\r\n payment_method: z.number().nullable(),\r\n periodicity: z.coerce.number().nullable(),\r\n value: z.number().nullable(),\r\n id_product: z.number(),\r\n id_plan: z.number(),\r\n plan_name: z.string().nullable().optional(),\r\n id_gateway: z.union([z.number(), z.string()]).nullable(),\r\n gateway_account: z.string().nullable(),\r\n date_hiring: z.coerce.date().nullable(),\r\n date_due: z.coerce.date().nullable(),\r\n date_cancellation: z.coerce.date().nullable(),\r\n date_verification: z.coerce.date().nullable(),\r\n cancellation_reason: z.string().nullable(),\r\n cancellation_description: z.string().nullable(),\r\n active: z.boolean(),\r\n charged: z.boolean(),\r\n datetime_last_update_periodicity: z.coerce.date().nullable().optional(),\r\n card_name: z.string().nullable().optional(),\r\n card_brand: z.string().nullable().optional(),\r\n card_number: z.string().nullable().optional(),\r\n card: z.record(z.string(), z.unknown()).nullable().optional(),\r\n items: z.array(SubscriptionItemSchema),\r\n pending_change: z.object({\r\n schedule_id: z.string(),\r\n schedule_status: z.string(),\r\n kind: z.string(),\r\n takes_effect_at: z.number(),\r\n takes_effect_at_iso: z.string(),\r\n new_plan: z.object({\r\n id: z.number(),\r\n name: z.string(),\r\n periodicity: z.number(),\r\n value: z.number(),\r\n value_gross: z.number(),\r\n }),\r\n new_items: z.array(z.object({\r\n price_id: z.string(),\r\n id_addon: z.number().nullable(),\r\n addon_name: z.string(),\r\n quantity: z.number(),\r\n unit_value: z.number(),\r\n value: z.number(),\r\n is_plan_base: z.boolean(),\r\n is_ai_credit: z.boolean(),\r\n })),\r\n new_discounts: z.array(z.unknown()),\r\n changes: z.array(z.object({\r\n type: z.string(),\r\n from: z.unknown(),\r\n to: z.unknown(),\r\n })),\r\n }).nullable().optional(),\r\n});\r\n\r\nexport type Subscription = z.infer<typeof SubscriptionSchema>;\r\n\r\nexport interface FindSubscriptionsParams {\r\n active?: boolean;\r\n trial?: boolean;\r\n date_start?: string;\r\n date_end?: string;\r\n date_hiring_start?: string;\r\n date_hiring_end?: string;\r\n limit?: number;\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -4,12 +4,33 @@ const useAccountModals = create((set) => ({
|
|
|
4
4
|
activeModal: null,
|
|
5
5
|
config: {},
|
|
6
6
|
initialSection: void 0,
|
|
7
|
+
deleteAccountPayload: null,
|
|
8
|
+
deleteAccountError: null,
|
|
7
9
|
updateConfig: (config) => set({ config }),
|
|
8
|
-
openConfigurations: (initialSection) => set({
|
|
9
|
-
|
|
10
|
+
openConfigurations: (initialSection) => set({
|
|
11
|
+
activeModal: "configurations",
|
|
12
|
+
initialSection,
|
|
13
|
+
deleteAccountPayload: null,
|
|
14
|
+
deleteAccountError: null
|
|
15
|
+
}),
|
|
16
|
+
openDeleteAccount: (error) => set({
|
|
17
|
+
activeModal: "deleteAccount",
|
|
18
|
+
deleteAccountPayload: null,
|
|
19
|
+
deleteAccountError: error ?? null
|
|
20
|
+
}),
|
|
10
21
|
openIsntPossibleDelete: () => set({ activeModal: "isntPossibleDelete" }),
|
|
11
|
-
openConfirmDelete: () => set({
|
|
12
|
-
|
|
22
|
+
openConfirmDelete: (payload) => set({
|
|
23
|
+
activeModal: "confirmDelete",
|
|
24
|
+
deleteAccountPayload: payload,
|
|
25
|
+
deleteAccountError: null
|
|
26
|
+
}),
|
|
27
|
+
clearDeleteAccountError: () => set({ deleteAccountError: null }),
|
|
28
|
+
close: () => set({
|
|
29
|
+
activeModal: null,
|
|
30
|
+
initialSection: void 0,
|
|
31
|
+
deleteAccountPayload: null,
|
|
32
|
+
deleteAccountError: null
|
|
33
|
+
})
|
|
13
34
|
}));
|
|
14
35
|
export {
|
|
15
36
|
useAccountModals
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/store/useAccountModals.ts"],"sourcesContent":["'use client';\n\nimport { create } from 'zustand';\nimport type { AccountSectionType } from '../enums/AccountSectionType';\n\ntype AccountModalType =\n | 'configurations'\n | 'deleteAccount'\n | 'isntPossibleDelete'\n | 'confirmDelete';\n\nexport interface AccountModalsConfig {\n onGoToSubscription?: () => void;\n}\n\ninterface AccountModalsState {\n activeModal: AccountModalType | null;\n config: AccountModalsConfig;\n initialSection?: AccountSectionType;\n\n /** Called by <AccountModals> to keep app-level config in sync */\n updateConfig: (config: AccountModalsConfig) => void;\n\n openConfigurations: (initialSection?: AccountSectionType) => void;\n openDeleteAccount: () => void;\n openIsntPossibleDelete: () => void;\n openConfirmDelete: () => void;\n close: () => void;\n}\n\nexport const useAccountModals = create<AccountModalsState>((set) => ({\n activeModal: null,\n config: {},\n initialSection: undefined,\n\n updateConfig: (config) => set({ config }),\n\n openConfigurations: (initialSection) =>\n set({
|
|
1
|
+
{"version":3,"sources":["../../src/store/useAccountModals.ts"],"sourcesContent":["'use client';\n\nimport { create } from 'zustand';\nimport type { AccountSectionType } from '../enums/AccountSectionType';\n\ntype AccountModalType =\n | 'configurations'\n | 'deleteAccount'\n | 'isntPossibleDelete'\n | 'confirmDelete';\n\nexport interface AccountModalsConfig {\n onGoToSubscription?: () => void;\n}\n\ninterface DeleteAccountPayload {\n password: string;\n}\n\ninterface AccountModalsState {\n activeModal: AccountModalType | null;\n config: AccountModalsConfig;\n initialSection?: AccountSectionType;\n\n /** Payload coletado no DeleteAccountModal, consumido pelo ConfirmDeleteAccountModal. */\n deleteAccountPayload: DeleteAccountPayload | null;\n /** Mensagem de erro do backend quando o delete falha (ex.: senha inválida).\n * Mostrada no DeleteAccountModal quando o usuário é mandado de volta. */\n deleteAccountError: string | null;\n\n /** Called by <AccountModals> to keep app-level config in sync */\n updateConfig: (config: AccountModalsConfig) => void;\n\n openConfigurations: (initialSection?: AccountSectionType) => void;\n openDeleteAccount: (error?: string) => void;\n openIsntPossibleDelete: () => void;\n openConfirmDelete: (payload: DeleteAccountPayload) => void;\n clearDeleteAccountError: () => void;\n close: () => void;\n}\n\nexport const useAccountModals = create<AccountModalsState>((set) => ({\n activeModal: null,\n config: {},\n initialSection: undefined,\n deleteAccountPayload: null,\n deleteAccountError: null,\n\n updateConfig: (config) => set({ config }),\n\n openConfigurations: (initialSection) =>\n set({\n activeModal: 'configurations',\n initialSection,\n deleteAccountPayload: null,\n deleteAccountError: null,\n }),\n\n openDeleteAccount: (error) =>\n set({\n activeModal: 'deleteAccount',\n deleteAccountPayload: null,\n deleteAccountError: error ?? null,\n }),\n\n openIsntPossibleDelete: () =>\n set({ activeModal: 'isntPossibleDelete' }),\n\n openConfirmDelete: (payload) =>\n set({\n activeModal: 'confirmDelete',\n deleteAccountPayload: payload,\n deleteAccountError: null,\n }),\n\n clearDeleteAccountError: () => set({ deleteAccountError: null }),\n\n close: () =>\n set({\n activeModal: null,\n initialSection: undefined,\n deleteAccountPayload: null,\n deleteAccountError: null,\n }),\n}));\n"],"mappings":";AAEA,SAAS,cAAc;AAuChB,MAAM,mBAAmB,OAA2B,CAAC,SAAS;AAAA,EACnE,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EAEpB,cAAc,CAAC,WAAW,IAAI,EAAE,OAAO,CAAC;AAAA,EAExC,oBAAoB,CAAC,mBACnB,IAAI;AAAA,IACF,aAAa;AAAA,IACb;AAAA,IACA,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,EACtB,CAAC;AAAA,EAEH,mBAAmB,CAAC,UAClB,IAAI;AAAA,IACF,aAAa;AAAA,IACb,sBAAsB;AAAA,IACtB,oBAAoB,SAAS;AAAA,EAC/B,CAAC;AAAA,EAEH,wBAAwB,MACtB,IAAI,EAAE,aAAa,qBAAqB,CAAC;AAAA,EAE3C,mBAAmB,CAAC,YAClB,IAAI;AAAA,IACF,aAAa;AAAA,IACb,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,EACtB,CAAC;AAAA,EAEH,yBAAyB,MAAM,IAAI,EAAE,oBAAoB,KAAK,CAAC;AAAA,EAE/D,OAAO,MACL,IAAI;AAAA,IACF,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,EACtB,CAAC;AACL,EAAE;","names":[]}
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@ import { useAuth } from '../../providers/auth.provider';
|
|
|
15
15
|
import { UserProfile } from '../../modules/users/schema';
|
|
16
16
|
|
|
17
17
|
export default function ConfirmDeleteAccountModal() {
|
|
18
|
-
const { activeModal, close } = useAccountModals();
|
|
18
|
+
const { activeModal, deleteAccountPayload, openDeleteAccount, close } = useAccountModals();
|
|
19
19
|
const open = activeModal === 'confirmDelete';
|
|
20
20
|
|
|
21
21
|
const { data: pagesCount = 0 } = useCountPages();
|
|
@@ -30,7 +30,13 @@ export default function ConfirmDeleteAccountModal() {
|
|
|
30
30
|
const handleConfirm = async () => {
|
|
31
31
|
try {
|
|
32
32
|
if (isOwner) {
|
|
33
|
-
|
|
33
|
+
if (!deleteAccountPayload) {
|
|
34
|
+
// Fluxo quebrado (usuário pulou o primeiro modal ou refresh) — manda
|
|
35
|
+
// de volta pro modal inicial pra re-coletar a senha.
|
|
36
|
+
openDeleteAccount('Sessão expirada. Preencha os campos novamente.');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await deleteAccount.mutateAsync({ password: deleteAccountPayload.password });
|
|
34
40
|
} else {
|
|
35
41
|
await deleteAccountUser.mutateAsync(user!.id);
|
|
36
42
|
}
|
|
@@ -40,12 +46,15 @@ export default function ConfirmDeleteAccountModal() {
|
|
|
40
46
|
));
|
|
41
47
|
await logout();
|
|
42
48
|
} catch (error) {
|
|
49
|
+
const message = error instanceof Error ? error.message : 'Erro ao excluir. Tente novamente.';
|
|
50
|
+
if (isOwner) {
|
|
51
|
+
// Falha no delete do owner (ex.: senha inválida) — volta pro primeiro
|
|
52
|
+
// modal com a mensagem do backend pra o usuário corrigir e tentar de novo.
|
|
53
|
+
openDeleteAccount(message);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
43
56
|
toast.custom((t) => (
|
|
44
|
-
<Toast
|
|
45
|
-
variant="error"
|
|
46
|
-
message={error instanceof Error ? error.message : 'Erro ao excluir. Tente novamente.'}
|
|
47
|
-
toastId={t}
|
|
48
|
-
/>
|
|
57
|
+
<Toast variant="error" message={message} toastId={t} />
|
|
49
58
|
));
|
|
50
59
|
}
|
|
51
60
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState, useCallback } from 'react';
|
|
3
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
4
4
|
import { IconLock, IconAlertTriangle } from '@tabler/icons-react';
|
|
5
5
|
import { toast } from 'sonner';
|
|
6
6
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';
|
|
@@ -23,7 +23,13 @@ const REASON_OPTIONS = [
|
|
|
23
23
|
];
|
|
24
24
|
|
|
25
25
|
export default function DeleteAccountModal() {
|
|
26
|
-
const {
|
|
26
|
+
const {
|
|
27
|
+
activeModal,
|
|
28
|
+
deleteAccountError,
|
|
29
|
+
openConfigurations,
|
|
30
|
+
openConfirmDelete,
|
|
31
|
+
clearDeleteAccountError,
|
|
32
|
+
} = useAccountModals();
|
|
27
33
|
const open = activeModal === 'deleteAccount';
|
|
28
34
|
|
|
29
35
|
const [reason, setReason] = useState('');
|
|
@@ -39,6 +45,14 @@ export default function DeleteAccountModal() {
|
|
|
39
45
|
setPassword('');
|
|
40
46
|
}, []);
|
|
41
47
|
|
|
48
|
+
// Quando o modal deixa de estar aberto, limpa o erro residual do store
|
|
49
|
+
// pra não aparecer numa próxima abertura vinda de fluxo limpo.
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!open) {
|
|
52
|
+
clearDeleteAccountError();
|
|
53
|
+
}
|
|
54
|
+
}, [open, clearDeleteAccountError]);
|
|
55
|
+
|
|
42
56
|
const handleClose = () => {
|
|
43
57
|
resetForm();
|
|
44
58
|
openConfigurations(AccountSectionType.SECURITY);
|
|
@@ -52,8 +66,9 @@ export default function DeleteAccountModal() {
|
|
|
52
66
|
));
|
|
53
67
|
return;
|
|
54
68
|
}
|
|
69
|
+
openConfirmDelete({ password });
|
|
70
|
+
// Campos locais podem ser limpos — o payload já está no store.
|
|
55
71
|
resetForm();
|
|
56
|
-
openConfirmDelete();
|
|
57
72
|
};
|
|
58
73
|
|
|
59
74
|
return (
|
|
@@ -104,10 +119,15 @@ export default function DeleteAccountModal() {
|
|
|
104
119
|
placeholder="Informe sua senha"
|
|
105
120
|
leftIcon={IconLock}
|
|
106
121
|
value={password}
|
|
107
|
-
onChange={(e) =>
|
|
122
|
+
onChange={(e) => {
|
|
123
|
+
setPassword(e.target.value);
|
|
124
|
+
if (deleteAccountError) clearDeleteAccountError();
|
|
125
|
+
}}
|
|
108
126
|
classnameContainer="h-10!"
|
|
109
127
|
showPassword={showPassword}
|
|
110
128
|
onTogglePassword={togglePassword}
|
|
129
|
+
error={!!deleteAccountError}
|
|
130
|
+
errorMessage={deleteAccountError ?? undefined}
|
|
111
131
|
/>
|
|
112
132
|
</div>
|
|
113
133
|
|
|
@@ -10,18 +10,12 @@ import { ACCEPTED_IMAGE_FORMATS_STRING } from '../../../modules/images/constants
|
|
|
10
10
|
import { Button } from '../../ui/buttons/Button';
|
|
11
11
|
import { Separator } from '../../ui/data-display/Separator';
|
|
12
12
|
import { Toast } from '../../ui/feedback/Toast';
|
|
13
|
-
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';
|
|
14
13
|
import { FormField } from '../../ui/form/FormField';
|
|
15
14
|
import { SelectField } from '../../ui/form/SelectField';
|
|
16
15
|
import PhoneInput from '../../ui/form/PhoneInput';
|
|
17
16
|
import { useAuth } from '../../../providers/auth.provider';
|
|
18
|
-
import { UserProfile } from '../../../modules/users/schema';
|
|
19
17
|
import { myProfileSchema, type MyProfileFormData } from '../../../utils/validators/account';
|
|
20
|
-
import {
|
|
21
|
-
useUpdateAccountUser,
|
|
22
|
-
useDeleteAccount,
|
|
23
|
-
useDeleteAccountUser,
|
|
24
|
-
} from '../../../modules/accounts/hooks/useAccountManagement';
|
|
18
|
+
import { useUpdateAccountUser } from '../../../modules/accounts/hooks/useAccountManagement';
|
|
25
19
|
import { GENDER_OPTIONS } from '../constants';
|
|
26
20
|
import { ChangePhoneModal } from './ChangePhoneModal';
|
|
27
21
|
import { ChangeEmailModal } from './ChangeEmailModal';
|
|
@@ -32,19 +26,13 @@ interface MyProfileSectionProps {
|
|
|
32
26
|
}
|
|
33
27
|
|
|
34
28
|
export function MyProfileSection({ onClose, storageUrl }: MyProfileSectionProps) {
|
|
35
|
-
const { user
|
|
29
|
+
const { user } = useAuth();
|
|
36
30
|
const updateAccountUser = useUpdateAccountUser();
|
|
37
|
-
const deleteAccount = useDeleteAccount();
|
|
38
|
-
const deleteAccountUser = useDeleteAccountUser();
|
|
39
31
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
40
32
|
const [selectedPhoto, setSelectedPhoto] = useState<File | null>(null);
|
|
41
33
|
const [photoRemoved, setPhotoRemoved] = useState(false);
|
|
42
34
|
const [changePhoneOpen, setChangePhoneOpen] = useState(false);
|
|
43
35
|
const [changeEmailOpen, setChangeEmailOpen] = useState(false);
|
|
44
|
-
const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
|
|
45
|
-
|
|
46
|
-
const isOwner = user?.profile === UserProfile.owner;
|
|
47
|
-
const isDeleting = deleteAccount.isPending || deleteAccountUser.isPending;
|
|
48
36
|
|
|
49
37
|
const form = useForm<MyProfileFormData>({
|
|
50
38
|
resolver: zodResolver(myProfileSchema),
|
|
@@ -85,26 +73,6 @@ export function MyProfileSection({ onClose, storageUrl }: MyProfileSectionProps)
|
|
|
85
73
|
setPhotoRemoved(true);
|
|
86
74
|
};
|
|
87
75
|
|
|
88
|
-
const handleDelete = async () => {
|
|
89
|
-
try {
|
|
90
|
-
if (isOwner) {
|
|
91
|
-
await deleteAccount.mutateAsync();
|
|
92
|
-
} else {
|
|
93
|
-
await deleteAccountUser.mutateAsync(user!.id);
|
|
94
|
-
}
|
|
95
|
-
await logout();
|
|
96
|
-
} catch (error) {
|
|
97
|
-
toast.custom((t) => (
|
|
98
|
-
<Toast
|
|
99
|
-
variant="error"
|
|
100
|
-
message={error instanceof Error ? error.message : 'Erro ao excluir. Tente novamente.'}
|
|
101
|
-
toastId={t}
|
|
102
|
-
/>
|
|
103
|
-
));
|
|
104
|
-
setDeleteConfirmOpen(false);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
76
|
const onSubmit = async (data: MyProfileFormData) => {
|
|
109
77
|
try {
|
|
110
78
|
await updateAccountUser.mutateAsync({
|
|
@@ -289,40 +257,6 @@ export function MyProfileSection({ onClose, storageUrl }: MyProfileSectionProps)
|
|
|
289
257
|
|
|
290
258
|
<ChangePhoneModal open={changePhoneOpen} onClose={() => setChangePhoneOpen(false)} />
|
|
291
259
|
<ChangeEmailModal open={changeEmailOpen} onClose={() => setChangeEmailOpen(false)} />
|
|
292
|
-
|
|
293
|
-
<Dialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
|
|
294
|
-
<DialogContent className="max-w-sm! gap-5">
|
|
295
|
-
<DialogHeader>
|
|
296
|
-
<DialogTitle className="paragraph-large-semibold text-gray-950">
|
|
297
|
-
{isOwner ? 'Excluir conta' : 'Excluir usuário'}
|
|
298
|
-
</DialogTitle>
|
|
299
|
-
</DialogHeader>
|
|
300
|
-
<p className="paragraph-small-regular text-gray-600">
|
|
301
|
-
{isOwner
|
|
302
|
-
? 'Tem certeza que deseja excluir sua conta? Todos os dados serão apagados permanentemente e essa ação não pode ser desfeita.'
|
|
303
|
-
: 'Tem certeza que deseja excluir seu usuário? Você perderá acesso a esta conta permanentemente.'}
|
|
304
|
-
</p>
|
|
305
|
-
<div className="flex items-center gap-3 justify-end">
|
|
306
|
-
<Button
|
|
307
|
-
type="button"
|
|
308
|
-
variant="secondary"
|
|
309
|
-
className="h-10!"
|
|
310
|
-
disabled={isDeleting}
|
|
311
|
-
onClick={() => setDeleteConfirmOpen(false)}
|
|
312
|
-
>
|
|
313
|
-
Cancelar
|
|
314
|
-
</Button>
|
|
315
|
-
<Button
|
|
316
|
-
type="button"
|
|
317
|
-
className="h-10! bg-red-600 hover:bg-red-700 text-white border-0!"
|
|
318
|
-
disabled={isDeleting}
|
|
319
|
-
onClick={handleDelete}
|
|
320
|
-
>
|
|
321
|
-
{isDeleting ? 'Excluindo...' : 'Confirmar exclusão'}
|
|
322
|
-
</Button>
|
|
323
|
-
</div>
|
|
324
|
-
</DialogContent>
|
|
325
|
-
</Dialog>
|
|
326
260
|
</>
|
|
327
261
|
);
|
|
328
262
|
}
|
|
@@ -20,16 +20,19 @@ export function CancelledSubscriptionBanner({ onReactivate }: CancelledSubscript
|
|
|
20
20
|
}, []);
|
|
21
21
|
|
|
22
22
|
const dismiss = useCallback(() => setVisible(false), []);
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
if (!visible) return null;
|
|
25
|
+
if (!subscription?.date_due) return null;
|
|
26
|
+
|
|
27
|
+
const dueDate = new Date(subscription.date_due);
|
|
24
28
|
const today = new Date();
|
|
25
29
|
const isPastDue = today >= dueDate;
|
|
26
30
|
const formattedDate = formatShortDate(dueDate);
|
|
27
31
|
|
|
28
|
-
const isTrial = subscription
|
|
32
|
+
const isTrial = subscription.type === 'trial';
|
|
29
33
|
|
|
30
|
-
if (!visible) return null;
|
|
31
34
|
if (isTrial && !isPastDue) return null;
|
|
32
|
-
if (!isTrial && (!subscription
|
|
35
|
+
if (!isTrial && (!subscription.date_cancellation || isPastDue)) return null;
|
|
33
36
|
|
|
34
37
|
return (
|
|
35
38
|
<div className="fixed top-[80px] md:top-0 left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0">
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
AccountUsersPaginationParams,
|
|
8
8
|
ChangePasswordRequest,
|
|
9
9
|
CreateAccountUserRequest,
|
|
10
|
+
DeleteAccountRequest,
|
|
10
11
|
UpdateAccountRequest,
|
|
11
12
|
UpdateAccountUserRequest,
|
|
12
13
|
} from '../types';
|
|
@@ -54,8 +55,8 @@ export async function deleteAccountUserAction(userId: number) {
|
|
|
54
55
|
return safeMutationAction(() => accountService.deleteAccountUser(userId));
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
export async function deleteAccountAction() {
|
|
58
|
-
return safeMutationAction(() => accountService.deleteAccount());
|
|
58
|
+
export async function deleteAccountAction(data: DeleteAccountRequest) {
|
|
59
|
+
return safeMutationAction(() => accountService.deleteAccount(data));
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
export async function createAccountUserAction(user: CreateAccountUserRequest) {
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
UpdateAccountRequest,
|
|
8
8
|
UpdateAccountUserRequest,
|
|
9
9
|
DeleteAccountUserResponse,
|
|
10
|
+
DeleteAccountRequest,
|
|
10
11
|
DeleteAccountResponse,
|
|
11
12
|
} from '../types';
|
|
12
13
|
import {
|
|
@@ -85,7 +86,7 @@ export function useDeleteAccountUser(
|
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
export function useDeleteAccount(
|
|
88
|
-
options?: UseMutationOptions<DeleteAccountResponse, Error,
|
|
89
|
+
options?: UseMutationOptions<DeleteAccountResponse, Error, DeleteAccountRequest>
|
|
89
90
|
) {
|
|
90
91
|
return useMutation({
|
|
91
92
|
mutationFn: withAction(deleteAccountAction),
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
ChangeUserPhotoResponse,
|
|
16
16
|
CreateAccountUserRequest,
|
|
17
17
|
CreateAccountUserResponse,
|
|
18
|
+
DeleteAccountRequest,
|
|
18
19
|
DeleteAccountResponse,
|
|
19
20
|
DeleteAccountUserResponse,
|
|
20
21
|
GetAccountDataResponse,
|
|
@@ -94,9 +95,12 @@ class AccountService {
|
|
|
94
95
|
return response;
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
async deleteAccount(): Promise<DeleteAccountResponse> {
|
|
98
|
+
async deleteAccount(data: DeleteAccountRequest): Promise<DeleteAccountResponse> {
|
|
98
99
|
const { id_account } = await getUserContext();
|
|
99
|
-
const response = await api.apps.delete<DeleteAccountResponse>(
|
|
100
|
+
const response = await api.apps.delete<DeleteAccountResponse>(
|
|
101
|
+
`/accounts/${id_account}`,
|
|
102
|
+
{ body: JSON.stringify(data) }
|
|
103
|
+
);
|
|
100
104
|
|
|
101
105
|
if (response.status === 0) {
|
|
102
106
|
throw new ApiError(response.message || 'Erro ao deletar conta', 'DELETE_ACCOUNT_FAILED', 400);
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
PaginationParamsSchema,
|
|
5
|
+
SearchParamsSchema,
|
|
6
|
+
SortParamsSchema,
|
|
7
|
+
} from '../../infra/api/types';
|
|
8
|
+
|
|
3
9
|
export const CardSchema = z.object({
|
|
4
10
|
id: z.union([z.number(), z.string()]),
|
|
5
|
-
id_wl: z.number()
|
|
6
|
-
id_account: z.union([z.number(), z.string()])
|
|
11
|
+
id_wl: z.number(),
|
|
12
|
+
id_account: z.union([z.number(), z.string()]),
|
|
7
13
|
id_gateway: z.union([z.number(), z.string()]).optional(),
|
|
8
|
-
gateway_account: z.string()
|
|
9
|
-
gateway_card: z.string()
|
|
14
|
+
gateway_account: z.string(),
|
|
15
|
+
gateway_card: z.string(),
|
|
10
16
|
brand: z.string(),
|
|
11
17
|
name: z.string(),
|
|
12
18
|
number: z.string().nullable(),
|
|
13
|
-
date: z.string().nullable()
|
|
19
|
+
date: z.string().nullable(),
|
|
14
20
|
deleted: z
|
|
15
21
|
.number()
|
|
16
22
|
.transform((val) => val === 1)
|
|
@@ -31,12 +37,8 @@ export const CreateCardRequestSchema = z.object({
|
|
|
31
37
|
|
|
32
38
|
export type CreateCardRequest = z.infer<typeof CreateCardRequestSchema>;
|
|
33
39
|
|
|
34
|
-
export const FindCardsParamsSchema =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
search: z.string().optional(),
|
|
38
|
-
sort: z.string().optional(),
|
|
39
|
-
order: z.enum(['asc', 'desc']).optional(),
|
|
40
|
-
});
|
|
40
|
+
export const FindCardsParamsSchema = PaginationParamsSchema.extend(SearchParamsSchema.shape).extend(
|
|
41
|
+
SortParamsSchema.shape
|
|
42
|
+
);
|
|
41
43
|
|
|
42
44
|
export type FindCardsParams = z.infer<typeof FindCardsParamsSchema>;
|
|
@@ -16,7 +16,7 @@ const BASE_FEATURES: PlanFeature[] = [
|
|
|
16
16
|
{ icon: "check", text: "Compartilhar páginas", tooltip: "sharePages" },
|
|
17
17
|
{ icon: "check", text: "Hospedagem inclusa" },
|
|
18
18
|
{ icon: "check", text: "SSL (HTTPS) + CDN" },
|
|
19
|
-
{ icon: "check", text: "Templates
|
|
19
|
+
{ icon: "check", text: "Templates gratuitos" },
|
|
20
20
|
];
|
|
21
21
|
|
|
22
22
|
function buildMainFeaturesFromItems(items: Plan["items"]): PlanMainFeatures {
|
|
@@ -41,7 +41,7 @@ export const SubscriptionSchema = z.object({
|
|
|
41
41
|
id_gateway: z.union([z.number(), z.string()]).nullable(),
|
|
42
42
|
gateway_account: z.string().nullable(),
|
|
43
43
|
date_hiring: z.coerce.date().nullable(),
|
|
44
|
-
date_due: z.coerce.date(),
|
|
44
|
+
date_due: z.coerce.date().nullable(),
|
|
45
45
|
date_cancellation: z.coerce.date().nullable(),
|
|
46
46
|
date_verification: z.coerce.date().nullable(),
|
|
47
47
|
cancellation_reason: z.string().nullable(),
|
|
@@ -52,6 +52,7 @@ export const SubscriptionSchema = z.object({
|
|
|
52
52
|
card_name: z.string().nullable().optional(),
|
|
53
53
|
card_brand: z.string().nullable().optional(),
|
|
54
54
|
card_number: z.string().nullable().optional(),
|
|
55
|
+
card: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
55
56
|
items: z.array(SubscriptionItemSchema),
|
|
56
57
|
pending_change: z.object({
|
|
57
58
|
schedule_id: z.string(),
|