herald-exchange-glide-widget 1.0.0
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/.babelrc +3 -0
- package/Readme.md +116 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +24 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +58 -0
- package/rollup.config.js +90 -0
- package/src/assets/css/style.module.css +1352 -0
- package/src/assets/icons-one.png +0 -0
- package/src/assets/swap.svg +8 -0
- package/src/components/ButtonStepper.tsx +143 -0
- package/src/components/CommonCenterLoader.tsx +118 -0
- package/src/components/CustomeSelect.tsx +179 -0
- package/src/components/DotLoader.tsx +8 -0
- package/src/components/SellAdminCryptoAccount.tsx +604 -0
- package/src/components/SellField.tsx +705 -0
- package/src/components/WidgetBankDetails.tsx +592 -0
- package/src/components/WidgetComponent.tsx +42 -0
- package/src/components/WidgetContent.tsx +36 -0
- package/src/components/WidgetSuccesDetails.tsx +122 -0
- package/src/components/api.ts +59 -0
- package/src/components/api.tsx +61 -0
- package/src/components/chains.ts +319 -0
- package/src/components/images.d.ts +5 -0
- package/src/components/loader.tsx +12 -0
- package/src/components/style.module.css.d.ts +4 -0
- package/src/components/toast.tsx +43 -0
- package/src/components/types.ts +237 -0
- package/src/components/utils.ts +17 -0
- package/src/components/utils.tsx +10 -0
- package/src/hooks/toastProvider.tsx +63 -0
- package/src/hooks/useSocketExchange.tsx +48 -0
- package/src/index.ts +3 -0
- package/tsconfig.json +118 -0
@@ -0,0 +1,592 @@
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
2
|
+
import CustomSelect from "./CustomeSelect";
|
3
|
+
import { useToast } from "../hooks/toastProvider";
|
4
|
+
import { handleApiCall } from "./api";
|
5
|
+
import type { tokenSellDataType } from "./SellField";
|
6
|
+
import type { BankAccountsAPIResponse, CustomOption, ServiceBankAPiResponse } from "./types";
|
7
|
+
import CommonCenterLoader from "./CommonCenterLoader";
|
8
|
+
import { Spinner } from "./loader";
|
9
|
+
import { getBaseUrl } from "./utils";
|
10
|
+
|
11
|
+
const accountTypeOptions = [
|
12
|
+
{
|
13
|
+
label: "SWIFT",
|
14
|
+
currency: "USD",
|
15
|
+
},
|
16
|
+
{
|
17
|
+
label: "SEPA",
|
18
|
+
currency: "EUR",
|
19
|
+
},
|
20
|
+
{ label: "Local", currency: "USD" },
|
21
|
+
];
|
22
|
+
|
23
|
+
type WidgetBankDetailsProps = {
|
24
|
+
setStep: (step: number) => void;
|
25
|
+
data: tokenSellDataType;
|
26
|
+
apiKey: string;
|
27
|
+
clientReferenceID: string;
|
28
|
+
setTokenSellData: (data: any) => void;
|
29
|
+
css: any;
|
30
|
+
mode: string;
|
31
|
+
};
|
32
|
+
const WidgetBankDetails = ({
|
33
|
+
setStep,
|
34
|
+
data,
|
35
|
+
apiKey,
|
36
|
+
clientReferenceID,
|
37
|
+
setTokenSellData,
|
38
|
+
mode,
|
39
|
+
css,
|
40
|
+
}: WidgetBankDetailsProps) => {
|
41
|
+
const { addToast } = useToast();
|
42
|
+
|
43
|
+
// Select beneficiary
|
44
|
+
const [beneficiaryOptions, setBeneficiaryOptions] = useState<CustomOption[] | []>([]);
|
45
|
+
const [selectedBeneficiary, setSelectedBeneficiary] = useState<CustomOption | null>(null);
|
46
|
+
const [bankOptions, setBankOptions] = useState<CustomOption[] | []>([]);
|
47
|
+
const [isFetchingBeneficiary, setIsFetchingBeneficiary] = useState(true);
|
48
|
+
const [addingBankAccount, setAddingBankAccount] = useState(false);
|
49
|
+
useEffect(() => {
|
50
|
+
fetchbeneficiaryOptions();
|
51
|
+
}, []);
|
52
|
+
|
53
|
+
useEffect(() => {
|
54
|
+
if (data?.selectedBeneficiary && beneficiaryOptions?.length && !selectedBeneficiary) {
|
55
|
+
if (data?.selectedBeneficiary) {
|
56
|
+
const beneficiary = beneficiaryOptions?.find(
|
57
|
+
(item) => item?.value === data?.selectedBeneficiary
|
58
|
+
);
|
59
|
+
if (beneficiary) setSelectedBeneficiary(beneficiary);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}, [data, beneficiaryOptions]);
|
63
|
+
|
64
|
+
const fetchbeneficiaryOptions = () => {
|
65
|
+
const baseUrl = getBaseUrl(mode);
|
66
|
+
handleApiCall({
|
67
|
+
url: `${baseUrl}/api/bank_accounts`,
|
68
|
+
headers: {
|
69
|
+
"Content-Type": "application/json",
|
70
|
+
"X-API-KEY": apiKey,
|
71
|
+
"User-Id": clientReferenceID,
|
72
|
+
},
|
73
|
+
onSuccess: (result: BankAccountsAPIResponse) => {
|
74
|
+
if (result?.success) {
|
75
|
+
const options = result?.data?.bank_accounts
|
76
|
+
?.filter((item) => item?.currency === data?.selectedFiat)
|
77
|
+
?.map((item) => {
|
78
|
+
return {
|
79
|
+
label: `${item?.bank_account?.bank_name} - ${
|
80
|
+
item?.bank_account?.account_number || item?.bank_account?.iban
|
81
|
+
}`,
|
82
|
+
value: item?.unique_id,
|
83
|
+
};
|
84
|
+
});
|
85
|
+
setBeneficiaryOptions(options?.[0] ? [options?.[0]] : []);
|
86
|
+
setIsFetchingBeneficiary(false);
|
87
|
+
}
|
88
|
+
},
|
89
|
+
onError: () => {
|
90
|
+
addToast("Error fetching Beneficiaries", "error");
|
91
|
+
setIsFetchingBeneficiary(false);
|
92
|
+
},
|
93
|
+
});
|
94
|
+
};
|
95
|
+
|
96
|
+
const handleSelectBeneficiary = (values: CustomOption | null) => {
|
97
|
+
setSelectedBeneficiary(values);
|
98
|
+
setTokenSellData({ ...data, selectedBeneficiary: values?.value });
|
99
|
+
};
|
100
|
+
|
101
|
+
const handleContinueWithSelectedBeneficiary = () => {
|
102
|
+
if (data?.selectedBeneficiary) {
|
103
|
+
setStep(3);
|
104
|
+
} else {
|
105
|
+
addToast("Please select a beneficiary", "error");
|
106
|
+
}
|
107
|
+
};
|
108
|
+
|
109
|
+
// Add new beneficiary
|
110
|
+
|
111
|
+
const [formState, setFormState] = useState({
|
112
|
+
type: data?.selectedFiat === "EUR" ? "SEPA" : "SWIFT",
|
113
|
+
currency: data?.selectedFiat || "USD",
|
114
|
+
bank_name: "",
|
115
|
+
account_number: "",
|
116
|
+
route_number: "",
|
117
|
+
swift_code: "",
|
118
|
+
iban: "",
|
119
|
+
service_bank: "",
|
120
|
+
});
|
121
|
+
|
122
|
+
const [formErrors, setFormErrors] = useState({
|
123
|
+
bank_name: "",
|
124
|
+
account_number: "",
|
125
|
+
route_number: "",
|
126
|
+
swift_code: "",
|
127
|
+
iban: "",
|
128
|
+
service_bank: "",
|
129
|
+
});
|
130
|
+
|
131
|
+
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
132
|
+
const { name, value } = e.target;
|
133
|
+
const limitedValue = name === "bank_name" ? value?.slice(0, 100) : value?.trim()?.slice(0, 100);
|
134
|
+
let error = "";
|
135
|
+
|
136
|
+
// Validation
|
137
|
+
if (!value) {
|
138
|
+
error = "Field is Required";
|
139
|
+
} else if (name === "bank_name") {
|
140
|
+
const isAlpha = /^[A-Za-z\s]+$/.test(limitedValue);
|
141
|
+
if (!isAlpha) {
|
142
|
+
error = "Enter only alphabets";
|
143
|
+
}
|
144
|
+
} else {
|
145
|
+
const isAlphanumeric = /^[A-Za-z0-9\s]+$/.test(limitedValue);
|
146
|
+
if (!isAlphanumeric) {
|
147
|
+
error = "Enter only alphanumeric";
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
if (error) {
|
152
|
+
// Set errors (preserve other errors)
|
153
|
+
setFormErrors((prevErrors) => ({
|
154
|
+
...prevErrors,
|
155
|
+
[name]: error,
|
156
|
+
}));
|
157
|
+
} else {
|
158
|
+
// remove errors
|
159
|
+
const errors: any = { ...formErrors };
|
160
|
+
delete errors[name];
|
161
|
+
|
162
|
+
setFormErrors(errors);
|
163
|
+
}
|
164
|
+
// Set state
|
165
|
+
setFormState((prevState) => ({
|
166
|
+
...prevState,
|
167
|
+
[name]: limitedValue,
|
168
|
+
}));
|
169
|
+
};
|
170
|
+
|
171
|
+
const handleSelectBankOption = (values: CustomOption | null) => {
|
172
|
+
setFormState({
|
173
|
+
...formState,
|
174
|
+
service_bank: values?.value || "",
|
175
|
+
});
|
176
|
+
const errors: any = { ...formErrors };
|
177
|
+
delete errors.service_bank;
|
178
|
+
setFormErrors({ ...errors });
|
179
|
+
};
|
180
|
+
|
181
|
+
const handleSelectTypeOfAccount = (e: React.ChangeEvent<HTMLInputElement>) => {
|
182
|
+
if (e.target?.value === "Local") {
|
183
|
+
fetchBankOptions();
|
184
|
+
}
|
185
|
+
setFormState({
|
186
|
+
...formState,
|
187
|
+
type: e.target?.value,
|
188
|
+
});
|
189
|
+
setFormErrors({
|
190
|
+
bank_name: "",
|
191
|
+
account_number: "",
|
192
|
+
route_number: "",
|
193
|
+
swift_code: "",
|
194
|
+
iban: "",
|
195
|
+
service_bank: "",
|
196
|
+
});
|
197
|
+
};
|
198
|
+
|
199
|
+
const fetchBankOptions = () => {
|
200
|
+
const baseUrl = getBaseUrl(mode);
|
201
|
+
handleApiCall({
|
202
|
+
url: `${baseUrl}/api/service_banks`,
|
203
|
+
headers: {
|
204
|
+
"Content-Type": "application/json",
|
205
|
+
"X-API-KEY": apiKey,
|
206
|
+
"User-Id": clientReferenceID,
|
207
|
+
},
|
208
|
+
onSuccess: (result: ServiceBankAPiResponse) => {
|
209
|
+
if (result?.success) {
|
210
|
+
const options = result?.data?.service_banks?.map((item) => {
|
211
|
+
return {
|
212
|
+
label: item?.bank_name,
|
213
|
+
value: item?.service_bank,
|
214
|
+
};
|
215
|
+
});
|
216
|
+
setBankOptions(options);
|
217
|
+
}
|
218
|
+
},
|
219
|
+
onError: () => {
|
220
|
+
addToast("Error fetching Bank Accounts", "error");
|
221
|
+
},
|
222
|
+
});
|
223
|
+
};
|
224
|
+
|
225
|
+
const handleAddbeneficiary = () => {
|
226
|
+
const baseUrl = getBaseUrl(mode);
|
227
|
+
const error: any = {};
|
228
|
+
const formData = new FormData();
|
229
|
+
setAddingBankAccount(true);
|
230
|
+
|
231
|
+
formData.append("currency", formState?.currency);
|
232
|
+
formData.append("type", formState?.type?.toLowerCase());
|
233
|
+
|
234
|
+
switch (formState.type) {
|
235
|
+
case "SWIFT":
|
236
|
+
if (!formState?.bank_name) error.bank_name = "Field is required";
|
237
|
+
if (!formState?.route_number) error.route_number = "Field is required";
|
238
|
+
if (!formState?.swift_code) error.swift_code = "Field is required";
|
239
|
+
if (!formState?.account_number) error.account_number = "Field is required";
|
240
|
+
formData.append("bank_name", formState?.bank_name);
|
241
|
+
formData.append("route_number", formState?.route_number);
|
242
|
+
formData.append("swift_code", formState?.swift_code);
|
243
|
+
formData.append("account_number", formState?.account_number);
|
244
|
+
|
245
|
+
break;
|
246
|
+
case "Local":
|
247
|
+
if (!formState?.service_bank) error.service_bank = "Field is required";
|
248
|
+
if (!formState?.route_number) error.route_number = "Field is required";
|
249
|
+
if (!formState?.account_number) error.account_number = "Field is required";
|
250
|
+
formData.append("service_bank", formState?.service_bank);
|
251
|
+
formData.append("route_number", formState?.route_number);
|
252
|
+
formData.append("account_number", formState?.account_number);
|
253
|
+
break;
|
254
|
+
|
255
|
+
case "SEPA":
|
256
|
+
if (!formState?.bank_name) error.bank_name = "Field is required";
|
257
|
+
if (!formState?.iban) error.iban = "Field is required";
|
258
|
+
formData.append("bank_name", formState?.bank_name);
|
259
|
+
formData.append("iban", formState?.iban);
|
260
|
+
break;
|
261
|
+
|
262
|
+
default:
|
263
|
+
break;
|
264
|
+
}
|
265
|
+
|
266
|
+
if (Object.keys(error)?.length > 0) {
|
267
|
+
setFormErrors(error);
|
268
|
+
addToast("Fill all fields", "error");
|
269
|
+
setAddingBankAccount(false);
|
270
|
+
return;
|
271
|
+
}
|
272
|
+
|
273
|
+
handleApiCall({
|
274
|
+
url: `${baseUrl}/api/bank_accounts`,
|
275
|
+
method: "POST",
|
276
|
+
headers: {
|
277
|
+
"X-API-KEY": apiKey,
|
278
|
+
"User-Id": clientReferenceID,
|
279
|
+
},
|
280
|
+
body: formData,
|
281
|
+
onSuccess: (result: any) => {
|
282
|
+
if (result?.success) {
|
283
|
+
setBeneficiaryOptions([
|
284
|
+
...beneficiaryOptions,
|
285
|
+
{
|
286
|
+
label: `${result?.data?.bank_account?.bank_name} - ${
|
287
|
+
result?.data?.bank_account?.account_number ||
|
288
|
+
result?.data?.bank_account?.bank_account?.iban
|
289
|
+
}`,
|
290
|
+
value: result?.data?.bank_account?.unique_id,
|
291
|
+
},
|
292
|
+
]);
|
293
|
+
|
294
|
+
setSelectedBeneficiary({
|
295
|
+
label: `${result?.data?.bank_account?.bank_name} - ${
|
296
|
+
result?.data?.bank_account?.account_number ||
|
297
|
+
result?.data?.bank_account?.bank_account?.iban
|
298
|
+
}`,
|
299
|
+
value: result?.data?.bank_account?.unique_id,
|
300
|
+
});
|
301
|
+
setTokenSellData({ ...data, selectedBeneficiary: result?.data?.bank_account?.unique_id });
|
302
|
+
setStep(3);
|
303
|
+
} else {
|
304
|
+
addToast(`Error Adding Bank Account : ${result?.message}`, "error");
|
305
|
+
}
|
306
|
+
setAddingBankAccount(false);
|
307
|
+
},
|
308
|
+
onError: (error: any) => {
|
309
|
+
addToast(`Error Adding Bank Account : ${error?.message}`, "error");
|
310
|
+
setAddingBankAccount(false);
|
311
|
+
},
|
312
|
+
});
|
313
|
+
};
|
314
|
+
|
315
|
+
const fetchMoreBanks = (value: string) => {
|
316
|
+
const baseUrl = getBaseUrl(mode);
|
317
|
+
|
318
|
+
handleApiCall({
|
319
|
+
url: `${baseUrl}/api/service_banks?search_key=${value}`,
|
320
|
+
headers: {
|
321
|
+
"Content-Type": "application/json",
|
322
|
+
"X-API-KEY": apiKey,
|
323
|
+
"User-Id": clientReferenceID,
|
324
|
+
},
|
325
|
+
onSuccess: (result: ServiceBankAPiResponse) => {
|
326
|
+
if (result?.success) {
|
327
|
+
const options = result?.data?.service_banks?.map((item) => {
|
328
|
+
return {
|
329
|
+
label: item?.bank_name,
|
330
|
+
value: item?.service_bank,
|
331
|
+
};
|
332
|
+
});
|
333
|
+
setBankOptions(options);
|
334
|
+
}
|
335
|
+
},
|
336
|
+
onError: () => {
|
337
|
+
addToast("Error fetching Bank Accounts", "error");
|
338
|
+
},
|
339
|
+
});
|
340
|
+
};
|
341
|
+
|
342
|
+
return (
|
343
|
+
<>
|
344
|
+
<div className={css.gilde_bank_frame}>
|
345
|
+
<div className={css.gilde_bank_head}>
|
346
|
+
<div style={{ cursor: "pointer" }} onClick={() => setStep(1)}>
|
347
|
+
<svg
|
348
|
+
xmlns="http://www.w3.org/2000/svg"
|
349
|
+
xmlSpace="preserve"
|
350
|
+
width="18"
|
351
|
+
height="18"
|
352
|
+
viewBox="0 0 240.823 240.823"
|
353
|
+
>
|
354
|
+
<path
|
355
|
+
d="M57.633 129.007 165.93 237.268c4.752 4.74 12.451 4.74 17.215 0 4.752-4.74 4.752-12.439 0-17.179l-99.707-99.671 99.695-99.671c4.752-4.74 4.752-12.439 0-17.191-4.752-4.74-12.463-4.74-17.215 0L57.621 111.816c-4.679 4.691-4.679 12.511.012 17.191"
|
356
|
+
data-original="#000000"
|
357
|
+
></path>
|
358
|
+
</svg>
|
359
|
+
</div>
|
360
|
+
<div className={css.bank_titles}>Bank Details</div>
|
361
|
+
</div>
|
362
|
+
<div className={css.gilde_bank_tabs_frame}>
|
363
|
+
{isFetchingBeneficiary ? (
|
364
|
+
<CommonCenterLoader css={css} />
|
365
|
+
) : (
|
366
|
+
<div className={css.gilde_bank_tabs_content}>
|
367
|
+
{beneficiaryOptions?.length > 0 ? (
|
368
|
+
<div className={css.gilde_bank_exist_box}>
|
369
|
+
<div className={css.gilde_bank_exist_feilds_frame}>
|
370
|
+
<div className={css.gilde_bank_exist_label}>Select Bank</div>
|
371
|
+
<div className={css.gilde_bank_exist_feilds}>
|
372
|
+
<CustomSelect
|
373
|
+
options={beneficiaryOptions}
|
374
|
+
onChange={handleSelectBeneficiary}
|
375
|
+
isClearable={true}
|
376
|
+
placeholder={isFetchingBeneficiary ? "Loading..." : "Select Beneficiary"}
|
377
|
+
value={selectedBeneficiary}
|
378
|
+
isDisabled={beneficiaryOptions?.length <= 0}
|
379
|
+
/>
|
380
|
+
</div>
|
381
|
+
</div>
|
382
|
+
|
383
|
+
<div className={css.gilde_ramp_action}>
|
384
|
+
<button
|
385
|
+
className={` ${css.action_btn} ${css.primary} `}
|
386
|
+
onClick={handleContinueWithSelectedBeneficiary}
|
387
|
+
>
|
388
|
+
Continue
|
389
|
+
</button>
|
390
|
+
</div>
|
391
|
+
</div>
|
392
|
+
) : (
|
393
|
+
<div className={css.off_gilde_new_box}>
|
394
|
+
<div className={css.off_gilde_check_wrap}>
|
395
|
+
{accountTypeOptions.map((item) =>
|
396
|
+
data?.selectedFiat === item.currency ? (
|
397
|
+
<div className={css.off_form_check} key={item.label}>
|
398
|
+
<label className={css.off_form_check_label} htmlFor={item.label}>
|
399
|
+
<input
|
400
|
+
className={css.off_form_check_input}
|
401
|
+
type="radio"
|
402
|
+
name="AccountType"
|
403
|
+
value={item.label}
|
404
|
+
id={item.label}
|
405
|
+
onChange={(e) => handleSelectTypeOfAccount(e)}
|
406
|
+
/>
|
407
|
+
<div className={css.off_currency_option}>
|
408
|
+
<h3>{item.label}</h3>
|
409
|
+
<svg
|
410
|
+
xmlns="http://www.w3.org/2000/svg"
|
411
|
+
width="20"
|
412
|
+
height="20"
|
413
|
+
viewBox="0 0 408.576 408.576"
|
414
|
+
>
|
415
|
+
<g>
|
416
|
+
<path
|
417
|
+
d="M204.288 0C91.648 0 0 91.648 0 204.288s91.648 204.288 204.288 204.288 204.288-91.648 204.288-204.288S316.928 0 204.288 0zm114.176 150.528-130.56 129.536c-7.68 7.68-19.968 8.192-28.16.512L90.624 217.6c-8.192-7.68-8.704-20.48-1.536-28.672 7.68-8.192 20.48-8.704 28.672-1.024l54.784 50.176L289.28 121.344c8.192-8.192 20.992-8.192 29.184 0s8.192 20.992 0 29.184z"
|
418
|
+
fill={
|
419
|
+
formState?.type === item.label
|
420
|
+
? "var(--primary-color-des)"
|
421
|
+
: "#efefef"
|
422
|
+
}
|
423
|
+
></path>
|
424
|
+
</g>
|
425
|
+
</svg>
|
426
|
+
</div>
|
427
|
+
</label>
|
428
|
+
</div>
|
429
|
+
) : (
|
430
|
+
<></>
|
431
|
+
)
|
432
|
+
)}
|
433
|
+
</div>
|
434
|
+
|
435
|
+
{formState.type === "Local" ? (
|
436
|
+
<div className={css.off_gilde_new_bank_box}>
|
437
|
+
<div className={css.off_gilde_new_bank_label}>
|
438
|
+
Bank Name <span className={css.required}>*</span>
|
439
|
+
</div>
|
440
|
+
<div className={css.off_gilde_new_bank_fields}>
|
441
|
+
<CustomSelect
|
442
|
+
options={bankOptions}
|
443
|
+
isClearable={true}
|
444
|
+
placeholder="Select Bank"
|
445
|
+
value={
|
446
|
+
formState?.service_bank
|
447
|
+
? bankOptions?.find(
|
448
|
+
(option) => option?.value === formState?.service_bank
|
449
|
+
)
|
450
|
+
: null
|
451
|
+
}
|
452
|
+
isSearchable={true}
|
453
|
+
onChange={handleSelectBankOption}
|
454
|
+
onInputChange={(inputValue: string, { action }: { action: string }) => {
|
455
|
+
if (action !== css.input_control) return;
|
456
|
+
|
457
|
+
if (inputValue?.length > 0) {
|
458
|
+
fetchMoreBanks(inputValue);
|
459
|
+
} else {
|
460
|
+
fetchBankOptions();
|
461
|
+
}
|
462
|
+
}}
|
463
|
+
/>
|
464
|
+
</div>
|
465
|
+
{formErrors?.service_bank && (
|
466
|
+
<span className={css.input_error}>{formErrors?.service_bank}</span>
|
467
|
+
)}
|
468
|
+
</div>
|
469
|
+
) : (
|
470
|
+
<div className={css.off_gilde_new_bank_box}>
|
471
|
+
<div className={css.off_gilde_new_bank_label}>
|
472
|
+
Bank Name <span className={css.required}>*</span>
|
473
|
+
</div>
|
474
|
+
<div className={css.off_gilde_new_bank_fields}>
|
475
|
+
<input
|
476
|
+
type="text"
|
477
|
+
value={formState.bank_name}
|
478
|
+
className={css.input_control}
|
479
|
+
placeholder="Enter Bank Name"
|
480
|
+
onChange={handleInputChange}
|
481
|
+
name="bank_name"
|
482
|
+
/>
|
483
|
+
</div>
|
484
|
+
{formErrors?.bank_name && (
|
485
|
+
<span className={css.input_error}>{formErrors?.bank_name}</span>
|
486
|
+
)}
|
487
|
+
</div>
|
488
|
+
)}
|
489
|
+
|
490
|
+
{formState.type === "SWIFT" || formState.type === "Local" ? (
|
491
|
+
<div className={css.off_gilde_new_bank_box}>
|
492
|
+
<div className={css.off_gilde_new_bank_label}>
|
493
|
+
Account Number <span className={css.required}>*</span>
|
494
|
+
</div>
|
495
|
+
<div className={css.off_gilde_new_bank_fields}>
|
496
|
+
<input
|
497
|
+
type="text"
|
498
|
+
value={formState.account_number}
|
499
|
+
className={css.input_control}
|
500
|
+
placeholder="Enter Account Number"
|
501
|
+
onChange={handleInputChange}
|
502
|
+
name="account_number"
|
503
|
+
/>
|
504
|
+
</div>
|
505
|
+
{formErrors?.account_number && (
|
506
|
+
<span className={css.input_error}>{formErrors?.account_number}</span>
|
507
|
+
)}
|
508
|
+
</div>
|
509
|
+
) : null}
|
510
|
+
{formState.type === "SWIFT" || formState.type === "Local" ? (
|
511
|
+
<div className={css.off_gilde_new_bank_box}>
|
512
|
+
<div className={css.off_gilde_new_bank_label}>
|
513
|
+
Route Number <span className={css.required}>*</span>
|
514
|
+
</div>
|
515
|
+
<div className={css.off_gilde_new_bank_fields}>
|
516
|
+
<input
|
517
|
+
type="text"
|
518
|
+
value={formState.route_number}
|
519
|
+
className={css.input_control}
|
520
|
+
placeholder="Enter Route Number"
|
521
|
+
onChange={handleInputChange}
|
522
|
+
name="route_number"
|
523
|
+
/>
|
524
|
+
</div>
|
525
|
+
{formErrors?.route_number && (
|
526
|
+
<span className={css.input_error}>{formErrors?.route_number} </span>
|
527
|
+
)}
|
528
|
+
</div>
|
529
|
+
) : null}
|
530
|
+
|
531
|
+
{formState.type === "SWIFT" && (
|
532
|
+
<div className={css.off_gilde_new_bank_box}>
|
533
|
+
<div className={css.off_gilde_new_bank_label}>
|
534
|
+
SWIFT Code <span className={css.required}>*</span>
|
535
|
+
</div>
|
536
|
+
<div className={css.off_gilde_new_bank_fields}>
|
537
|
+
<input
|
538
|
+
type="text"
|
539
|
+
value={formState.swift_code}
|
540
|
+
className={css.input_control}
|
541
|
+
placeholder="Enter SWIFT Code"
|
542
|
+
onChange={handleInputChange}
|
543
|
+
name="swift_code"
|
544
|
+
/>
|
545
|
+
</div>
|
546
|
+
{formErrors?.swift_code && (
|
547
|
+
<span className={css.input_error}>{formErrors?.swift_code}</span>
|
548
|
+
)}
|
549
|
+
</div>
|
550
|
+
)}
|
551
|
+
|
552
|
+
{formState.type === "SEPA" && (
|
553
|
+
<div className={css.off_gilde_new_bank_box}>
|
554
|
+
<div className={css.off_gilde_new_bank_label}>
|
555
|
+
IBAN <span className={css.required}>*</span>
|
556
|
+
</div>
|
557
|
+
<div className={css.off_gilde_new_bank_fields}>
|
558
|
+
<input
|
559
|
+
type="text"
|
560
|
+
value={formState.iban}
|
561
|
+
className={css.input_control}
|
562
|
+
placeholder="Enter IBAN"
|
563
|
+
onChange={handleInputChange}
|
564
|
+
name="iban"
|
565
|
+
/>
|
566
|
+
</div>
|
567
|
+
{formErrors?.iban && (
|
568
|
+
<span className={css.input_error}>{formErrors?.iban}</span>
|
569
|
+
)}
|
570
|
+
</div>
|
571
|
+
)}
|
572
|
+
|
573
|
+
<div className={css.gilde_ramp_action}>
|
574
|
+
<button
|
575
|
+
className={` ${css.action_btn} ${css.primary} `}
|
576
|
+
onClick={handleAddbeneficiary}
|
577
|
+
disabled={addingBankAccount}
|
578
|
+
>
|
579
|
+
Continue {addingBankAccount && <Spinner />}
|
580
|
+
</button>
|
581
|
+
</div>
|
582
|
+
</div>
|
583
|
+
)}
|
584
|
+
</div>
|
585
|
+
)}
|
586
|
+
</div>
|
587
|
+
</div>
|
588
|
+
</>
|
589
|
+
);
|
590
|
+
};
|
591
|
+
|
592
|
+
export default WidgetBankDetails;
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import css from "../assets/css/style.module.css";
|
3
|
+
import WidgetContent from "./WidgetContent";
|
4
|
+
import { ToastProvider } from "../hooks/toastProvider";
|
5
|
+
import type { SellParamsType } from "./types";
|
6
|
+
|
7
|
+
// Props
|
8
|
+
type WidgetComponentProps = {
|
9
|
+
apiKey: string;
|
10
|
+
sellParameters: SellParamsType;
|
11
|
+
clientReferenceID: string;
|
12
|
+
mode?: "development" | "production";
|
13
|
+
};
|
14
|
+
|
15
|
+
const WidgetComponent = ({
|
16
|
+
apiKey,
|
17
|
+
sellParameters,
|
18
|
+
clientReferenceID,
|
19
|
+
mode = "development",
|
20
|
+
}: WidgetComponentProps) => {
|
21
|
+
return (
|
22
|
+
<div style={{ position: "relative" }} className={css.widget_component} id="widget-container">
|
23
|
+
<div className={css.gilde_widget_wrapped}>
|
24
|
+
<div className={css.gilde_widget_modal}>
|
25
|
+
<div className={css.gilde_widget_content}>
|
26
|
+
<ToastProvider>
|
27
|
+
<WidgetContent
|
28
|
+
sellParameters={sellParameters}
|
29
|
+
apiKey={apiKey}
|
30
|
+
clientReferenceID={clientReferenceID}
|
31
|
+
css={css}
|
32
|
+
mode={mode}
|
33
|
+
/>
|
34
|
+
</ToastProvider>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
);
|
40
|
+
};
|
41
|
+
|
42
|
+
export default WidgetComponent;
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import SellField from "./SellField";
|
3
|
+
import type { SellParamsType } from "./types";
|
4
|
+
// Props
|
5
|
+
type WidgetContentProps = {
|
6
|
+
apiKey: string;
|
7
|
+
sellParameters: SellParamsType;
|
8
|
+
clientReferenceID: string;
|
9
|
+
css: any;
|
10
|
+
mode: string;
|
11
|
+
};
|
12
|
+
|
13
|
+
const WidgetContent = ({
|
14
|
+
apiKey,
|
15
|
+
sellParameters,
|
16
|
+
clientReferenceID,
|
17
|
+
css,
|
18
|
+
mode,
|
19
|
+
}: WidgetContentProps) => {
|
20
|
+
// const [activeTab, setActiveTab] = useState("sell");
|
21
|
+
return (
|
22
|
+
<div className={css.gilde_tabs_wrapped}>
|
23
|
+
<div className={css.gilde_tabs_content}>
|
24
|
+
<SellField
|
25
|
+
apiKey={apiKey}
|
26
|
+
parameters={sellParameters}
|
27
|
+
clientReferenceID={clientReferenceID}
|
28
|
+
css={css}
|
29
|
+
mode={mode}
|
30
|
+
/>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
);
|
34
|
+
};
|
35
|
+
|
36
|
+
export default WidgetContent;
|