@greatapps/common 1.1.677 → 1.1.678

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.
@@ -5,7 +5,7 @@ export const PlanItemSchema = z.object({
5
5
  id_addon: z.number(),
6
6
  quantity: z.number(),
7
7
  value: z.number(),
8
- value_usd: z.coerce.number().nullish(),
8
+ value_usd: z.number().nullish(),
9
9
  });
10
10
 
11
11
  export type PlanItem = z.infer<typeof PlanItemSchema>;
@@ -14,10 +14,13 @@ export const PlanSchema = z.object({
14
14
  id: z.number(),
15
15
  id_plan: z.number().optional(),
16
16
  name: z.string(),
17
- value: z.number().default(0),
17
+ value: z.number().nullable().default(0),
18
18
  // Preço em USD (conta stripe_usd). Operador cadastra no backend; ausente em planos
19
- // sem suporte internacional. Espelha a coluna value_usd de gapps-r3-api.
20
- value_usd: z.coerce.number().nullish(),
19
+ // sem suporte internacional. Backend agora resolve por moeda da conta (customer),
20
+ // omitindo value_usd para customer requests e adicionando currency. Admin paths
21
+ // ainda recebem value_usd como número (sem .coerce — backend joga agora como Number).
22
+ value_usd: z.number().nullish(),
23
+ currency: z.enum(['brl', 'usd']).optional(),
21
24
  type: z.string().optional(),
22
25
  discount_semester: z.number().default(0),
23
26
  discount_annual: z.number().default(0),
@@ -60,6 +63,7 @@ export type UiPlan = {
60
63
  price: string;
61
64
  pricingByPeriod?: PlanPricingByPeriod;
62
65
  buttonVariant?: 'brand' | 'default';
66
+ priceUnavailable?: boolean;
63
67
  items: PlanItem[];
64
68
  };
65
69
 
@@ -82,9 +82,12 @@ function buildMainFeaturesFromItems(
82
82
  }
83
83
 
84
84
  function computePricingByPeriod(apiPlan: Plan, currency: CurrencyCode): PlanPricingByPeriod {
85
- // Conta USD usa value_usd; fallback pro value (BRL) evita NaN quando o operador ainda
86
- // não cadastrou o preço internacional. Os descontos por período são percentuais — aplicam igual.
87
- const monthly = currency === "usd" ? (apiPlan.value_usd ?? apiPlan.value) : apiPlan.value;
85
+ // Backend agora resolve value por moeda da conta; mapper apenas lê.
86
+ // value pode ser null (ex.: conta USD, preço USD não cadastrado).
87
+ const monthly = apiPlan.value;
88
+ if (monthly == null) {
89
+ return { monthly: 0, semiannual: 0, annual: 0 };
90
+ }
88
91
  const round2 = (n: number) => Math.round(n * 100) / 100;
89
92
  return {
90
93
  monthly,
@@ -123,9 +126,12 @@ function buildUiPlan(plan: Plan, currency: CurrencyCode, translate?: TranslateFn
123
126
 
124
127
  const currencyAwareItems = plan.items.map((item) => ({
125
128
  ...item,
126
- value: currency === "usd" ? (item.value_usd ?? item.value) : item.value,
129
+ value: item.value ?? 0,
127
130
  }));
128
131
 
132
+ const priceUnavailable = plan.value == null;
133
+ const unavailableLabel = translate ? translate("common.plans.usdNotConfigured") : "USD não configurado";
134
+
129
135
  return {
130
136
  planId: plan.id,
131
137
  name: plan.name,
@@ -133,9 +139,10 @@ function buildUiPlan(plan: Plan, currency: CurrencyCode, translate?: TranslateFn
133
139
  buttonVariant,
134
140
  mainFeatures: buildMainFeaturesFromItems(plan.items, translate),
135
141
  features,
136
- originalPrice: formatCurrencyNumber(monthlyFinal, 2, currency),
137
- price: formatCurrencyNumber(monthlyFinal, 2, currency),
142
+ originalPrice: priceUnavailable ? unavailableLabel : formatCurrencyNumber(monthlyFinal, 2, currency),
143
+ price: priceUnavailable ? unavailableLabel : formatCurrencyNumber(monthlyFinal, 2, currency),
138
144
  pricingByPeriod,
145
+ priceUnavailable,
139
146
  items: currencyAwareItems,
140
147
  };
141
148
  }