@greatapps/common 1.1.290 → 1.1.292
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/modals/cards/AddCardModal.mjs +74 -38
- package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CardFormFields.mjs +149 -25
- package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
- package/dist/index.mjs +4 -0
- package/dist/index.mjs.map +1 -1
- package/dist/utils/constants/br-states.mjs +33 -0
- package/dist/utils/constants/br-states.mjs.map +1 -0
- package/dist/utils/format/masks.mjs +11 -0
- package/dist/utils/format/masks.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/modals/cards/AddCardModal.tsx +95 -39
- package/src/components/modals/cards/CardFormFields.tsx +163 -43
- package/src/index.ts +2 -0
- package/src/modules/accounts/types.ts +10 -0
- package/src/utils/constants/br-states.ts +29 -0
- package/src/utils/format/masks.ts +11 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { UseFormReturn } from 'react-hook-form';
|
|
4
4
|
import { FormField } from '../../ui/form/FormField';
|
|
5
5
|
import { SelectField } from '../../ui/form/SelectField';
|
|
6
|
-
import { formatCPF, formatPostalCode } from '../../../utils/format/masks';
|
|
6
|
+
import { formatCPF, formatCNPJ, formatPostalCode } from '../../../utils/format/masks';
|
|
7
7
|
import z from 'zod';
|
|
8
8
|
import { CardCvcElement, CardExpiryElement, CardNumberElement } from '@stripe/react-stripe-js';
|
|
9
9
|
|
|
@@ -20,18 +20,39 @@ const stripeElementOptions = {
|
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export const cardFormSchema = z
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
export const cardFormSchema = z
|
|
24
|
+
.object({
|
|
25
|
+
name: z.string().min(1, 'Nome é obrigatório'),
|
|
26
|
+
number: z.string().min(1, 'Número do cartão é obrigatório'),
|
|
27
|
+
expiry: z.string().min(1, 'Data de validade é obrigatória'),
|
|
28
|
+
cvv: z.string().min(1, 'Código de segurança é obrigatório'),
|
|
29
|
+
country: z.string().min(1, 'País é obrigatório'),
|
|
30
|
+
personType: z.enum(['pf', 'pj']),
|
|
31
|
+
cpf: z.string().optional(),
|
|
32
|
+
cnpj: z.string().optional(),
|
|
33
|
+
fullName: z.string().min(1, 'Nome completo é obrigatório'),
|
|
34
|
+
cep: z.string().min(9, 'CEP é obrigatório'),
|
|
35
|
+
street: z.string().min(1, 'Endereço é obrigatório'),
|
|
36
|
+
streetNumber: z.string().min(1, 'Número é obrigatório'),
|
|
37
|
+
city: z.string().min(1, 'Cidade é obrigatória'),
|
|
38
|
+
state: z.string().min(1, 'UF é obrigatório'),
|
|
39
|
+
complement: z.string().optional(),
|
|
40
|
+
})
|
|
41
|
+
.refine(
|
|
42
|
+
(data) => {
|
|
43
|
+
if (data.personType === 'pf') return !!data.cpf && data.cpf.length >= 14;
|
|
44
|
+
return !!data.cnpj && data.cnpj.length >= 18;
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
message: 'Documento é obrigatório',
|
|
48
|
+
path: ['cpf'],
|
|
49
|
+
}
|
|
50
|
+
);
|
|
32
51
|
|
|
33
52
|
export type CardFormData = z.infer<typeof cardFormSchema>;
|
|
34
53
|
|
|
54
|
+
export const STEP1_FIELDS = ['name', 'number', 'expiry', 'cvv', 'country', 'personType', 'cpf', 'cnpj'] as const;
|
|
55
|
+
|
|
35
56
|
type CardFormFieldsProps = {
|
|
36
57
|
readonly form: UseFormReturn<CardFormData>;
|
|
37
58
|
};
|
|
@@ -44,6 +65,8 @@ export function CardFormFields({ form }: CardFormFieldsProps) {
|
|
|
44
65
|
formState: { errors },
|
|
45
66
|
} = form;
|
|
46
67
|
|
|
68
|
+
const personType = watch('personType');
|
|
69
|
+
|
|
47
70
|
return (
|
|
48
71
|
<div className="flex flex-col gap-5">
|
|
49
72
|
<FormField
|
|
@@ -55,9 +78,7 @@ export function CardFormFields({ form }: CardFormFieldsProps) {
|
|
|
55
78
|
/>
|
|
56
79
|
|
|
57
80
|
<div className="flex flex-col gap-1.5">
|
|
58
|
-
<label className="paragraph-xsmall-semibold text-zinc-600">
|
|
59
|
-
Número do cartão
|
|
60
|
-
</label>
|
|
81
|
+
<label className="paragraph-xsmall-semibold text-zinc-600">Número do cartão</label>
|
|
61
82
|
<div className="h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400 relative">
|
|
62
83
|
<div className="w-full">
|
|
63
84
|
<CardNumberElement
|
|
@@ -75,9 +96,7 @@ export function CardFormFields({ form }: CardFormFieldsProps) {
|
|
|
75
96
|
|
|
76
97
|
<div className="flex gap-4">
|
|
77
98
|
<div className="flex-1 flex flex-col gap-1.5">
|
|
78
|
-
<label className="paragraph-xsmall-semibold text-zinc-600">
|
|
79
|
-
Data de validade
|
|
80
|
-
</label>
|
|
99
|
+
<label className="paragraph-xsmall-semibold text-zinc-600">Data de validade</label>
|
|
81
100
|
<div className="h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400">
|
|
82
101
|
<div className="w-full">
|
|
83
102
|
<CardExpiryElement
|
|
@@ -94,9 +113,7 @@ export function CardFormFields({ form }: CardFormFieldsProps) {
|
|
|
94
113
|
</div>
|
|
95
114
|
|
|
96
115
|
<div className="flex-1 flex flex-col gap-1.5">
|
|
97
|
-
<label className="paragraph-xsmall-semibold text-zinc-600">
|
|
98
|
-
CVC
|
|
99
|
-
</label>
|
|
116
|
+
<label className="paragraph-xsmall-semibold text-zinc-600">CVC</label>
|
|
100
117
|
<div className="h-10 px-3 flex items-center w-full border border-zinc-200 rounded-lg bg-white transition-colors focus-within:border-zinc-400">
|
|
101
118
|
<div className="w-full">
|
|
102
119
|
<CardCvcElement
|
|
@@ -113,45 +130,148 @@ export function CardFormFields({ form }: CardFormFieldsProps) {
|
|
|
113
130
|
</div>
|
|
114
131
|
</div>
|
|
115
132
|
|
|
133
|
+
<SelectField
|
|
134
|
+
label="País"
|
|
135
|
+
placeholder="Selecione"
|
|
136
|
+
value={watch('country')}
|
|
137
|
+
onChange={(value) => setValue('country', value as string)}
|
|
138
|
+
options={[
|
|
139
|
+
{ value: 'BR', label: 'Brasil' },
|
|
140
|
+
{ value: 'ES', label: 'Espanha' },
|
|
141
|
+
{ value: 'US', label: 'Estados Unidos' },
|
|
142
|
+
]}
|
|
143
|
+
/>
|
|
144
|
+
|
|
116
145
|
<div className="flex gap-4">
|
|
117
146
|
<SelectField
|
|
118
|
-
label="
|
|
147
|
+
label="Tipo de pessoa"
|
|
119
148
|
placeholder="Selecione"
|
|
120
|
-
value={
|
|
121
|
-
onChange={(value) =>
|
|
149
|
+
value={personType}
|
|
150
|
+
onChange={(value) => {
|
|
151
|
+
setValue('personType', value as 'pf' | 'pj');
|
|
152
|
+
setValue('cpf', '');
|
|
153
|
+
setValue('cnpj', '');
|
|
154
|
+
}}
|
|
122
155
|
options={[
|
|
123
|
-
{ value: '
|
|
124
|
-
{ value: '
|
|
125
|
-
{ value: 'US', label: 'Estados Unidos' },
|
|
156
|
+
{ value: 'pf', label: 'Pessoa física' },
|
|
157
|
+
{ value: 'pj', label: 'Pessoa jurídica' },
|
|
126
158
|
]}
|
|
127
159
|
containerClassName="flex-1"
|
|
128
160
|
/>
|
|
129
161
|
<div className="flex-1">
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
162
|
+
{personType === 'pj' ? (
|
|
163
|
+
<FormField
|
|
164
|
+
label="CNPJ"
|
|
165
|
+
placeholder="__.___.___/____-__"
|
|
166
|
+
{...register('cnpj', {
|
|
167
|
+
onChange: (e) => {
|
|
168
|
+
setValue('cnpj', formatCNPJ(e.target.value));
|
|
169
|
+
},
|
|
170
|
+
})}
|
|
171
|
+
error={!!errors.cpf}
|
|
172
|
+
errorMessage={errors.cpf?.message}
|
|
173
|
+
/>
|
|
174
|
+
) : (
|
|
175
|
+
<FormField
|
|
176
|
+
label="CPF"
|
|
177
|
+
placeholder="___.___.___-__"
|
|
178
|
+
{...register('cpf', {
|
|
179
|
+
onChange: (e) => {
|
|
180
|
+
setValue('cpf', formatCPF(e.target.value));
|
|
181
|
+
},
|
|
182
|
+
})}
|
|
183
|
+
error={!!errors.cpf}
|
|
184
|
+
errorMessage={errors.cpf?.message}
|
|
185
|
+
/>
|
|
186
|
+
)}
|
|
142
187
|
</div>
|
|
143
188
|
</div>
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
type BillingFormFieldsProps = {
|
|
194
|
+
readonly form: UseFormReturn<CardFormData>;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export function BillingFormFields({ form }: BillingFormFieldsProps) {
|
|
198
|
+
const {
|
|
199
|
+
register,
|
|
200
|
+
setValue,
|
|
201
|
+
formState: { errors },
|
|
202
|
+
} = form;
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<div className="flex flex-col gap-5">
|
|
206
|
+
<FormField
|
|
207
|
+
label="Nome completo"
|
|
208
|
+
placeholder="Digite aqui"
|
|
209
|
+
{...register('fullName')}
|
|
210
|
+
error={!!errors.fullName}
|
|
211
|
+
errorMessage={errors.fullName?.message}
|
|
212
|
+
/>
|
|
144
213
|
|
|
145
214
|
<FormField
|
|
146
|
-
label="
|
|
147
|
-
placeholder="___
|
|
148
|
-
{...register('
|
|
215
|
+
label="CEP"
|
|
216
|
+
placeholder="_____-___"
|
|
217
|
+
{...register('cep', {
|
|
149
218
|
onChange: (e) => {
|
|
150
|
-
setValue('
|
|
219
|
+
setValue('cep', formatPostalCode(e.target.value));
|
|
151
220
|
},
|
|
152
221
|
})}
|
|
153
|
-
error={!!errors.
|
|
154
|
-
errorMessage={errors.
|
|
222
|
+
error={!!errors.cep}
|
|
223
|
+
errorMessage={errors.cep?.message}
|
|
224
|
+
/>
|
|
225
|
+
|
|
226
|
+
<div className="flex gap-4">
|
|
227
|
+
<div className="flex-[2]">
|
|
228
|
+
<FormField
|
|
229
|
+
label="Endereço"
|
|
230
|
+
placeholder=""
|
|
231
|
+
{...register('street')}
|
|
232
|
+
error={!!errors.street}
|
|
233
|
+
errorMessage={errors.street?.message}
|
|
234
|
+
/>
|
|
235
|
+
</div>
|
|
236
|
+
<div className="flex-1">
|
|
237
|
+
<FormField
|
|
238
|
+
label="Número"
|
|
239
|
+
placeholder=""
|
|
240
|
+
{...register('streetNumber')}
|
|
241
|
+
error={!!errors.streetNumber}
|
|
242
|
+
errorMessage={errors.streetNumber?.message}
|
|
243
|
+
/>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<div className="flex gap-4">
|
|
248
|
+
<div className="flex-1">
|
|
249
|
+
<FormField
|
|
250
|
+
label="Cidade"
|
|
251
|
+
placeholder=""
|
|
252
|
+
{...register('city')}
|
|
253
|
+
error={!!errors.city}
|
|
254
|
+
errorMessage={errors.city?.message}
|
|
255
|
+
/>
|
|
256
|
+
</div>
|
|
257
|
+
<div className="flex-1">
|
|
258
|
+
<FormField
|
|
259
|
+
label="UF"
|
|
260
|
+
placeholder=""
|
|
261
|
+
{...register('state')}
|
|
262
|
+
error={!!errors.state}
|
|
263
|
+
errorMessage={errors.state?.message}
|
|
264
|
+
/>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<FormField
|
|
269
|
+
label="Complemento"
|
|
270
|
+
optional
|
|
271
|
+
placeholder=""
|
|
272
|
+
{...register('complement')}
|
|
273
|
+
error={!!errors.complement}
|
|
274
|
+
errorMessage={errors.complement?.message}
|
|
155
275
|
/>
|
|
156
276
|
</div>
|
|
157
277
|
);
|
package/src/index.ts
CHANGED
|
@@ -312,8 +312,10 @@ export {
|
|
|
312
312
|
formatTimer,
|
|
313
313
|
formatFullName,
|
|
314
314
|
formatCPF,
|
|
315
|
+
formatCNPJ,
|
|
315
316
|
formatCardNumber,
|
|
316
317
|
} from "./utils/format/masks";
|
|
318
|
+
export { BR_STATE_OPTIONS } from "./utils/constants/br-states";
|
|
317
319
|
export type { TimezoneOption } from "./modules/accounts/services/timezone.service";
|
|
318
320
|
export {
|
|
319
321
|
buildLocaleOptions,
|
|
@@ -146,6 +146,16 @@ export interface UpdateAccountRequest {
|
|
|
146
146
|
currency?: string;
|
|
147
147
|
timezone?: string;
|
|
148
148
|
bussiness_type?: number;
|
|
149
|
+
financial_document_type?: number;
|
|
150
|
+
financial_document?: string;
|
|
151
|
+
financial_name?: string;
|
|
152
|
+
zipcode?: string;
|
|
153
|
+
address?: string;
|
|
154
|
+
address_number?: string;
|
|
155
|
+
address_complement?: string;
|
|
156
|
+
neighborhood?: string;
|
|
157
|
+
city?: string;
|
|
158
|
+
state?: string;
|
|
149
159
|
}
|
|
150
160
|
|
|
151
161
|
export interface UpdateAccountResponse {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const BR_STATE_OPTIONS = [
|
|
2
|
+
{ value: 'AC', label: 'AC' },
|
|
3
|
+
{ value: 'AL', label: 'AL' },
|
|
4
|
+
{ value: 'AP', label: 'AP' },
|
|
5
|
+
{ value: 'AM', label: 'AM' },
|
|
6
|
+
{ value: 'BA', label: 'BA' },
|
|
7
|
+
{ value: 'CE', label: 'CE' },
|
|
8
|
+
{ value: 'DF', label: 'DF' },
|
|
9
|
+
{ value: 'ES', label: 'ES' },
|
|
10
|
+
{ value: 'GO', label: 'GO' },
|
|
11
|
+
{ value: 'MA', label: 'MA' },
|
|
12
|
+
{ value: 'MT', label: 'MT' },
|
|
13
|
+
{ value: 'MS', label: 'MS' },
|
|
14
|
+
{ value: 'MG', label: 'MG' },
|
|
15
|
+
{ value: 'PA', label: 'PA' },
|
|
16
|
+
{ value: 'PB', label: 'PB' },
|
|
17
|
+
{ value: 'PR', label: 'PR' },
|
|
18
|
+
{ value: 'PE', label: 'PE' },
|
|
19
|
+
{ value: 'PI', label: 'PI' },
|
|
20
|
+
{ value: 'RJ', label: 'RJ' },
|
|
21
|
+
{ value: 'RN', label: 'RN' },
|
|
22
|
+
{ value: 'RS', label: 'RS' },
|
|
23
|
+
{ value: 'RO', label: 'RO' },
|
|
24
|
+
{ value: 'RR', label: 'RR' },
|
|
25
|
+
{ value: 'SC', label: 'SC' },
|
|
26
|
+
{ value: 'SP', label: 'SP' },
|
|
27
|
+
{ value: 'SE', label: 'SE' },
|
|
28
|
+
{ value: 'TO', label: 'TO' },
|
|
29
|
+
];
|
|
@@ -32,6 +32,17 @@ export function formatPostalCode(value: string): string {
|
|
|
32
32
|
return `${numbers.slice(0, 5)}-${numbers.slice(5, 8)}`;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
export function formatCNPJ(value: string): string {
|
|
36
|
+
const numbers = value.replace(/\D/g, '');
|
|
37
|
+
if (numbers.length <= 2) return numbers;
|
|
38
|
+
if (numbers.length <= 5) return `${numbers.slice(0, 2)}.${numbers.slice(2)}`;
|
|
39
|
+
if (numbers.length <= 8)
|
|
40
|
+
return `${numbers.slice(0, 2)}.${numbers.slice(2, 5)}.${numbers.slice(5)}`;
|
|
41
|
+
if (numbers.length <= 12)
|
|
42
|
+
return `${numbers.slice(0, 2)}.${numbers.slice(2, 5)}.${numbers.slice(5, 8)}/${numbers.slice(8)}`;
|
|
43
|
+
return `${numbers.slice(0, 2)}.${numbers.slice(2, 5)}.${numbers.slice(5, 8)}/${numbers.slice(8, 12)}-${numbers.slice(12, 14)}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
export function formatPhone(value: string): string {
|
|
36
47
|
const numbers = value.replace(/\D/g, '').substring(0, 11);
|
|
37
48
|
if (numbers.length <= 2) return numbers;
|