@greatapps/common 1.1.762 → 1.1.764
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/billing/RequiredBillingDataModal.mjs +139 -129
- package/dist/components/modals/billing/RequiredBillingDataModal.mjs.map +1 -1
- package/dist/components/ui/overlay/Dialog.mjs +21 -3
- package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
- package/dist/i18n/messages/en-us.mjs +1 -0
- package/dist/i18n/messages/en-us.mjs.map +1 -1
- package/dist/i18n/messages/es-es.mjs +1 -0
- package/dist/i18n/messages/es-es.mjs.map +1 -1
- package/dist/i18n/messages/pt-br.mjs +1 -0
- package/dist/i18n/messages/pt-br.mjs.map +1 -1
- package/dist/middlewares/chain.mjs +10 -1
- package/dist/middlewares/chain.mjs.map +1 -1
- package/dist/modules/subscriptions/types/subscription.type.mjs +9 -6
- package/dist/modules/subscriptions/types/subscription.type.mjs.map +1 -1
- package/dist/utils/geo-country.mjs +16 -0
- package/dist/utils/geo-country.mjs.map +1 -0
- package/package.json +1 -1
- package/src/components/modals/billing/RequiredBillingDataModal.tsx +163 -144
- package/src/components/ui/overlay/Dialog.tsx +29 -3
- package/src/i18n/messages/en-us.ts +2 -0
- package/src/i18n/messages/es-es.ts +2 -0
- package/src/i18n/messages/pt-br.ts +2 -0
- package/src/middlewares/chain.ts +14 -1
- package/src/modules/subscriptions/types/subscription.type.ts +9 -6
- package/src/utils/geo-country.ts +15 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Controller, useForm } from "react-hook-form";
|
|
5
5
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
@@ -17,6 +17,7 @@ import { useViaCep } from "../../../modules/accounts/hooks/useViaCep";
|
|
|
17
17
|
import { useUpdateBillingData } from "../../../modules/accounts/hooks/useAccountManagement";
|
|
18
18
|
import { useRequiredBillingData } from "../../../modules/accounts/hooks/use-required-billing-data.hook";
|
|
19
19
|
import { COUNTRIES } from "../../../utils/countries";
|
|
20
|
+
import { readGeoCountry } from "../../../utils/geo-country";
|
|
20
21
|
import { BR_STATE_OPTIONS } from "../../../utils/constants/br-states";
|
|
21
22
|
import { formatCNPJ, formatCPF, formatPostalCode } from "../../../utils/format/masks";
|
|
22
23
|
import { isValidCNPJ, isValidCPF } from "../../../utils/validators/common";
|
|
@@ -24,36 +25,38 @@ const COUNTRY_OPTIONS = COUNTRIES.map((country) => ({
|
|
|
24
25
|
value: country.iso,
|
|
25
26
|
label: country.name
|
|
26
27
|
}));
|
|
28
|
+
const BR_REQUIRED_ADDRESS_FIELDS = [
|
|
29
|
+
"street",
|
|
30
|
+
"streetNumber",
|
|
31
|
+
"neighborhood",
|
|
32
|
+
"city",
|
|
33
|
+
"state"
|
|
34
|
+
];
|
|
27
35
|
function buildBillingDataSchema(translate) {
|
|
28
|
-
const requiredText = z.string().trim().min(1, translate("common.billing.requiredData.requiredField"));
|
|
29
36
|
const base = z.object({
|
|
30
37
|
personType: z.enum(["pf", "pj"]),
|
|
31
38
|
document: z.string().trim(),
|
|
32
|
-
financialName:
|
|
39
|
+
financialName: z.string().trim().min(1, translate("common.billing.requiredData.requiredField")),
|
|
33
40
|
financialEmail: z.string().trim().min(1, translate("common.billing.requiredData.requiredField")).email(translate("common.billing.requiredData.invalidEmail")),
|
|
34
|
-
cep:
|
|
35
|
-
street:
|
|
41
|
+
cep: z.string().trim(),
|
|
42
|
+
street: z.string().trim(),
|
|
36
43
|
streetNumber: z.string().trim(),
|
|
37
44
|
complement: z.string().trim().optional(),
|
|
38
45
|
neighborhood: z.string().trim(),
|
|
39
|
-
city:
|
|
40
|
-
state:
|
|
41
|
-
country:
|
|
46
|
+
city: z.string().trim(),
|
|
47
|
+
state: z.string().trim(),
|
|
48
|
+
country: z.string().trim().min(1, translate("common.billing.requiredData.requiredField"))
|
|
42
49
|
});
|
|
43
50
|
return base.superRefine((data, ctx) => {
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
code: "custom",
|
|
54
|
-
path: ["neighborhood"],
|
|
55
|
-
message: translate("common.billing.requiredData.requiredField")
|
|
56
|
-
});
|
|
51
|
+
if (data.country !== "BR") return;
|
|
52
|
+
for (const field of BR_REQUIRED_ADDRESS_FIELDS) {
|
|
53
|
+
if (!data[field]) {
|
|
54
|
+
ctx.addIssue({
|
|
55
|
+
code: "custom",
|
|
56
|
+
path: [field],
|
|
57
|
+
message: translate("common.billing.requiredData.requiredField")
|
|
58
|
+
});
|
|
59
|
+
}
|
|
57
60
|
}
|
|
58
61
|
if (data.cep.replace(/\D/g, "").length !== 8) {
|
|
59
62
|
ctx.addIssue({
|
|
@@ -127,6 +130,7 @@ function RequiredBillingDataModalContent() {
|
|
|
127
130
|
} = form;
|
|
128
131
|
const personType = watch("personType");
|
|
129
132
|
const isCompany = personType === "pj";
|
|
133
|
+
const isBrazil = watch("country") === "BR";
|
|
130
134
|
useEffect(() => {
|
|
131
135
|
if (!account || isPrefilled.current) return;
|
|
132
136
|
isPrefilled.current = true;
|
|
@@ -143,7 +147,7 @@ function RequiredBillingDataModalContent() {
|
|
|
143
147
|
neighborhood: account.neighborhood ?? "",
|
|
144
148
|
city: account.city ?? "",
|
|
145
149
|
state: account.state ?? "",
|
|
146
|
-
country: account.country || "BR"
|
|
150
|
+
country: account.country || readGeoCountry() || "BR"
|
|
147
151
|
});
|
|
148
152
|
}, [account, reset, user?.email]);
|
|
149
153
|
const handleDocumentChange = (rawValue) => {
|
|
@@ -169,7 +173,7 @@ function RequiredBillingDataModalContent() {
|
|
|
169
173
|
});
|
|
170
174
|
};
|
|
171
175
|
async function onSubmit(data) {
|
|
172
|
-
const payload = {
|
|
176
|
+
const payload = data.country === "BR" ? {
|
|
173
177
|
financial_document_type: data.personType === "pf" ? 1 : 2,
|
|
174
178
|
financial_document: data.document,
|
|
175
179
|
financial_name: data.financialName,
|
|
@@ -182,6 +186,10 @@ function RequiredBillingDataModalContent() {
|
|
|
182
186
|
city: data.city,
|
|
183
187
|
state: data.state,
|
|
184
188
|
country: data.country
|
|
189
|
+
} : {
|
|
190
|
+
financial_name: data.financialName,
|
|
191
|
+
financial_email: data.financialEmail,
|
|
192
|
+
country: data.country
|
|
185
193
|
};
|
|
186
194
|
try {
|
|
187
195
|
await updateBillingData(payload);
|
|
@@ -219,7 +227,7 @@ function RequiredBillingDataModalContent() {
|
|
|
219
227
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-10 h-10 bg-zinc-50 rounded-lg", children: /* @__PURE__ */ jsx(IconFileInvoice, { size: 24, className: "text-zinc-950" }) }),
|
|
220
228
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
221
229
|
/* @__PURE__ */ jsx(DialogTitle, { className: "paragraph-medium-semibold text-zinc-950", children: translate("common.billing.requiredData.title") }),
|
|
222
|
-
/* @__PURE__ */ jsx("span", { className: "paragraph-small-regular text-zinc-600", children: translate("common.billing.requiredData.description") })
|
|
230
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-small-regular text-zinc-600", children: isBrazil ? translate("common.billing.requiredData.description") : translate("common.billing.requiredData.descriptionInternational") })
|
|
223
231
|
] })
|
|
224
232
|
] }),
|
|
225
233
|
/* @__PURE__ */ jsxs(
|
|
@@ -231,7 +239,26 @@ function RequiredBillingDataModalContent() {
|
|
|
231
239
|
children: [
|
|
232
240
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 p-4 lg:p-5 flex-1 overflow-y-auto", children: [
|
|
233
241
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
234
|
-
/* @__PURE__ */
|
|
242
|
+
/* @__PURE__ */ jsx(
|
|
243
|
+
Controller,
|
|
244
|
+
{
|
|
245
|
+
name: "country",
|
|
246
|
+
control,
|
|
247
|
+
render: ({ field }) => /* @__PURE__ */ jsx(
|
|
248
|
+
SelectField,
|
|
249
|
+
{
|
|
250
|
+
label: translate("common.billing.requiredData.country"),
|
|
251
|
+
placeholder: translate("common.billing.requiredData.select"),
|
|
252
|
+
value: field.value || void 0,
|
|
253
|
+
onChange: (value) => setValue("country", String(value), { shouldValidate: true }),
|
|
254
|
+
options: COUNTRY_OPTIONS,
|
|
255
|
+
error: !!errors.country,
|
|
256
|
+
errorMessage: errors.country?.message
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
),
|
|
261
|
+
isBrazil && /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
235
262
|
/* @__PURE__ */ jsx(
|
|
236
263
|
Controller,
|
|
237
264
|
{
|
|
@@ -275,7 +302,7 @@ function RequiredBillingDataModalContent() {
|
|
|
275
302
|
/* @__PURE__ */ jsx(
|
|
276
303
|
FormField,
|
|
277
304
|
{
|
|
278
|
-
label: isCompany ? translate("common.billing.requiredData.companyName") : translate("common.billing.requiredData.fullName"),
|
|
305
|
+
label: isBrazil && isCompany ? translate("common.billing.requiredData.companyName") : translate("common.billing.requiredData.fullName"),
|
|
279
306
|
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
280
307
|
error: !!errors.financialName,
|
|
281
308
|
errorMessage: errors.financialName?.message,
|
|
@@ -294,114 +321,97 @@ function RequiredBillingDataModalContent() {
|
|
|
294
321
|
}
|
|
295
322
|
)
|
|
296
323
|
] }),
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
|
|
299
|
-
/* @__PURE__ */
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
{
|
|
303
|
-
label: translate("common.billing.requiredData.cep"),
|
|
304
|
-
placeholder: "_____-___",
|
|
305
|
-
error: !!errors.cep,
|
|
306
|
-
errorMessage: errors.cep?.message,
|
|
307
|
-
...register("cep", {
|
|
308
|
-
onChange: (event) => handleCepChange(event.target.value)
|
|
309
|
-
})
|
|
310
|
-
}
|
|
311
|
-
),
|
|
312
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
313
|
-
/* @__PURE__ */ jsx("div", { className: "flex-[3]", children: /* @__PURE__ */ jsx(
|
|
314
|
-
FormField,
|
|
315
|
-
{
|
|
316
|
-
label: translate("common.billing.requiredData.street"),
|
|
317
|
-
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
318
|
-
error: !!errors.street,
|
|
319
|
-
errorMessage: errors.street?.message,
|
|
320
|
-
...register("street")
|
|
321
|
-
}
|
|
322
|
-
) }),
|
|
323
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
324
|
-
FormField,
|
|
325
|
-
{
|
|
326
|
-
label: translate("common.billing.requiredData.streetNumber"),
|
|
327
|
-
placeholder: "000",
|
|
328
|
-
error: !!errors.streetNumber,
|
|
329
|
-
errorMessage: errors.streetNumber?.message,
|
|
330
|
-
...register("streetNumber")
|
|
331
|
-
}
|
|
332
|
-
) })
|
|
333
|
-
] }),
|
|
334
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
335
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
336
|
-
FormField,
|
|
337
|
-
{
|
|
338
|
-
label: translate("common.billing.requiredData.neighborhood"),
|
|
339
|
-
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
340
|
-
error: !!errors.neighborhood,
|
|
341
|
-
errorMessage: errors.neighborhood?.message,
|
|
342
|
-
...register("neighborhood")
|
|
343
|
-
}
|
|
344
|
-
) }),
|
|
345
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
346
|
-
FormField,
|
|
347
|
-
{
|
|
348
|
-
label: translate("common.billing.requiredData.complement"),
|
|
349
|
-
optional: true,
|
|
350
|
-
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
351
|
-
...register("complement")
|
|
352
|
-
}
|
|
353
|
-
) })
|
|
354
|
-
] }),
|
|
355
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
356
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
324
|
+
isBrazil && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
325
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-zinc-200" }),
|
|
326
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
327
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-zinc-950", children: translate("common.billing.requiredData.addressHeading") }),
|
|
328
|
+
/* @__PURE__ */ jsx(
|
|
357
329
|
FormField,
|
|
358
330
|
{
|
|
359
|
-
label: translate("common.billing.requiredData.
|
|
360
|
-
placeholder:
|
|
361
|
-
error: !!errors.
|
|
362
|
-
errorMessage: errors.
|
|
363
|
-
...register("
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
367
|
-
Controller,
|
|
368
|
-
{
|
|
369
|
-
name: "state",
|
|
370
|
-
control,
|
|
371
|
-
render: ({ field }) => /* @__PURE__ */ jsx(
|
|
372
|
-
SelectField,
|
|
373
|
-
{
|
|
374
|
-
label: translate("common.billing.requiredData.state"),
|
|
375
|
-
placeholder: translate("common.billing.requiredData.select"),
|
|
376
|
-
value: field.value || void 0,
|
|
377
|
-
onChange: (value) => setValue("state", value, { shouldValidate: true }),
|
|
378
|
-
options: BR_STATE_OPTIONS,
|
|
379
|
-
error: !!errors.state,
|
|
380
|
-
errorMessage: errors.state?.message
|
|
381
|
-
}
|
|
382
|
-
)
|
|
331
|
+
label: translate("common.billing.requiredData.cep"),
|
|
332
|
+
placeholder: "_____-___",
|
|
333
|
+
error: !!errors.cep,
|
|
334
|
+
errorMessage: errors.cep?.message,
|
|
335
|
+
...register("cep", {
|
|
336
|
+
onChange: (event) => handleCepChange(event.target.value)
|
|
337
|
+
})
|
|
383
338
|
}
|
|
384
|
-
)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
{
|
|
389
|
-
name: "country",
|
|
390
|
-
control,
|
|
391
|
-
render: ({ field }) => /* @__PURE__ */ jsx(
|
|
392
|
-
SelectField,
|
|
339
|
+
),
|
|
340
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
341
|
+
/* @__PURE__ */ jsx("div", { className: "flex-[3]", children: /* @__PURE__ */ jsx(
|
|
342
|
+
FormField,
|
|
393
343
|
{
|
|
394
|
-
label: translate("common.billing.requiredData.
|
|
395
|
-
placeholder: translate("common.billing.requiredData.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
error: !!errors.country,
|
|
400
|
-
errorMessage: errors.country?.message
|
|
344
|
+
label: translate("common.billing.requiredData.street"),
|
|
345
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
346
|
+
error: !!errors.street,
|
|
347
|
+
errorMessage: errors.street?.message,
|
|
348
|
+
...register("street")
|
|
401
349
|
}
|
|
402
|
-
)
|
|
403
|
-
|
|
404
|
-
|
|
350
|
+
) }),
|
|
351
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
352
|
+
FormField,
|
|
353
|
+
{
|
|
354
|
+
label: translate("common.billing.requiredData.streetNumber"),
|
|
355
|
+
placeholder: "000",
|
|
356
|
+
error: !!errors.streetNumber,
|
|
357
|
+
errorMessage: errors.streetNumber?.message,
|
|
358
|
+
...register("streetNumber")
|
|
359
|
+
}
|
|
360
|
+
) })
|
|
361
|
+
] }),
|
|
362
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
363
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
364
|
+
FormField,
|
|
365
|
+
{
|
|
366
|
+
label: translate("common.billing.requiredData.neighborhood"),
|
|
367
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
368
|
+
error: !!errors.neighborhood,
|
|
369
|
+
errorMessage: errors.neighborhood?.message,
|
|
370
|
+
...register("neighborhood")
|
|
371
|
+
}
|
|
372
|
+
) }),
|
|
373
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
374
|
+
FormField,
|
|
375
|
+
{
|
|
376
|
+
label: translate("common.billing.requiredData.complement"),
|
|
377
|
+
optional: true,
|
|
378
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
379
|
+
...register("complement")
|
|
380
|
+
}
|
|
381
|
+
) })
|
|
382
|
+
] }),
|
|
383
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
384
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
385
|
+
FormField,
|
|
386
|
+
{
|
|
387
|
+
label: translate("common.billing.requiredData.city"),
|
|
388
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
389
|
+
error: !!errors.city,
|
|
390
|
+
errorMessage: errors.city?.message,
|
|
391
|
+
...register("city")
|
|
392
|
+
}
|
|
393
|
+
) }),
|
|
394
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
395
|
+
Controller,
|
|
396
|
+
{
|
|
397
|
+
name: "state",
|
|
398
|
+
control,
|
|
399
|
+
render: ({ field }) => /* @__PURE__ */ jsx(
|
|
400
|
+
SelectField,
|
|
401
|
+
{
|
|
402
|
+
label: translate("common.billing.requiredData.state"),
|
|
403
|
+
placeholder: translate("common.billing.requiredData.select"),
|
|
404
|
+
value: field.value || void 0,
|
|
405
|
+
onChange: (value) => setValue("state", String(value), { shouldValidate: true }),
|
|
406
|
+
options: BR_STATE_OPTIONS,
|
|
407
|
+
error: !!errors.state,
|
|
408
|
+
errorMessage: errors.state?.message
|
|
409
|
+
}
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
) })
|
|
413
|
+
] })
|
|
414
|
+
] })
|
|
405
415
|
] })
|
|
406
416
|
] }),
|
|
407
417
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end p-4 lg:p-5 border-t border-zinc-200 shrink-0", children: /* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/modals/billing/RequiredBillingDataModal.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- o generic Translator do next-intl não é\n expressável estruturalmente; o `any` do TranslateFn é intencional e está contido neste arquivo\n (mesmo padrão de modules/plans/utils/map-api-plan-to-ui.ts). */\n'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { Controller, useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useTranslations } from 'next-intl';\nimport { toast } from 'sonner';\nimport z from 'zod';\nimport { IconFileInvoice } from '@tabler/icons-react';\n\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';\nimport { Button } from '../../ui/buttons/Button';\nimport { FormField } from '../../ui/form/FormField';\nimport { SelectField } from '../../ui/form/SelectField';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { useAuth } from '../../../providers/auth.provider';\nimport { useViaCep } from '../../../modules/accounts/hooks/useViaCep';\nimport { useUpdateBillingData } from '../../../modules/accounts/hooks/useAccountManagement';\nimport { useRequiredBillingData } from '../../../modules/accounts/hooks/use-required-billing-data.hook';\nimport { COUNTRIES } from '../../../utils/countries';\nimport { BR_STATE_OPTIONS } from '../../../utils/constants/br-states';\nimport { formatCNPJ, formatCPF, formatPostalCode } from '../../../utils/format/masks';\nimport { isValidCNPJ, isValidCPF } from '../../../utils/validators/common';\nimport type { UpdateBillingDataRequest } from '../../../modules/accounts/types';\n\ntype TranslateFn = (key: any, values?: Record<string, string | number>) => string;\n\ntype BillingDataFormValues = {\n personType: 'pf' | 'pj';\n document: string;\n financialName: string;\n financialEmail: string;\n cep: string;\n street: string;\n streetNumber: string;\n complement?: string;\n neighborhood: string;\n city: string;\n state: string;\n country: string;\n};\n\nconst COUNTRY_OPTIONS = COUNTRIES.map((country: { iso: string; name: string }) => ({\n value: country.iso,\n label: country.name,\n}));\n\nfunction buildBillingDataSchema(translate: TranslateFn) {\n const requiredText = z\n .string()\n .trim()\n .min(1, translate('common.billing.requiredData.requiredField'));\n\n const base = z.object({\n personType: z.enum(['pf', 'pj']),\n document: z.string().trim(),\n financialName: requiredText,\n financialEmail: z\n .string()\n .trim()\n .min(1, translate('common.billing.requiredData.requiredField'))\n .email(translate('common.billing.requiredData.invalidEmail')),\n cep: requiredText,\n street: requiredText,\n streetNumber: z.string().trim(),\n complement: z.string().trim().optional(),\n neighborhood: z.string().trim(),\n city: requiredText,\n state: requiredText,\n country: requiredText,\n });\n\n return base.superRefine((data, ctx) => {\n if (!data.streetNumber) {\n ctx.addIssue({\n code: 'custom',\n path: ['streetNumber'],\n message: translate('common.billing.requiredData.requiredField'),\n });\n }\n\n if (!data.neighborhood) {\n ctx.addIssue({\n code: 'custom',\n path: ['neighborhood'],\n message: translate('common.billing.requiredData.requiredField'),\n });\n }\n\n if (data.cep.replace(/\\D/g, '').length !== 8) {\n ctx.addIssue({\n code: 'custom',\n path: ['cep'],\n message: translate('common.billing.requiredData.invalidCep'),\n });\n }\n\n const isCompany = data.personType === 'pj';\n const digits = data.document.replace(/\\D/g, '');\n\n if (digits.length !== (isCompany ? 14 : 11)) {\n ctx.addIssue({\n code: 'custom',\n path: ['document'],\n message: isCompany\n ? translate('common.billing.requiredData.invalidCnpj')\n : translate('common.billing.requiredData.invalidCpf'),\n });\n return;\n }\n\n /* Dígito verificador, mesmo algoritmo do backend: sem isso 111.111.111-11 passa\n * aqui e o PUT da conta é recusado depois, sem o usuário saber o motivo. */\n const isValid = isCompany ? isValidCNPJ(digits) : isValidCPF(digits);\n if (!isValid) {\n ctx.addIssue({\n code: 'custom',\n path: ['document'],\n message: isCompany\n ? translate('common.billing.requiredData.invalidCnpjChecksum')\n : translate('common.billing.requiredData.invalidCpfChecksum'),\n });\n }\n });\n}\n\nfunction formatDocument(document: string | null | undefined, isCompany: boolean) {\n if (!document) return '';\n return isCompany ? formatCNPJ(document) : formatCPF(document);\n}\n\nfunction RequiredBillingDataModalContent() {\n const translate = useTranslations();\n const { user } = useAuth();\n const { isRequired, account } = useRequiredBillingData();\n const { mutateAsync: updateBillingData } = useUpdateBillingData();\n const { mutateAsync: lookupCep } = useViaCep();\n\n /* O modal fecha na hora do submit e não reabre enquanto o invalidate do account\n * não volta — sem isso o usuário vê o modal piscar de novo com o cache antigo. */\n const [isSubmitted, setIsSubmitted] = useState(false);\n const isPrefilled = useRef(false);\n\n const schema = useMemo(\n () => buildBillingDataSchema(translate),\n [translate],\n );\n\n const form = useForm<BillingDataFormValues>({\n resolver: zodResolver(schema),\n mode: 'onChange',\n defaultValues: {\n personType: 'pf',\n document: '',\n financialName: '',\n financialEmail: '',\n cep: '',\n street: '',\n streetNumber: '',\n complement: '',\n neighborhood: '',\n city: '',\n state: '',\n country: 'BR',\n },\n });\n\n const {\n register,\n control,\n handleSubmit,\n reset,\n setValue,\n watch,\n formState: { errors, isSubmitting, isValid },\n } = form;\n\n const personType = watch('personType');\n const isCompany = personType === 'pj';\n\n useEffect(() => {\n if (!account || isPrefilled.current) return;\n isPrefilled.current = true;\n\n const accountIsCompany = account.financial_document_type === 2;\n reset({\n personType: accountIsCompany ? 'pj' : 'pf',\n document: formatDocument(account.financial_document, accountIsCompany),\n financialName: account.financial_name ?? '',\n financialEmail: account.financial_email || user?.email || '',\n cep: account.zipcode ?? '',\n street: account.address ?? '',\n streetNumber: account.address_number ?? '',\n complement: account.address_complement ?? '',\n neighborhood: account.neighborhood ?? '',\n city: account.city ?? '',\n state: account.state ?? '',\n country: account.country || 'BR',\n });\n }, [account, reset, user?.email]);\n\n const handleDocumentChange = (rawValue: string) => {\n setValue('document', isCompany ? formatCNPJ(rawValue) : formatCPF(rawValue), {\n shouldValidate: true,\n });\n };\n\n const handlePersonTypeChange = (value: 'pf' | 'pj') => {\n if (value === personType) return;\n setValue('document', '');\n /* shouldValidate reroda o resolver: sem isso o `isValid` fica preso no valor\n * do documento antigo e o botão continua habilitado com o campo já limpo. */\n setValue('personType', value, { shouldValidate: true });\n };\n\n const handleCepChange = (rawValue: string) => {\n setValue('cep', formatPostalCode(rawValue), { shouldValidate: true });\n\n const digits = rawValue.replace(/\\D/g, '');\n if (digits.length !== 8) return;\n\n lookupCep(digits)\n .then((data) => {\n setValue('street', data.logradouro, { shouldValidate: true });\n setValue('neighborhood', data.bairro, { shouldValidate: true });\n setValue('city', data.localidade, { shouldValidate: true });\n setValue('state', data.uf, { shouldValidate: true });\n })\n .catch(() => {\n // CEP não encontrado: o usuário preenche o endereço na mão.\n });\n };\n\n async function onSubmit(data: BillingDataFormValues) {\n const payload: UpdateBillingDataRequest = {\n financial_document_type: data.personType === 'pf' ? 1 : 2,\n financial_document: data.document,\n financial_name: data.financialName,\n financial_email: data.financialEmail,\n zipcode: data.cep,\n address: data.street,\n address_number: data.streetNumber,\n address_complement: data.complement ?? '',\n neighborhood: data.neighborhood,\n city: data.city,\n state: data.state,\n country: data.country,\n };\n\n try {\n await updateBillingData(payload);\n setIsSubmitted(true);\n toast.custom(\n (t) => (\n <Toast\n variant=\"success\"\n message={translate('common.billing.requiredData.successToast')}\n toastId={t}\n />\n ),\n { duration: 5000 },\n );\n } catch (error) {\n /* O backend devolve a razão exata da recusa (ex.: documento fiscal inválido).\n * Trocar por um texto genérico deixaria o usuário travado sem saber o que corrigir. */\n const message =\n error instanceof Error && error.message\n ? error.message\n : translate('common.billing.requiredData.errorToast');\n toast.custom((t) => <Toast variant=\"error\" message={message} toastId={t} />, {\n duration: 5000,\n });\n }\n }\n\n if (!isRequired || isSubmitted) return null;\n\n return (\n <Dialog open onOpenChange={() => {}}>\n <DialogContent\n showCloseButton={false}\n onEscapeKeyDown={(event: Event) => event.preventDefault()}\n onPointerDownOutside={(event: Event) => event.preventDefault()}\n onInteractOutside={(event: Event) => event.preventDefault()}\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-[502px] 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-hidden\"\n >\n <DialogHeader className=\"gap-3 text-left p-4 lg:p-5 border-b border-zinc-200 shrink-0\">\n <div className=\"flex items-center justify-center w-10 h-10 bg-zinc-50 rounded-lg\">\n <IconFileInvoice size={24} className=\"text-zinc-950\" />\n </div>\n <div className=\"flex flex-col gap-2\">\n <DialogTitle className=\"paragraph-medium-semibold text-zinc-950\">\n {translate('common.billing.requiredData.title')}\n </DialogTitle>\n <span className=\"paragraph-small-regular text-zinc-600\">\n {translate('common.billing.requiredData.description')}\n </span>\n </div>\n </DialogHeader>\n\n <form\n onSubmit={handleSubmit(onSubmit)}\n className=\"flex flex-col flex-1 min-h-0\"\n noValidate\n >\n <div className=\"flex flex-col gap-6 p-4 lg:p-5 flex-1 overflow-y-auto\">\n <div className=\"flex flex-col gap-5\">\n <div className=\"flex gap-4\">\n <Controller\n name=\"personType\"\n control={control}\n render={({ field }) => (\n <SelectField\n label={translate('common.billing.requiredData.personType')}\n placeholder={translate('common.billing.requiredData.select')}\n value={field.value}\n onChange={(value) => handlePersonTypeChange(value as 'pf' | 'pj')}\n options={[\n {\n value: 'pf',\n label: translate('common.billing.requiredData.personTypePf'),\n },\n {\n value: 'pj',\n label: translate('common.billing.requiredData.personTypePj'),\n },\n ]}\n containerClassName=\"flex-1\"\n />\n )}\n />\n <div className=\"flex-1\">\n <FormField\n label={\n isCompany\n ? translate('common.billing.requiredData.cnpj')\n : translate('common.billing.requiredData.cpf')\n }\n placeholder={isCompany ? '__.___.___/____-__' : '___.___.___-__'}\n error={!!errors.document}\n errorMessage={errors.document?.message}\n {...register('document', {\n onChange: (event) => handleDocumentChange(event.target.value),\n })}\n />\n </div>\n </div>\n\n <FormField\n label={\n isCompany\n ? translate('common.billing.requiredData.companyName')\n : translate('common.billing.requiredData.fullName')\n }\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.financialName}\n errorMessage={errors.financialName?.message}\n {...register('financialName')}\n />\n\n <FormField\n label={translate('common.billing.requiredData.financialEmail')}\n placeholder={translate('common.billing.requiredData.financialEmailPlaceholder')}\n type=\"email\"\n error={!!errors.financialEmail}\n errorMessage={errors.financialEmail?.message}\n {...register('financialEmail')}\n />\n </div>\n\n <div className=\"h-px bg-zinc-200\" />\n\n <div className=\"flex flex-col gap-5\">\n <span className=\"paragraph-small-semibold text-zinc-950\">\n {translate('common.billing.requiredData.addressHeading')}\n </span>\n\n <FormField\n label={translate('common.billing.requiredData.cep')}\n placeholder=\"_____-___\"\n error={!!errors.cep}\n errorMessage={errors.cep?.message}\n {...register('cep', {\n onChange: (event) => handleCepChange(event.target.value),\n })}\n />\n\n <div className=\"flex gap-4\">\n <div className=\"flex-[3]\">\n <FormField\n label={translate('common.billing.requiredData.street')}\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.street}\n errorMessage={errors.street?.message}\n {...register('street')}\n />\n </div>\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.streetNumber')}\n placeholder=\"000\"\n error={!!errors.streetNumber}\n errorMessage={errors.streetNumber?.message}\n {...register('streetNumber')}\n />\n </div>\n </div>\n\n <div className=\"flex gap-4\">\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.neighborhood')}\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.neighborhood}\n errorMessage={errors.neighborhood?.message}\n {...register('neighborhood')}\n />\n </div>\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.complement')}\n optional\n placeholder={translate('common.billing.requiredData.typeHere')}\n {...register('complement')}\n />\n </div>\n </div>\n\n <div className=\"flex gap-4\">\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.city')}\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.city}\n errorMessage={errors.city?.message}\n {...register('city')}\n />\n </div>\n <div className=\"flex-1\">\n <Controller\n name=\"state\"\n control={control}\n render={({ field }) => (\n <SelectField\n label={translate('common.billing.requiredData.state')}\n placeholder={translate('common.billing.requiredData.select')}\n value={field.value || undefined}\n onChange={(value) =>\n setValue('state', value as string, { shouldValidate: true })\n }\n options={BR_STATE_OPTIONS}\n error={!!errors.state}\n errorMessage={errors.state?.message}\n />\n )}\n />\n </div>\n </div>\n\n <Controller\n name=\"country\"\n control={control}\n render={({ field }) => (\n <SelectField\n label={translate('common.billing.requiredData.country')}\n placeholder={translate('common.billing.requiredData.select')}\n value={field.value || undefined}\n onChange={(value) =>\n setValue('country', value as string, { shouldValidate: true })\n }\n options={COUNTRY_OPTIONS}\n error={!!errors.country}\n errorMessage={errors.country?.message}\n />\n )}\n />\n </div>\n </div>\n\n <div className=\"flex items-center justify-end p-4 lg:p-5 border-t border-zinc-200 shrink-0\">\n <Button\n type=\"submit\"\n className=\"h-10! w-full lg:w-fit\"\n disabled={!isValid || isSubmitting}\n loading={isSubmitting}\n >\n {isSubmitting\n ? translate('common.billing.requiredData.submitting')\n : translate('common.billing.requiredData.submit')}\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\n/**\n * Modal bloqueante que exige o cadastro de cobrança/fiscal de contas que já\n * pagaram sem ele — sem esses dados a nota fiscal não é emitida. Monte uma vez\n * no layout raiz do app; ele mesmo decide se aparece (ver `useRequiredBillingData`).\n */\nexport default function RequiredBillingDataModal() {\n const { user, isLoading } = useAuth();\n\n /* Sem sessão não há conta nem assinatura pra consultar — evita disparar as\n * queries (e tomar 401) em /login, /register e demais rotas públicas. */\n if (isLoading || !user) return null;\n\n return <RequiredBillingDataModalContent />;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/modals/billing/RequiredBillingDataModal.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- o generic Translator do next-intl não é\n expressável estruturalmente; o `any` do TranslateFn é intencional e está contido neste arquivo\n (mesmo padrão de modules/plans/utils/map-api-plan-to-ui.ts). */\n'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { Controller, useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useTranslations } from 'next-intl';\nimport { toast } from 'sonner';\nimport z from 'zod';\nimport { IconFileInvoice } from '@tabler/icons-react';\n\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../ui/overlay/Dialog';\nimport { Button } from '../../ui/buttons/Button';\nimport { FormField } from '../../ui/form/FormField';\nimport { SelectField } from '../../ui/form/SelectField';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { useAuth } from '../../../providers/auth.provider';\nimport { useViaCep } from '../../../modules/accounts/hooks/useViaCep';\nimport { useUpdateBillingData } from '../../../modules/accounts/hooks/useAccountManagement';\nimport { useRequiredBillingData } from '../../../modules/accounts/hooks/use-required-billing-data.hook';\nimport { COUNTRIES } from '../../../utils/countries';\nimport { readGeoCountry } from '../../../utils/geo-country';\nimport { BR_STATE_OPTIONS } from '../../../utils/constants/br-states';\nimport { formatCNPJ, formatCPF, formatPostalCode } from '../../../utils/format/masks';\nimport { isValidCNPJ, isValidCPF } from '../../../utils/validators/common';\nimport type { UpdateBillingDataRequest } from '../../../modules/accounts/types';\n\ntype TranslateFn = (key: any, values?: Record<string, string | number>) => string;\n\ntype BillingDataFormValues = {\n personType: 'pf' | 'pj';\n document: string;\n financialName: string;\n financialEmail: string;\n cep: string;\n street: string;\n streetNumber: string;\n complement?: string;\n neighborhood: string;\n city: string;\n state: string;\n country: string;\n};\n\nconst COUNTRY_OPTIONS = COUNTRIES.map((country: { iso: string; name: string }) => ({\n value: country.iso,\n label: country.name,\n}));\n\nconst BR_REQUIRED_ADDRESS_FIELDS: readonly (keyof BillingDataFormValues)[] = [\n 'street',\n 'streetNumber',\n 'neighborhood',\n 'city',\n 'state',\n];\n\nfunction buildBillingDataSchema(translate: TranslateFn) {\n const base = z.object({\n personType: z.enum(['pf', 'pj']),\n document: z.string().trim(),\n financialName: z\n .string()\n .trim()\n .min(1, translate('common.billing.requiredData.requiredField')),\n financialEmail: z\n .string()\n .trim()\n .min(1, translate('common.billing.requiredData.requiredField'))\n .email(translate('common.billing.requiredData.invalidEmail')),\n cep: z.string().trim(),\n street: z.string().trim(),\n streetNumber: z.string().trim(),\n complement: z.string().trim().optional(),\n neighborhood: z.string().trim(),\n city: z.string().trim(),\n state: z.string().trim(),\n country: z.string().trim().min(1, translate('common.billing.requiredData.requiredField')),\n });\n\n return base.superRefine((data, ctx) => {\n if (data.country !== 'BR') return;\n\n for (const field of BR_REQUIRED_ADDRESS_FIELDS) {\n if (!data[field]) {\n ctx.addIssue({\n code: 'custom',\n path: [field],\n message: translate('common.billing.requiredData.requiredField'),\n });\n }\n }\n\n if (data.cep.replace(/\\D/g, '').length !== 8) {\n ctx.addIssue({\n code: 'custom',\n path: ['cep'],\n message: translate('common.billing.requiredData.invalidCep'),\n });\n }\n\n const isCompany = data.personType === 'pj';\n const digits = data.document.replace(/\\D/g, '');\n\n if (digits.length !== (isCompany ? 14 : 11)) {\n ctx.addIssue({\n code: 'custom',\n path: ['document'],\n message: isCompany\n ? translate('common.billing.requiredData.invalidCnpj')\n : translate('common.billing.requiredData.invalidCpf'),\n });\n return;\n }\n\n /* Dígito verificador, mesmo algoritmo do backend: sem isso 111.111.111-11 passa\n * aqui e o PUT da conta é recusado depois, sem o usuário saber o motivo. */\n const isValid = isCompany ? isValidCNPJ(digits) : isValidCPF(digits);\n if (!isValid) {\n ctx.addIssue({\n code: 'custom',\n path: ['document'],\n message: isCompany\n ? translate('common.billing.requiredData.invalidCnpjChecksum')\n : translate('common.billing.requiredData.invalidCpfChecksum'),\n });\n }\n });\n}\n\nfunction formatDocument(document: string | null | undefined, isCompany: boolean) {\n if (!document) return '';\n return isCompany ? formatCNPJ(document) : formatCPF(document);\n}\n\nfunction RequiredBillingDataModalContent() {\n const translate = useTranslations();\n const { user } = useAuth();\n const { isRequired, account } = useRequiredBillingData();\n const { mutateAsync: updateBillingData } = useUpdateBillingData();\n const { mutateAsync: lookupCep } = useViaCep();\n\n /* O modal fecha na hora do submit e não reabre enquanto o invalidate do account\n * não volta — sem isso o usuário vê o modal piscar de novo com o cache antigo. */\n const [isSubmitted, setIsSubmitted] = useState(false);\n const isPrefilled = useRef(false);\n\n const schema = useMemo(\n () => buildBillingDataSchema(translate),\n [translate],\n );\n\n const form = useForm<BillingDataFormValues>({\n resolver: zodResolver(schema),\n mode: 'onChange',\n defaultValues: {\n personType: 'pf',\n document: '',\n financialName: '',\n financialEmail: '',\n cep: '',\n street: '',\n streetNumber: '',\n complement: '',\n neighborhood: '',\n city: '',\n state: '',\n country: 'BR',\n },\n });\n\n const {\n register,\n control,\n handleSubmit,\n reset,\n setValue,\n watch,\n formState: { errors, isSubmitting, isValid },\n } = form;\n\n const personType = watch('personType');\n const isCompany = personType === 'pj';\n const isBrazil = watch('country') === 'BR';\n\n useEffect(() => {\n if (!account || isPrefilled.current) return;\n isPrefilled.current = true;\n\n const accountIsCompany = account.financial_document_type === 2;\n reset({\n personType: accountIsCompany ? 'pj' : 'pf',\n document: formatDocument(account.financial_document, accountIsCompany),\n financialName: account.financial_name ?? '',\n financialEmail: account.financial_email || user?.email || '',\n cep: account.zipcode ?? '',\n street: account.address ?? '',\n streetNumber: account.address_number ?? '',\n complement: account.address_complement ?? '',\n neighborhood: account.neighborhood ?? '',\n city: account.city ?? '',\n state: account.state ?? '',\n country: account.country || readGeoCountry() || 'BR',\n });\n }, [account, reset, user?.email]);\n\n const handleDocumentChange = (rawValue: string) => {\n setValue('document', isCompany ? formatCNPJ(rawValue) : formatCPF(rawValue), {\n shouldValidate: true,\n });\n };\n\n const handlePersonTypeChange = (value: 'pf' | 'pj') => {\n if (value === personType) return;\n setValue('document', '');\n /* shouldValidate reroda o resolver: sem isso o `isValid` fica preso no valor\n * do documento antigo e o botão continua habilitado com o campo já limpo. */\n setValue('personType', value, { shouldValidate: true });\n };\n\n const handleCepChange = (rawValue: string) => {\n setValue('cep', formatPostalCode(rawValue), { shouldValidate: true });\n\n const digits = rawValue.replace(/\\D/g, '');\n if (digits.length !== 8) return;\n\n lookupCep(digits)\n .then((data) => {\n setValue('street', data.logradouro, { shouldValidate: true });\n setValue('neighborhood', data.bairro, { shouldValidate: true });\n setValue('city', data.localidade, { shouldValidate: true });\n setValue('state', data.uf, { shouldValidate: true });\n })\n .catch(() => {\n // CEP não encontrado: o usuário preenche o endereço na mão.\n });\n };\n\n async function onSubmit(data: BillingDataFormValues) {\n const payload: UpdateBillingDataRequest =\n data.country === 'BR'\n ? {\n financial_document_type: data.personType === 'pf' ? 1 : 2,\n financial_document: data.document,\n financial_name: data.financialName,\n financial_email: data.financialEmail,\n zipcode: data.cep,\n address: data.street,\n address_number: data.streetNumber,\n address_complement: data.complement ?? '',\n neighborhood: data.neighborhood,\n city: data.city,\n state: data.state,\n country: data.country,\n }\n : {\n financial_name: data.financialName,\n financial_email: data.financialEmail,\n country: data.country,\n };\n\n try {\n await updateBillingData(payload);\n setIsSubmitted(true);\n toast.custom(\n (t) => (\n <Toast\n variant=\"success\"\n message={translate('common.billing.requiredData.successToast')}\n toastId={t}\n />\n ),\n { duration: 5000 },\n );\n } catch (error) {\n /* O backend devolve a razão exata da recusa (ex.: documento fiscal inválido).\n * Trocar por um texto genérico deixaria o usuário travado sem saber o que corrigir. */\n const message =\n error instanceof Error && error.message\n ? error.message\n : translate('common.billing.requiredData.errorToast');\n toast.custom((t) => <Toast variant=\"error\" message={message} toastId={t} />, {\n duration: 5000,\n });\n }\n }\n\n if (!isRequired || isSubmitted) return null;\n\n return (\n <Dialog open onOpenChange={() => {}}>\n <DialogContent\n showCloseButton={false}\n onEscapeKeyDown={(event: Event) => event.preventDefault()}\n onPointerDownOutside={(event: Event) => event.preventDefault()}\n onInteractOutside={(event: Event) => event.preventDefault()}\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-[502px] 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-hidden\"\n >\n <DialogHeader className=\"gap-3 text-left p-4 lg:p-5 border-b border-zinc-200 shrink-0\">\n <div className=\"flex items-center justify-center w-10 h-10 bg-zinc-50 rounded-lg\">\n <IconFileInvoice size={24} className=\"text-zinc-950\" />\n </div>\n <div className=\"flex flex-col gap-2\">\n <DialogTitle className=\"paragraph-medium-semibold text-zinc-950\">\n {translate('common.billing.requiredData.title')}\n </DialogTitle>\n <span className=\"paragraph-small-regular text-zinc-600\">\n {isBrazil\n ? translate('common.billing.requiredData.description')\n : translate('common.billing.requiredData.descriptionInternational')}\n </span>\n </div>\n </DialogHeader>\n\n <form\n onSubmit={handleSubmit(onSubmit)}\n className=\"flex flex-col flex-1 min-h-0\"\n noValidate\n >\n <div className=\"flex flex-col gap-6 p-4 lg:p-5 flex-1 overflow-y-auto\">\n <div className=\"flex flex-col gap-5\">\n <Controller\n name=\"country\"\n control={control}\n render={({ field }) => (\n <SelectField\n label={translate('common.billing.requiredData.country')}\n placeholder={translate('common.billing.requiredData.select')}\n value={field.value || undefined}\n onChange={(value) =>\n setValue('country', String(value), { shouldValidate: true })\n }\n options={COUNTRY_OPTIONS}\n error={!!errors.country}\n errorMessage={errors.country?.message}\n />\n )}\n />\n\n {isBrazil && (\n <div className=\"flex gap-4\">\n <Controller\n name=\"personType\"\n control={control}\n render={({ field }) => (\n <SelectField\n label={translate('common.billing.requiredData.personType')}\n placeholder={translate('common.billing.requiredData.select')}\n value={field.value}\n onChange={(value) => handlePersonTypeChange(value as 'pf' | 'pj')}\n options={[\n {\n value: 'pf',\n label: translate('common.billing.requiredData.personTypePf'),\n },\n {\n value: 'pj',\n label: translate('common.billing.requiredData.personTypePj'),\n },\n ]}\n containerClassName=\"flex-1\"\n />\n )}\n />\n <div className=\"flex-1\">\n <FormField\n label={\n isCompany\n ? translate('common.billing.requiredData.cnpj')\n : translate('common.billing.requiredData.cpf')\n }\n placeholder={isCompany ? '__.___.___/____-__' : '___.___.___-__'}\n error={!!errors.document}\n errorMessage={errors.document?.message}\n {...register('document', {\n onChange: (event) => handleDocumentChange(event.target.value),\n })}\n />\n </div>\n </div>\n )}\n\n <FormField\n label={\n isBrazil && isCompany\n ? translate('common.billing.requiredData.companyName')\n : translate('common.billing.requiredData.fullName')\n }\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.financialName}\n errorMessage={errors.financialName?.message}\n {...register('financialName')}\n />\n\n <FormField\n label={translate('common.billing.requiredData.financialEmail')}\n placeholder={translate('common.billing.requiredData.financialEmailPlaceholder')}\n type=\"email\"\n error={!!errors.financialEmail}\n errorMessage={errors.financialEmail?.message}\n {...register('financialEmail')}\n />\n </div>\n\n {isBrazil && (\n <>\n <div className=\"h-px bg-zinc-200\" />\n\n <div className=\"flex flex-col gap-5\">\n <span className=\"paragraph-small-semibold text-zinc-950\">\n {translate('common.billing.requiredData.addressHeading')}\n </span>\n\n <FormField\n label={translate('common.billing.requiredData.cep')}\n placeholder=\"_____-___\"\n error={!!errors.cep}\n errorMessage={errors.cep?.message}\n {...register('cep', {\n onChange: (event) => handleCepChange(event.target.value),\n })}\n />\n\n <div className=\"flex gap-4\">\n <div className=\"flex-[3]\">\n <FormField\n label={translate('common.billing.requiredData.street')}\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.street}\n errorMessage={errors.street?.message}\n {...register('street')}\n />\n </div>\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.streetNumber')}\n placeholder=\"000\"\n error={!!errors.streetNumber}\n errorMessage={errors.streetNumber?.message}\n {...register('streetNumber')}\n />\n </div>\n </div>\n\n <div className=\"flex gap-4\">\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.neighborhood')}\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.neighborhood}\n errorMessage={errors.neighborhood?.message}\n {...register('neighborhood')}\n />\n </div>\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.complement')}\n optional\n placeholder={translate('common.billing.requiredData.typeHere')}\n {...register('complement')}\n />\n </div>\n </div>\n\n <div className=\"flex gap-4\">\n <div className=\"flex-1\">\n <FormField\n label={translate('common.billing.requiredData.city')}\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.city}\n errorMessage={errors.city?.message}\n {...register('city')}\n />\n </div>\n <div className=\"flex-1\">\n <Controller\n name=\"state\"\n control={control}\n render={({ field }) => (\n <SelectField\n label={translate('common.billing.requiredData.state')}\n placeholder={translate('common.billing.requiredData.select')}\n value={field.value || undefined}\n onChange={(value) =>\n setValue('state', String(value), { shouldValidate: true })\n }\n options={BR_STATE_OPTIONS}\n error={!!errors.state}\n errorMessage={errors.state?.message}\n />\n )}\n />\n </div>\n </div>\n </div>\n </>\n )}\n </div>\n\n <div className=\"flex items-center justify-end p-4 lg:p-5 border-t border-zinc-200 shrink-0\">\n <Button\n type=\"submit\"\n className=\"h-10! w-full lg:w-fit\"\n disabled={!isValid || isSubmitting}\n loading={isSubmitting}\n >\n {isSubmitting\n ? translate('common.billing.requiredData.submitting')\n : translate('common.billing.requiredData.submit')}\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\n/**\n * Modal bloqueante que exige o cadastro de cobrança/fiscal de contas que já\n * pagaram sem ele — sem esses dados a nota fiscal não é emitida. Monte uma vez\n * no layout raiz do app; ele mesmo decide se aparece (ver `useRequiredBillingData`).\n */\nexport default function RequiredBillingDataModal() {\n const { user, isLoading } = useAuth();\n\n /* Sem sessão não há conta nem assinatura pra consultar — evita disparar as\n * queries (e tomar 401) em /login, /register e demais rotas públicas. */\n if (isLoading || !user) return null;\n\n return <RequiredBillingDataModalContent />;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
3
4
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
4
5
|
import { IconX } from "@tabler/icons-react";
|
|
5
6
|
import { cn } from "../../../infra/utils/clsx";
|
|
7
|
+
const DialogDepthContext = React.createContext(0);
|
|
8
|
+
const DIALOG_LAYERS = [
|
|
9
|
+
{ overlay: "z-[1000]", content: "z-[1001]" },
|
|
10
|
+
{ overlay: "z-[1010]", content: "z-[1011]" },
|
|
11
|
+
{ overlay: "z-[1020]", content: "z-[1021]" },
|
|
12
|
+
{ overlay: "z-[1030]", content: "z-[1031]" }
|
|
13
|
+
];
|
|
14
|
+
function useDialogLayer() {
|
|
15
|
+
const depth = React.useContext(DialogDepthContext);
|
|
16
|
+
const index = Math.min(Math.max(depth - 1, 0), DIALOG_LAYERS.length - 1);
|
|
17
|
+
return DIALOG_LAYERS[index];
|
|
18
|
+
}
|
|
6
19
|
function Dialog({
|
|
7
20
|
...props
|
|
8
21
|
}) {
|
|
9
|
-
|
|
22
|
+
const depth = React.useContext(DialogDepthContext);
|
|
23
|
+
return /* @__PURE__ */ jsx(DialogDepthContext.Provider, { value: depth + 1, children: /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props }) });
|
|
10
24
|
}
|
|
11
25
|
function DialogTrigger({
|
|
12
26
|
...props
|
|
@@ -27,12 +41,14 @@ function DialogOverlay({
|
|
|
27
41
|
className,
|
|
28
42
|
...props
|
|
29
43
|
}) {
|
|
44
|
+
const layer = useDialogLayer();
|
|
30
45
|
return /* @__PURE__ */ jsx(
|
|
31
46
|
DialogPrimitive.Overlay,
|
|
32
47
|
{
|
|
33
48
|
"data-slot": "dialog-overlay",
|
|
34
49
|
className: cn(
|
|
35
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0
|
|
50
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 bg-black/50",
|
|
51
|
+
layer.overlay,
|
|
36
52
|
className
|
|
37
53
|
),
|
|
38
54
|
...props
|
|
@@ -47,6 +63,7 @@ function DialogContent({
|
|
|
47
63
|
hideOverlay = false,
|
|
48
64
|
...props
|
|
49
65
|
}) {
|
|
66
|
+
const layer = useDialogLayer();
|
|
50
67
|
return /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
51
68
|
!hideOverlay && /* @__PURE__ */ jsx(DialogOverlay, { className: overlayClassName }),
|
|
52
69
|
/* @__PURE__ */ jsxs(
|
|
@@ -54,7 +71,8 @@ function DialogContent({
|
|
|
54
71
|
{
|
|
55
72
|
"data-slot": "dialog-content",
|
|
56
73
|
className: cn(
|
|
57
|
-
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%]
|
|
74
|
+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
75
|
+
layer.content,
|
|
58
76
|
className
|
|
59
77
|
),
|
|
60
78
|
...props,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ui/overlay/Dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from '@tabler/icons-react';\nimport { cn } from \"../../../infra/utils/clsx\";\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ui/overlay/Dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from '@tabler/icons-react';\nimport { cn } from \"../../../infra/utils/clsx\";\n\n// Cada `Dialog` aninhado sobe uma camada de z-index, para que o overlay do modal\n// de cima cubra o conteudo do modal de baixo. Classes literais para o Tailwind gerar.\nconst DialogDepthContext = React.createContext(0);\n\nconst DIALOG_LAYERS = [\n { overlay: \"z-[1000]\", content: \"z-[1001]\" },\n { overlay: \"z-[1010]\", content: \"z-[1011]\" },\n { overlay: \"z-[1020]\", content: \"z-[1021]\" },\n { overlay: \"z-[1030]\", content: \"z-[1031]\" },\n] as const;\n\nfunction useDialogLayer() {\n const depth = React.useContext(DialogDepthContext);\n const index = Math.min(Math.max(depth - 1, 0), DIALOG_LAYERS.length - 1);\n return DIALOG_LAYERS[index];\n}\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n const depth = React.useContext(DialogDepthContext);\n return (\n <DialogDepthContext.Provider value={depth + 1}>\n <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n </DialogDepthContext.Provider>\n );\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n const layer = useDialogLayer();\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 bg-black/50\",\n layer.overlay,\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n overlayClassName,\n hideOverlay = false,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n overlayClassName?: string;\n hideOverlay?: boolean;\n}) {\n const layer = useDialogLayer();\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n {!hideOverlay && <DialogOverlay className={overlayClassName} />}\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n layer.content,\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <div className=\"absolute top-0.5 right-0\">\n <div className=\"p-4\">\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none\"\n >\n <IconX className=\"size-[18px]\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </div>\n </div>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\n \"p-5 flex flex-col gap-2 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n"],"mappings":";AA8BM,cAsEQ,YAtER;AA5BN,YAAY,WAAW;AACvB,YAAY,qBAAqB;AACjC,SAAS,aAAa;AACtB,SAAS,UAAU;AAInB,MAAM,qBAAqB,MAAM,cAAc,CAAC;AAEhD,MAAM,gBAAgB;AAAA,EACpB,EAAE,SAAS,YAAY,SAAS,WAAW;AAAA,EAC3C,EAAE,SAAS,YAAY,SAAS,WAAW;AAAA,EAC3C,EAAE,SAAS,YAAY,SAAS,WAAW;AAAA,EAC3C,EAAE,SAAS,YAAY,SAAS,WAAW;AAC7C;AAEA,SAAS,iBAAiB;AACxB,QAAM,QAAQ,MAAM,WAAW,kBAAkB;AACjD,QAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,QAAQ,GAAG,CAAC,GAAG,cAAc,SAAS,CAAC;AACvE,SAAO,cAAc,KAAK;AAC5B;AAEA,SAAS,OAAO;AAAA,EACd,GAAG;AACL,GAAsD;AACpD,QAAM,QAAQ,MAAM,WAAW,kBAAkB;AACjD,SACE,oBAAC,mBAAmB,UAAnB,EAA4B,OAAO,QAAQ,GAC1C,8BAAC,gBAAgB,MAAhB,EAAqB,aAAU,UAAU,GAAG,OAAO,GACtD;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB,GAAG;AACL,GAAyD;AACvD,SAAO,oBAAC,gBAAgB,SAAhB,EAAwB,aAAU,kBAAkB,GAAG,OAAO;AACxE;AAEA,SAAS,aAAa;AAAA,EACpB,GAAG;AACL,GAAwD;AACtD,SAAO,oBAAC,gBAAgB,QAAhB,EAAuB,aAAU,iBAAiB,GAAG,OAAO;AACtE;AAEA,SAAS,YAAY;AAAA,EACnB,GAAG;AACL,GAAuD;AACrD,SAAO,oBAAC,gBAAgB,OAAhB,EAAsB,aAAU,gBAAgB,GAAG,OAAO;AACpE;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA,GAAG;AACL,GAAyD;AACvD,QAAM,QAAQ,eAAe;AAC7B,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA,MAAM;AAAA,QACN;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA,cAAc;AAAA,EACd,GAAG;AACL,GAIG;AACD,QAAM,QAAQ,eAAe;AAC7B,SACE,qBAAC,gBAAa,aAAU,iBACrB;AAAA,KAAC,eAAe,oBAAC,iBAAc,WAAW,kBAAkB;AAAA,IAC7D;AAAA,MAAC,gBAAgB;AAAA,MAAhB;AAAA,QACC,aAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA,MAAM;AAAA,UACN;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,UACA,mBACC,oBAAC,SAAI,WAAU,4BACb,8BAAC,SAAI,WAAU,OACb;AAAA,YAAC,gBAAgB;AAAA,YAAhB;AAAA,cACC,aAAU;AAAA,cACV,WAAU;AAAA,cAEV;AAAA,oCAAC,SAAM,WAAU,eAAc;AAAA,gBAC/B,oBAAC,UAAK,WAAU,WAAU,mBAAK;AAAA;AAAA;AAAA,UACjC,GACF,GACF;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAEJ;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA,GAAG;AACL,GAAuD;AACrD,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,sCAAsC,SAAS;AAAA,MAC5D,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iCAAiC,SAAS;AAAA,MACvD,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -331,6 +331,7 @@ const messages = {
|
|
|
331
331
|
requiredData: {
|
|
332
332
|
title: "Complete your billing information",
|
|
333
333
|
description: "We need this information to issue the invoice for your payments. Filling it in is required to keep using the platform.",
|
|
334
|
+
descriptionInternational: "Since your billing address is outside Brazil, we only need your name and email for your payment receipts.",
|
|
334
335
|
addressHeading: "Billing address",
|
|
335
336
|
select: "Select",
|
|
336
337
|
typeHere: "Type here",
|