@greatapps/common 1.1.739 → 1.1.741
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 +448 -0
- package/dist/components/modals/billing/RequiredBillingDataModal.mjs.map +1 -0
- package/dist/i18n/messages/en-us.mjs +39 -0
- package/dist/i18n/messages/en-us.mjs.map +1 -1
- package/dist/i18n/messages/es-es.mjs +39 -0
- package/dist/i18n/messages/es-es.mjs.map +1 -1
- package/dist/i18n/messages/pt-br.mjs +40 -0
- package/dist/i18n/messages/pt-br.mjs.map +1 -1
- package/dist/index.mjs +48 -32
- package/dist/index.mjs.map +1 -1
- package/dist/modules/accounts/actions/account-management.action.mjs +15 -0
- package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
- package/dist/modules/accounts/hooks/use-required-billing-data.hook.mjs +26 -0
- package/dist/modules/accounts/hooks/use-required-billing-data.hook.mjs.map +1 -0
- package/dist/modules/accounts/hooks/useAccountManagement.mjs +13 -1
- package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
- package/dist/modules/accounts/utils/billing-data.mjs +35 -0
- package/dist/modules/accounts/utils/billing-data.mjs.map +1 -0
- package/dist/modules/subscriptions/utils/has-paid-subscription.mjs +13 -0
- package/dist/modules/subscriptions/utils/has-paid-subscription.mjs.map +1 -0
- package/dist/server.mjs +2 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/modals/billing/RequiredBillingDataModal.tsx +548 -0
- package/src/i18n/messages/en-us.ts +40 -0
- package/src/i18n/messages/es-es.ts +40 -0
- package/src/i18n/messages/pt-br.ts +42 -0
- package/src/index.ts +11 -0
- package/src/modules/accounts/actions/account-management.action.ts +24 -0
- package/src/modules/accounts/hooks/use-required-billing-data.hook.ts +38 -0
- package/src/modules/accounts/hooks/useAccountManagement.ts +13 -0
- package/src/modules/accounts/types.ts +11 -0
- package/src/modules/accounts/utils/billing-data.ts +81 -0
- package/src/modules/subscriptions/utils/has-paid-subscription.ts +27 -0
- package/src/server.ts +1 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { Controller, useForm } from "react-hook-form";
|
|
5
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
6
|
+
import { useTranslations } from "next-intl";
|
|
7
|
+
import { toast } from "sonner";
|
|
8
|
+
import z from "zod";
|
|
9
|
+
import { IconFileInvoice } from "@tabler/icons-react";
|
|
10
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../../ui/overlay/Dialog";
|
|
11
|
+
import { Button } from "../../ui/buttons/Button";
|
|
12
|
+
import { FormField } from "../../ui/form/FormField";
|
|
13
|
+
import { SelectField } from "../../ui/form/SelectField";
|
|
14
|
+
import { Toast } from "../../ui/feedback/Toast";
|
|
15
|
+
import { useAuth } from "../../../providers/auth.provider";
|
|
16
|
+
import { useViaCep } from "../../../modules/accounts/hooks/useViaCep";
|
|
17
|
+
import { useUpdateBillingData } from "../../../modules/accounts/hooks/useAccountManagement";
|
|
18
|
+
import { useRequiredBillingData } from "../../../modules/accounts/hooks/use-required-billing-data.hook";
|
|
19
|
+
import { COUNTRIES } from "../../../utils/countries";
|
|
20
|
+
import { BR_STATE_OPTIONS } from "../../../utils/constants/br-states";
|
|
21
|
+
import { formatCNPJ, formatCPF, formatPostalCode } from "../../../utils/format/masks";
|
|
22
|
+
import { isValidCNPJ, isValidCPF } from "../../../utils/validators/common";
|
|
23
|
+
const COUNTRY_OPTIONS = COUNTRIES.map((country) => ({
|
|
24
|
+
value: country.iso,
|
|
25
|
+
label: country.name
|
|
26
|
+
}));
|
|
27
|
+
function buildBillingDataSchema(isInternational, translate) {
|
|
28
|
+
const requiredText = z.string().trim().min(1, translate("common.billing.requiredData.requiredField"));
|
|
29
|
+
const base = z.object({
|
|
30
|
+
personType: z.enum(["pf", "pj"]),
|
|
31
|
+
document: z.string().trim(),
|
|
32
|
+
financialName: requiredText,
|
|
33
|
+
financialEmail: z.string().trim().min(1, translate("common.billing.requiredData.requiredField")).email(translate("common.billing.requiredData.invalidEmail")),
|
|
34
|
+
cep: requiredText,
|
|
35
|
+
street: requiredText,
|
|
36
|
+
streetNumber: z.string().trim(),
|
|
37
|
+
complement: z.string().trim().optional(),
|
|
38
|
+
neighborhood: z.string().trim(),
|
|
39
|
+
city: requiredText,
|
|
40
|
+
state: requiredText,
|
|
41
|
+
country: requiredText
|
|
42
|
+
});
|
|
43
|
+
if (isInternational) return base;
|
|
44
|
+
return base.superRefine((data, ctx) => {
|
|
45
|
+
if (!data.streetNumber) {
|
|
46
|
+
ctx.addIssue({
|
|
47
|
+
code: "custom",
|
|
48
|
+
path: ["streetNumber"],
|
|
49
|
+
message: translate("common.billing.requiredData.requiredField")
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (!data.neighborhood) {
|
|
53
|
+
ctx.addIssue({
|
|
54
|
+
code: "custom",
|
|
55
|
+
path: ["neighborhood"],
|
|
56
|
+
message: translate("common.billing.requiredData.requiredField")
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (data.cep.replace(/\D/g, "").length !== 8) {
|
|
60
|
+
ctx.addIssue({
|
|
61
|
+
code: "custom",
|
|
62
|
+
path: ["cep"],
|
|
63
|
+
message: translate("common.billing.requiredData.invalidCep")
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const isCompany = data.personType === "pj";
|
|
67
|
+
const digits = data.document.replace(/\D/g, "");
|
|
68
|
+
if (digits.length !== (isCompany ? 14 : 11)) {
|
|
69
|
+
ctx.addIssue({
|
|
70
|
+
code: "custom",
|
|
71
|
+
path: ["document"],
|
|
72
|
+
message: isCompany ? translate("common.billing.requiredData.invalidCnpj") : translate("common.billing.requiredData.invalidCpf")
|
|
73
|
+
});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const isValid = isCompany ? isValidCNPJ(digits) : isValidCPF(digits);
|
|
77
|
+
if (!isValid) {
|
|
78
|
+
ctx.addIssue({
|
|
79
|
+
code: "custom",
|
|
80
|
+
path: ["document"],
|
|
81
|
+
message: isCompany ? translate("common.billing.requiredData.invalidCnpjChecksum") : translate("common.billing.requiredData.invalidCpfChecksum")
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function formatDocument(document, isCompany) {
|
|
87
|
+
if (!document) return "";
|
|
88
|
+
return isCompany ? formatCNPJ(document) : formatCPF(document);
|
|
89
|
+
}
|
|
90
|
+
function RequiredBillingDataModalContent() {
|
|
91
|
+
const translate = useTranslations();
|
|
92
|
+
const { user } = useAuth();
|
|
93
|
+
const { isRequired, account, isInternational } = useRequiredBillingData();
|
|
94
|
+
const { mutateAsync: updateBillingData } = useUpdateBillingData();
|
|
95
|
+
const { mutateAsync: lookupCep } = useViaCep();
|
|
96
|
+
const [isSubmitted, setIsSubmitted] = useState(false);
|
|
97
|
+
const isPrefilled = useRef(false);
|
|
98
|
+
const schema = useMemo(
|
|
99
|
+
() => buildBillingDataSchema(isInternational, translate),
|
|
100
|
+
[isInternational, translate]
|
|
101
|
+
);
|
|
102
|
+
const form = useForm({
|
|
103
|
+
resolver: zodResolver(schema),
|
|
104
|
+
mode: "onChange",
|
|
105
|
+
defaultValues: {
|
|
106
|
+
personType: "pf",
|
|
107
|
+
document: "",
|
|
108
|
+
financialName: "",
|
|
109
|
+
financialEmail: "",
|
|
110
|
+
cep: "",
|
|
111
|
+
street: "",
|
|
112
|
+
streetNumber: "",
|
|
113
|
+
complement: "",
|
|
114
|
+
neighborhood: "",
|
|
115
|
+
city: "",
|
|
116
|
+
state: "",
|
|
117
|
+
country: "BR"
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
const {
|
|
121
|
+
register,
|
|
122
|
+
control,
|
|
123
|
+
handleSubmit,
|
|
124
|
+
reset,
|
|
125
|
+
setValue,
|
|
126
|
+
watch,
|
|
127
|
+
formState: { errors, isSubmitting, isValid }
|
|
128
|
+
} = form;
|
|
129
|
+
const personType = watch("personType");
|
|
130
|
+
const isCompany = personType === "pj";
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (!account || isPrefilled.current) return;
|
|
133
|
+
isPrefilled.current = true;
|
|
134
|
+
const accountIsCompany = account.financial_document_type === 2;
|
|
135
|
+
reset({
|
|
136
|
+
personType: accountIsCompany ? "pj" : "pf",
|
|
137
|
+
document: formatDocument(account.financial_document, accountIsCompany),
|
|
138
|
+
financialName: account.financial_name ?? "",
|
|
139
|
+
financialEmail: account.financial_email || user?.email || "",
|
|
140
|
+
cep: account.zipcode ?? "",
|
|
141
|
+
street: account.address ?? "",
|
|
142
|
+
streetNumber: account.address_number ?? "",
|
|
143
|
+
complement: account.address_complement ?? "",
|
|
144
|
+
neighborhood: account.neighborhood ?? "",
|
|
145
|
+
city: account.city ?? "",
|
|
146
|
+
state: account.state ?? "",
|
|
147
|
+
country: account.country || (isInternational ? "US" : "BR")
|
|
148
|
+
});
|
|
149
|
+
}, [account, isInternational, reset, user?.email]);
|
|
150
|
+
const handleDocumentChange = (rawValue) => {
|
|
151
|
+
setValue("document", isCompany ? formatCNPJ(rawValue) : formatCPF(rawValue), {
|
|
152
|
+
shouldValidate: true
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
const handlePersonTypeChange = (value) => {
|
|
156
|
+
if (value === personType) return;
|
|
157
|
+
setValue("document", "");
|
|
158
|
+
setValue("personType", value, { shouldValidate: true });
|
|
159
|
+
};
|
|
160
|
+
const handleCepChange = (rawValue) => {
|
|
161
|
+
if (isInternational) {
|
|
162
|
+
setValue("cep", rawValue, { shouldValidate: true });
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
setValue("cep", formatPostalCode(rawValue), { shouldValidate: true });
|
|
166
|
+
const digits = rawValue.replace(/\D/g, "");
|
|
167
|
+
if (digits.length !== 8) return;
|
|
168
|
+
lookupCep(digits).then((data) => {
|
|
169
|
+
setValue("street", data.logradouro, { shouldValidate: true });
|
|
170
|
+
setValue("neighborhood", data.bairro, { shouldValidate: true });
|
|
171
|
+
setValue("city", data.localidade, { shouldValidate: true });
|
|
172
|
+
setValue("state", data.uf, { shouldValidate: true });
|
|
173
|
+
}).catch(() => {
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
async function onSubmit(data) {
|
|
177
|
+
const payload = {
|
|
178
|
+
...isInternational ? {} : {
|
|
179
|
+
financial_document_type: data.personType === "pf" ? 1 : 2,
|
|
180
|
+
financial_document: data.document
|
|
181
|
+
},
|
|
182
|
+
financial_name: data.financialName,
|
|
183
|
+
financial_email: data.financialEmail,
|
|
184
|
+
zipcode: data.cep,
|
|
185
|
+
address: data.street,
|
|
186
|
+
address_number: data.streetNumber,
|
|
187
|
+
address_complement: data.complement ?? "",
|
|
188
|
+
neighborhood: data.neighborhood,
|
|
189
|
+
city: data.city,
|
|
190
|
+
state: data.state,
|
|
191
|
+
country: data.country
|
|
192
|
+
};
|
|
193
|
+
try {
|
|
194
|
+
await updateBillingData(payload);
|
|
195
|
+
setIsSubmitted(true);
|
|
196
|
+
toast.custom(
|
|
197
|
+
(t) => /* @__PURE__ */ jsx(
|
|
198
|
+
Toast,
|
|
199
|
+
{
|
|
200
|
+
variant: "success",
|
|
201
|
+
message: translate("common.billing.requiredData.successToast"),
|
|
202
|
+
toastId: t
|
|
203
|
+
}
|
|
204
|
+
),
|
|
205
|
+
{ duration: 5e3 }
|
|
206
|
+
);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const message = error instanceof Error && error.message ? error.message : translate("common.billing.requiredData.errorToast");
|
|
209
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message, toastId: t }), {
|
|
210
|
+
duration: 5e3
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (!isRequired || isSubmitted) return null;
|
|
215
|
+
return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: () => {
|
|
216
|
+
}, children: /* @__PURE__ */ jsxs(
|
|
217
|
+
DialogContent,
|
|
218
|
+
{
|
|
219
|
+
showCloseButton: false,
|
|
220
|
+
onEscapeKeyDown: (event) => event.preventDefault(),
|
|
221
|
+
onPointerDownOutside: (event) => event.preventDefault(),
|
|
222
|
+
onInteractOutside: (event) => event.preventDefault(),
|
|
223
|
+
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",
|
|
224
|
+
children: [
|
|
225
|
+
/* @__PURE__ */ jsxs(DialogHeader, { className: "gap-3 text-left p-4 lg:p-5 border-b border-zinc-200 shrink-0", children: [
|
|
226
|
+
/* @__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" }) }),
|
|
227
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
228
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "paragraph-medium-semibold text-zinc-950", children: translate("common.billing.requiredData.title") }),
|
|
229
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-small-regular text-zinc-600", children: translate("common.billing.requiredData.description") })
|
|
230
|
+
] })
|
|
231
|
+
] }),
|
|
232
|
+
/* @__PURE__ */ jsxs(
|
|
233
|
+
"form",
|
|
234
|
+
{
|
|
235
|
+
onSubmit: handleSubmit(onSubmit),
|
|
236
|
+
className: "flex flex-col flex-1 min-h-0",
|
|
237
|
+
noValidate: true,
|
|
238
|
+
children: [
|
|
239
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 p-4 lg:p-5 flex-1 overflow-y-auto", children: [
|
|
240
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
241
|
+
!isInternational && /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
242
|
+
/* @__PURE__ */ jsx(
|
|
243
|
+
Controller,
|
|
244
|
+
{
|
|
245
|
+
name: "personType",
|
|
246
|
+
control,
|
|
247
|
+
render: ({ field }) => /* @__PURE__ */ jsx(
|
|
248
|
+
SelectField,
|
|
249
|
+
{
|
|
250
|
+
label: translate("common.billing.requiredData.personType"),
|
|
251
|
+
placeholder: translate("common.billing.requiredData.select"),
|
|
252
|
+
value: field.value,
|
|
253
|
+
onChange: (value) => handlePersonTypeChange(value),
|
|
254
|
+
options: [
|
|
255
|
+
{
|
|
256
|
+
value: "pf",
|
|
257
|
+
label: translate("common.billing.requiredData.personTypePf")
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
value: "pj",
|
|
261
|
+
label: translate("common.billing.requiredData.personTypePj")
|
|
262
|
+
}
|
|
263
|
+
],
|
|
264
|
+
containerClassName: "flex-1"
|
|
265
|
+
}
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
),
|
|
269
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
270
|
+
FormField,
|
|
271
|
+
{
|
|
272
|
+
label: isCompany ? translate("common.billing.requiredData.cnpj") : translate("common.billing.requiredData.cpf"),
|
|
273
|
+
placeholder: isCompany ? "__.___.___/____-__" : "___.___.___-__",
|
|
274
|
+
error: !!errors.document,
|
|
275
|
+
errorMessage: errors.document?.message,
|
|
276
|
+
...register("document", {
|
|
277
|
+
onChange: (event) => handleDocumentChange(event.target.value)
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
) })
|
|
281
|
+
] }),
|
|
282
|
+
/* @__PURE__ */ jsx(
|
|
283
|
+
FormField,
|
|
284
|
+
{
|
|
285
|
+
label: isCompany ? translate("common.billing.requiredData.companyName") : translate("common.billing.requiredData.fullName"),
|
|
286
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
287
|
+
error: !!errors.financialName,
|
|
288
|
+
errorMessage: errors.financialName?.message,
|
|
289
|
+
...register("financialName")
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
/* @__PURE__ */ jsx(
|
|
293
|
+
FormField,
|
|
294
|
+
{
|
|
295
|
+
label: translate("common.billing.requiredData.financialEmail"),
|
|
296
|
+
placeholder: translate("common.billing.requiredData.financialEmailPlaceholder"),
|
|
297
|
+
type: "email",
|
|
298
|
+
error: !!errors.financialEmail,
|
|
299
|
+
errorMessage: errors.financialEmail?.message,
|
|
300
|
+
...register("financialEmail")
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
] }),
|
|
304
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-zinc-200" }),
|
|
305
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
306
|
+
/* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-zinc-950", children: translate("common.billing.requiredData.addressHeading") }),
|
|
307
|
+
/* @__PURE__ */ jsx(
|
|
308
|
+
FormField,
|
|
309
|
+
{
|
|
310
|
+
label: isInternational ? translate("common.billing.requiredData.postalCode") : translate("common.billing.requiredData.cep"),
|
|
311
|
+
placeholder: isInternational ? "" : "_____-___",
|
|
312
|
+
error: !!errors.cep,
|
|
313
|
+
errorMessage: errors.cep?.message,
|
|
314
|
+
...register("cep", {
|
|
315
|
+
onChange: (event) => handleCepChange(event.target.value)
|
|
316
|
+
})
|
|
317
|
+
}
|
|
318
|
+
),
|
|
319
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
320
|
+
/* @__PURE__ */ jsx("div", { className: "flex-[3]", children: /* @__PURE__ */ jsx(
|
|
321
|
+
FormField,
|
|
322
|
+
{
|
|
323
|
+
label: translate("common.billing.requiredData.street"),
|
|
324
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
325
|
+
error: !!errors.street,
|
|
326
|
+
errorMessage: errors.street?.message,
|
|
327
|
+
...register("street")
|
|
328
|
+
}
|
|
329
|
+
) }),
|
|
330
|
+
!isInternational && /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
331
|
+
FormField,
|
|
332
|
+
{
|
|
333
|
+
label: translate("common.billing.requiredData.streetNumber"),
|
|
334
|
+
placeholder: "000",
|
|
335
|
+
error: !!errors.streetNumber,
|
|
336
|
+
errorMessage: errors.streetNumber?.message,
|
|
337
|
+
...register("streetNumber")
|
|
338
|
+
}
|
|
339
|
+
) })
|
|
340
|
+
] }),
|
|
341
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
342
|
+
!isInternational && /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
343
|
+
FormField,
|
|
344
|
+
{
|
|
345
|
+
label: translate("common.billing.requiredData.neighborhood"),
|
|
346
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
347
|
+
error: !!errors.neighborhood,
|
|
348
|
+
errorMessage: errors.neighborhood?.message,
|
|
349
|
+
...register("neighborhood")
|
|
350
|
+
}
|
|
351
|
+
) }),
|
|
352
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
353
|
+
FormField,
|
|
354
|
+
{
|
|
355
|
+
label: translate("common.billing.requiredData.complement"),
|
|
356
|
+
optional: true,
|
|
357
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
358
|
+
...register("complement")
|
|
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.city"),
|
|
367
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
368
|
+
error: !!errors.city,
|
|
369
|
+
errorMessage: errors.city?.message,
|
|
370
|
+
...register("city")
|
|
371
|
+
}
|
|
372
|
+
) }),
|
|
373
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: isInternational ? /* @__PURE__ */ jsx(
|
|
374
|
+
FormField,
|
|
375
|
+
{
|
|
376
|
+
label: translate("common.billing.requiredData.stateProvince"),
|
|
377
|
+
placeholder: translate("common.billing.requiredData.typeHere"),
|
|
378
|
+
error: !!errors.state,
|
|
379
|
+
errorMessage: errors.state?.message,
|
|
380
|
+
...register("state")
|
|
381
|
+
}
|
|
382
|
+
) : /* @__PURE__ */ jsx(
|
|
383
|
+
Controller,
|
|
384
|
+
{
|
|
385
|
+
name: "state",
|
|
386
|
+
control,
|
|
387
|
+
render: ({ field }) => /* @__PURE__ */ jsx(
|
|
388
|
+
SelectField,
|
|
389
|
+
{
|
|
390
|
+
label: translate("common.billing.requiredData.state"),
|
|
391
|
+
placeholder: translate("common.billing.requiredData.select"),
|
|
392
|
+
value: field.value || void 0,
|
|
393
|
+
onChange: (value) => setValue("state", value, { shouldValidate: true }),
|
|
394
|
+
options: BR_STATE_OPTIONS,
|
|
395
|
+
error: !!errors.state,
|
|
396
|
+
errorMessage: errors.state?.message
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
}
|
|
400
|
+
) })
|
|
401
|
+
] }),
|
|
402
|
+
/* @__PURE__ */ jsx(
|
|
403
|
+
Controller,
|
|
404
|
+
{
|
|
405
|
+
name: "country",
|
|
406
|
+
control,
|
|
407
|
+
render: ({ field }) => /* @__PURE__ */ jsx(
|
|
408
|
+
SelectField,
|
|
409
|
+
{
|
|
410
|
+
label: translate("common.billing.requiredData.country"),
|
|
411
|
+
placeholder: translate("common.billing.requiredData.select"),
|
|
412
|
+
value: field.value || void 0,
|
|
413
|
+
onChange: (value) => setValue("country", value, { shouldValidate: true }),
|
|
414
|
+
options: COUNTRY_OPTIONS,
|
|
415
|
+
error: !!errors.country,
|
|
416
|
+
errorMessage: errors.country?.message
|
|
417
|
+
}
|
|
418
|
+
)
|
|
419
|
+
}
|
|
420
|
+
)
|
|
421
|
+
] })
|
|
422
|
+
] }),
|
|
423
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end p-4 lg:p-5 border-t border-zinc-200 shrink-0", children: /* @__PURE__ */ jsx(
|
|
424
|
+
Button,
|
|
425
|
+
{
|
|
426
|
+
type: "submit",
|
|
427
|
+
className: "h-10! w-full lg:w-fit",
|
|
428
|
+
disabled: !isValid || isSubmitting,
|
|
429
|
+
loading: isSubmitting,
|
|
430
|
+
children: isSubmitting ? translate("common.billing.requiredData.submitting") : translate("common.billing.requiredData.submit")
|
|
431
|
+
}
|
|
432
|
+
) })
|
|
433
|
+
]
|
|
434
|
+
}
|
|
435
|
+
)
|
|
436
|
+
]
|
|
437
|
+
}
|
|
438
|
+
) });
|
|
439
|
+
}
|
|
440
|
+
function RequiredBillingDataModal() {
|
|
441
|
+
const { user, isLoading } = useAuth();
|
|
442
|
+
if (isLoading || !user) return null;
|
|
443
|
+
return /* @__PURE__ */ jsx(RequiredBillingDataModalContent, {});
|
|
444
|
+
}
|
|
445
|
+
export {
|
|
446
|
+
RequiredBillingDataModal as default
|
|
447
|
+
};
|
|
448
|
+
//# sourceMappingURL=RequiredBillingDataModal.mjs.map
|
|
@@ -0,0 +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(isInternational: boolean, 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 /* Conta internacional não tem CPF/CNPJ, número nem bairro — mesmo recorte do\n * AddCardModal. Exigir esses campos aqui trancaria o cliente fora do app, já que\n * o modal é bloqueante. */\n if (isInternational) return base;\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, isInternational } = 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(isInternational, translate),\n [isInternational, 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 || (isInternational ? 'US' : 'BR'),\n });\n }, [account, isInternational, 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 if (isInternational) {\n setValue('cep', rawValue, { shouldValidate: true });\n return;\n }\n\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 ...(isInternational\n ? {}\n : {\n financial_document_type: data.personType === 'pf' ? 1 : 2,\n financial_document: data.document,\n }),\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 {!isInternational && (\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 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={\n isInternational\n ? translate('common.billing.requiredData.postalCode')\n : translate('common.billing.requiredData.cep')\n }\n placeholder={isInternational ? '' : '_____-___'}\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 {!isInternational && (\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 )}\n </div>\n\n <div className=\"flex gap-4\">\n {!isInternational && (\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 )}\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 {isInternational ? (\n <FormField\n label={translate('common.billing.requiredData.stateProvince')}\n placeholder={translate('common.billing.requiredData.typeHere')}\n error={!!errors.state}\n errorMessage={errors.state?.message}\n {...register('state')}\n />\n ) : (\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 )}\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":[]}
|
|
@@ -326,6 +326,45 @@ const messages = {
|
|
|
326
326
|
newPaymentMethod: "New payment method"
|
|
327
327
|
}
|
|
328
328
|
},
|
|
329
|
+
billing: {
|
|
330
|
+
requiredData: {
|
|
331
|
+
title: "Complete your billing information",
|
|
332
|
+
description: "We need this information to issue the invoice for your payments. Filling it in is required to keep using the platform.",
|
|
333
|
+
addressHeading: "Billing address",
|
|
334
|
+
select: "Select",
|
|
335
|
+
typeHere: "Type here",
|
|
336
|
+
personType: "Entity type",
|
|
337
|
+
personTypePf: "Individual",
|
|
338
|
+
personTypePj: "Company",
|
|
339
|
+
cpf: "CPF",
|
|
340
|
+
cnpj: "CNPJ",
|
|
341
|
+
fullName: "Full name",
|
|
342
|
+
companyName: "Legal name",
|
|
343
|
+
financialEmail: "Billing email",
|
|
344
|
+
financialEmailPlaceholder: "billing@company.com",
|
|
345
|
+
cep: "ZIP code",
|
|
346
|
+
postalCode: "Postal code",
|
|
347
|
+
street: "Address",
|
|
348
|
+
streetNumber: "Number",
|
|
349
|
+
neighborhood: "District",
|
|
350
|
+
complement: "Complement",
|
|
351
|
+
city: "City",
|
|
352
|
+
state: "State",
|
|
353
|
+
stateProvince: "State/Province",
|
|
354
|
+
country: "Country",
|
|
355
|
+
submit: "Save and continue",
|
|
356
|
+
submitting: "Saving...",
|
|
357
|
+
successToast: "Billing information saved successfully.",
|
|
358
|
+
errorToast: "We could not save your billing information, please try again.",
|
|
359
|
+
requiredField: "Required field",
|
|
360
|
+
invalidEmail: "Invalid email",
|
|
361
|
+
invalidCep: "Invalid ZIP code",
|
|
362
|
+
invalidCpf: "Invalid CPF",
|
|
363
|
+
invalidCnpj: "Invalid CNPJ",
|
|
364
|
+
invalidCpfChecksum: "Invalid CPF \u2014 check the verification digits",
|
|
365
|
+
invalidCnpjChecksum: "Invalid CNPJ \u2014 check the verification digits"
|
|
366
|
+
}
|
|
367
|
+
},
|
|
329
368
|
navigation: {
|
|
330
369
|
banners: {
|
|
331
370
|
cancelled: {
|