@akinon/pz-saved-card 1.101.0-rc.76 → 1.101.0-snapshot-ZERO-3615-20250924121313
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/CHANGELOG.md +1 -96
- package/package.json +1 -1
- package/src/components/agreement-and-submit.tsx +3 -15
- package/src/components/card-selection-section.tsx +1 -0
- package/src/components/installment-section.tsx +4 -2
- package/src/components/installments.tsx +4 -1
- package/src/index.tsx +1 -7
- package/src/redux/api.ts +7 -34
- package/src/redux/middleware.ts +5 -10
- package/src/redux/reducer.ts +2 -21
- package/src/types/index.ts +4 -50
- package/src/views/saved-card-option.tsx +2 -0
- package/src/components/card-form-section.tsx +0 -127
- package/src/views/iyzico-saved-card-option.tsx +0 -427
package/CHANGELOG.md
CHANGED
|
@@ -1,32 +1,6 @@
|
|
|
1
1
|
# @akinon/pz-saved-card
|
|
2
2
|
|
|
3
|
-
## 1.101.0-
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- 6bfbdc2: ZERO-3653: optimize saved card option
|
|
8
|
-
|
|
9
|
-
## 1.101.0-rc.75
|
|
10
|
-
|
|
11
|
-
### Minor Changes
|
|
12
|
-
|
|
13
|
-
- 9442cf0: ZERO-3653: make the register_consumer_card option optional
|
|
14
|
-
|
|
15
|
-
## 1.101.0-rc.74
|
|
16
|
-
|
|
17
|
-
## 1.101.0-rc.73
|
|
18
|
-
|
|
19
|
-
### Minor Changes
|
|
20
|
-
|
|
21
|
-
- 4ca44c7: ZERO-3634: add register_consumer_card
|
|
22
|
-
- d8be48fb: ZERO-3422: Update fetch method to use dynamic request method in wallet complete redirection middleware
|
|
23
|
-
- 16aff543: ZERO-3431: Add test script for redirect utility in package.json
|
|
24
|
-
- e974d8e8: ZERO-3406: Fix rc build
|
|
25
|
-
- 7eb51ca9: ZERO-3424 :Update package versions
|
|
26
|
-
- 7727ae55: ZERO-3073: Refactor basket page to use server-side data fetching and simplify component structure
|
|
27
|
-
- 8b1d24eb: ZERO-3422: Update fetch method to use dynamic request method in wallet complete redirection middleware
|
|
28
|
-
- 33377cfd: ZERO-3267: Refactor import statement for ROUTES in error-page component
|
|
29
|
-
- 5b50079: ZERO-3634: iyzico saved card
|
|
3
|
+
## 1.101.0-snapshot-ZERO-3615-20250924121313
|
|
30
4
|
|
|
31
5
|
## 1.100.0
|
|
32
6
|
|
|
@@ -52,83 +26,14 @@
|
|
|
52
26
|
|
|
53
27
|
## 1.91.0
|
|
54
28
|
|
|
55
|
-
> > > > > > > origin/ZERO-3418
|
|
56
|
-
|
|
57
29
|
## 1.90.0
|
|
58
30
|
|
|
59
31
|
## 1.89.0
|
|
60
32
|
|
|
61
33
|
### Minor Changes
|
|
62
34
|
|
|
63
|
-
- e974d8e: ZERO-3406: Fix rc build
|
|
64
|
-
- 7727ae55: ZERO-3073: Refactor basket page to use server-side data fetching and simplify component structure
|
|
65
|
-
- 33377cfd: ZERO-3267: Refactor import statement for ROUTES in error-page component
|
|
66
|
-
|
|
67
|
-
## 1.89.0-rc.21
|
|
68
|
-
|
|
69
|
-
### Minor Changes
|
|
70
|
-
|
|
71
|
-
- e974d8e: ZERO-3406: Fix rc build
|
|
72
|
-
|
|
73
|
-
## 1.89.0-rc.20
|
|
74
|
-
|
|
75
|
-
## 1.89.0-rc.19
|
|
76
|
-
|
|
77
|
-
## 1.89.0-rc.18
|
|
78
|
-
|
|
79
|
-
## 1.89.0-rc.17
|
|
80
|
-
|
|
81
|
-
## 1.89.0-rc.16
|
|
82
|
-
|
|
83
|
-
## 1.89.0-rc.15
|
|
84
|
-
|
|
85
|
-
## 1.89.0-rc.14
|
|
86
|
-
|
|
87
|
-
## 1.89.0-rc.13
|
|
88
|
-
|
|
89
|
-
## 1.89.0-rc.12
|
|
90
|
-
|
|
91
|
-
## 1.89.0-rc.11
|
|
92
|
-
|
|
93
|
-
## 1.89.0-rc.10
|
|
94
|
-
|
|
95
|
-
### Minor Changes
|
|
96
|
-
|
|
97
|
-
- 7727ae55: ZERO-3073: Refactor basket page to use server-side data fetching and simplify component structure
|
|
98
|
-
- 33377cfd: ZERO-3267: Refactor import statement for ROUTES in error-page component
|
|
99
|
-
- e2026ec: ZERO-3353: add missing test ids for e2e test
|
|
100
|
-
|
|
101
|
-
## 1.89.0-rc.9
|
|
102
|
-
|
|
103
|
-
### Minor Changes
|
|
104
|
-
|
|
105
|
-
- 7727ae55: ZERO-3073: Refactor basket page to use server-side data fetching and simplify component structure
|
|
106
|
-
- 33377cfd: ZERO-3267: Refactor import statement for ROUTES in error-page component
|
|
107
35
|
- e2026ec: ZERO-3353: add missing test ids for e2e test
|
|
108
36
|
|
|
109
|
-
## 1.89.0-rc.8
|
|
110
|
-
|
|
111
|
-
## 1.89.0-rc.7
|
|
112
|
-
|
|
113
|
-
## 1.89.0-rc.6
|
|
114
|
-
|
|
115
|
-
## 1.89.0-rc.5
|
|
116
|
-
|
|
117
|
-
## 1.89.0-rc.4
|
|
118
|
-
|
|
119
|
-
## 1.89.0-rc.3
|
|
120
|
-
|
|
121
|
-
## 1.89.0-rc.2
|
|
122
|
-
|
|
123
|
-
## 1.89.0-rc.1
|
|
124
|
-
|
|
125
|
-
## 1.89.0-rc.0
|
|
126
|
-
|
|
127
|
-
### Minor Changes
|
|
128
|
-
|
|
129
|
-
- 7727ae55: ZERO-3073: Refactor basket page to use server-side data fetching and simplify component structure
|
|
130
|
-
- 33377cf: ZERO-3267: Refactor import statement for ROUTES in error-page component
|
|
131
|
-
|
|
132
37
|
## 1.88.0
|
|
133
38
|
|
|
134
39
|
## 1.87.0
|
package/package.json
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { cloneElement } from 'react';
|
|
1
|
+
import React, { cloneElement } from 'react';
|
|
2
2
|
import { Button, Icon } from '@akinon/next/components';
|
|
3
|
-
import { AgreementAndSubmitProps } from '../types';
|
|
4
3
|
|
|
5
4
|
export const AgreementAndSubmit = ({
|
|
6
5
|
agreementCheckbox,
|
|
7
6
|
control,
|
|
8
7
|
errors,
|
|
9
|
-
buttonText
|
|
10
|
-
|
|
11
|
-
}: AgreementAndSubmitProps) => (
|
|
8
|
+
buttonText
|
|
9
|
+
}) => (
|
|
12
10
|
<div className="flex flex-col text-xs pb-4 px-4 sm:px-6">
|
|
13
11
|
{agreementCheckbox &&
|
|
14
12
|
cloneElement(agreementCheckbox, {
|
|
@@ -16,16 +14,6 @@ export const AgreementAndSubmit = ({
|
|
|
16
14
|
error: errors.agreement,
|
|
17
15
|
fieldId: 'agreement'
|
|
18
16
|
})}
|
|
19
|
-
{formError?.non_field_errors && (
|
|
20
|
-
<div className="w-full text-xs text-start px-1 mt-3 text-error">
|
|
21
|
-
{formError.non_field_errors}
|
|
22
|
-
</div>
|
|
23
|
-
)}
|
|
24
|
-
{formError?.status && (
|
|
25
|
-
<div className="w-full text-xs text-start px-1 mt-3 text-error">
|
|
26
|
-
{formError.status}
|
|
27
|
-
</div>
|
|
28
|
-
)}
|
|
29
17
|
<Button
|
|
30
18
|
type="submit"
|
|
31
19
|
className="group uppercase mt-4 inline-flex items-center justify-center"
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import SavedCardInstallments from './installments';
|
|
2
|
-
import
|
|
2
|
+
import React from 'react';
|
|
3
3
|
|
|
4
4
|
export const InstallmentSection = ({
|
|
5
5
|
title,
|
|
6
|
+
selectedCard,
|
|
6
7
|
installmentOptions,
|
|
7
8
|
translations,
|
|
8
9
|
errors
|
|
9
|
-
}
|
|
10
|
+
}) => (
|
|
10
11
|
<div className="border-solid border-gray-400 bg-white">
|
|
11
12
|
<div className="px-4 py-2">
|
|
12
13
|
<span className="text-black-800 text-lg font-medium">{title}</span>
|
|
13
14
|
</div>
|
|
14
15
|
<SavedCardInstallments
|
|
16
|
+
selectedCard={selectedCard}
|
|
15
17
|
installmentOptions={installmentOptions}
|
|
16
18
|
translations={translations}
|
|
17
19
|
error={errors}
|
|
@@ -12,12 +12,14 @@ const defaultTranslations = {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
type SavedCardInstallmentsProps = {
|
|
15
|
+
selectedCard: SavedCard;
|
|
15
16
|
installmentOptions: any[];
|
|
16
17
|
translations?: InstallmentTexts;
|
|
17
18
|
error: any;
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
const SavedCardInstallments = ({
|
|
22
|
+
selectedCard,
|
|
21
23
|
installmentOptions = [],
|
|
22
24
|
translations,
|
|
23
25
|
error
|
|
@@ -28,6 +30,7 @@ const SavedCardInstallments = ({
|
|
|
28
30
|
|
|
29
31
|
useEffect(() => {
|
|
30
32
|
if (
|
|
33
|
+
selectedCard &&
|
|
31
34
|
installmentOptions.length > 0 &&
|
|
32
35
|
installmentOptions[0]?.pk !== installmentOption
|
|
33
36
|
) {
|
|
@@ -37,7 +40,7 @@ const SavedCardInstallments = ({
|
|
|
37
40
|
});
|
|
38
41
|
setInstallmentOption(firstOptionPk);
|
|
39
42
|
}
|
|
40
|
-
}, [installmentOptions, installmentOption, setInstallment]);
|
|
43
|
+
}, [installmentOptions, installmentOption, setInstallment, selectedCard]);
|
|
41
44
|
|
|
42
45
|
if (installmentOptions.length === 0) {
|
|
43
46
|
return (
|
package/src/index.tsx
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import savedCardReducer from './redux/reducer';
|
|
2
2
|
import savedCardMiddleware from './redux/middleware';
|
|
3
3
|
import SavedCardOption from './views/saved-card-option';
|
|
4
|
-
import IyzicoSavedCardOption from './views/iyzico-saved-card-option';
|
|
5
4
|
|
|
6
|
-
export {
|
|
7
|
-
savedCardReducer,
|
|
8
|
-
savedCardMiddleware,
|
|
9
|
-
SavedCardOption,
|
|
10
|
-
IyzicoSavedCardOption
|
|
11
|
-
};
|
|
5
|
+
export { savedCardReducer, savedCardMiddleware, SavedCardOption };
|
package/src/redux/api.ts
CHANGED
|
@@ -21,49 +21,20 @@ interface GetResponse<T> {
|
|
|
21
21
|
results: T[];
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
type
|
|
24
|
+
type SetSavedCardRequest = {
|
|
25
25
|
card: SavedCard;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
type IyzicoSetSavedCardRequest = {
|
|
29
|
-
card: string;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
type SetSavedCardRequest =
|
|
33
|
-
| DefaultSetSavedCardRequest
|
|
34
|
-
| IyzicoSetSavedCardRequest;
|
|
35
|
-
|
|
36
28
|
type DeleteSavedCardRequest = number;
|
|
37
29
|
|
|
38
30
|
type SetInstallmentRequest = {
|
|
39
31
|
installment: string;
|
|
40
32
|
};
|
|
41
33
|
|
|
42
|
-
type
|
|
34
|
+
type CompleteSavedCardRequest = {
|
|
43
35
|
agreement: boolean;
|
|
44
36
|
};
|
|
45
37
|
|
|
46
|
-
type IyzicoCompleteSavedCardRequest =
|
|
47
|
-
| {
|
|
48
|
-
agreement: boolean;
|
|
49
|
-
register_consumer_card: boolean;
|
|
50
|
-
consumer_token: string;
|
|
51
|
-
card_token: string;
|
|
52
|
-
}
|
|
53
|
-
| {
|
|
54
|
-
agreement: boolean;
|
|
55
|
-
card_holder: string;
|
|
56
|
-
card_number: string;
|
|
57
|
-
card_cvv: string;
|
|
58
|
-
card_month: string;
|
|
59
|
-
card_year: string;
|
|
60
|
-
register_consumer_card: boolean;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
type CompleteSavedCardRequest =
|
|
64
|
-
| DefaultCompleteSavedCardRequest
|
|
65
|
-
| IyzicoCompleteSavedCardRequest;
|
|
66
|
-
|
|
67
38
|
export const savedCardApi = api.injectEndpoints({
|
|
68
39
|
endpoints: (build) => ({
|
|
69
40
|
getSavedCards: build.query<GetResponse<SavedCard>, void>({
|
|
@@ -100,7 +71,7 @@ export const savedCardApi = api.injectEndpoints({
|
|
|
100
71
|
),
|
|
101
72
|
method: 'POST',
|
|
102
73
|
body: {
|
|
103
|
-
card:
|
|
74
|
+
card: card.token
|
|
104
75
|
}
|
|
105
76
|
}),
|
|
106
77
|
async onQueryStarted({ card }, { dispatch, queryFulfilled }) {
|
|
@@ -135,7 +106,7 @@ export const savedCardApi = api.injectEndpoints({
|
|
|
135
106
|
CheckoutResponse,
|
|
136
107
|
CompleteSavedCardRequest
|
|
137
108
|
>({
|
|
138
|
-
query: (
|
|
109
|
+
query: ({ agreement }) => ({
|
|
139
110
|
url: buildClientRequestUrl(
|
|
140
111
|
`/orders/checkout?page=CompleteSavedCardRequest`,
|
|
141
112
|
{
|
|
@@ -143,7 +114,9 @@ export const savedCardApi = api.injectEndpoints({
|
|
|
143
114
|
}
|
|
144
115
|
),
|
|
145
116
|
method: 'POST',
|
|
146
|
-
body
|
|
117
|
+
body: {
|
|
118
|
+
agreement
|
|
119
|
+
}
|
|
147
120
|
}),
|
|
148
121
|
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
149
122
|
dispatch(setPaymentStepBusy(true));
|
package/src/redux/middleware.ts
CHANGED
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
import { Middleware } from '@reduxjs/toolkit';
|
|
2
|
-
import { setCards
|
|
2
|
+
import { setCards } from './reducer';
|
|
3
3
|
|
|
4
4
|
const savedCardMiddleware: Middleware = ({ dispatch }) => {
|
|
5
5
|
return (next) => (action) => {
|
|
6
6
|
const result = next(action);
|
|
7
7
|
|
|
8
8
|
const savedCardContext = result.payload?.context_list?.find(
|
|
9
|
-
(context) =>
|
|
9
|
+
(context) =>
|
|
10
|
+
context.page_slug === 'savedcardselectionpage' &&
|
|
11
|
+
context.page_context.cards
|
|
10
12
|
);
|
|
11
13
|
|
|
12
|
-
if (savedCardContext
|
|
14
|
+
if (savedCardContext) {
|
|
13
15
|
const cards = JSON.parse(
|
|
14
16
|
JSON.stringify(savedCardContext.page_context.cards)
|
|
15
17
|
);
|
|
16
18
|
|
|
17
19
|
dispatch(setCards(cards));
|
|
18
|
-
} else if (savedCardContext && savedCardContext.page_context?.ucs) {
|
|
19
|
-
const ucs = JSON.parse(JSON.stringify(savedCardContext.page_context.ucs));
|
|
20
|
-
|
|
21
|
-
const match = ucs.script.match(/<script\b[^>]*>([\s\S]*?)<\/script>/);
|
|
22
|
-
ucs.script = match ? match[1] : ucs.script;
|
|
23
|
-
|
|
24
|
-
dispatch(setUcs(ucs));
|
|
25
20
|
}
|
|
26
21
|
|
|
27
22
|
return result;
|
package/src/redux/reducer.ts
CHANGED
|
@@ -7,20 +7,12 @@ export type SavedCard = {
|
|
|
7
7
|
token: string;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
export type IyzicoUcs = {
|
|
11
|
-
maskedGsmNumber?: string;
|
|
12
|
-
script?: string;
|
|
13
|
-
scriptType?: string;
|
|
14
|
-
ucsToken?: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
10
|
export interface SavedCardState {
|
|
18
11
|
cards?: Array<SavedCard>;
|
|
19
12
|
deletion: {
|
|
20
13
|
id: number;
|
|
21
14
|
isModalVisible: boolean;
|
|
22
15
|
};
|
|
23
|
-
ucs?: IyzicoUcs;
|
|
24
16
|
}
|
|
25
17
|
|
|
26
18
|
const initialState: SavedCardState = {
|
|
@@ -43,22 +35,11 @@ const savedCardSlice = createSlice({
|
|
|
43
35
|
},
|
|
44
36
|
setDeletionModalVisible(state, { payload }) {
|
|
45
37
|
state.deletion.isModalVisible = payload;
|
|
46
|
-
},
|
|
47
|
-
setUcs(state, action: { payload: IyzicoUcs }) {
|
|
48
|
-
state.ucs = action.payload;
|
|
49
|
-
},
|
|
50
|
-
resetUcs() {
|
|
51
|
-
return initialState;
|
|
52
38
|
}
|
|
53
39
|
}
|
|
54
40
|
});
|
|
55
41
|
|
|
56
|
-
export const {
|
|
57
|
-
|
|
58
|
-
setDeletionModalId,
|
|
59
|
-
setDeletionModalVisible,
|
|
60
|
-
setUcs,
|
|
61
|
-
resetUcs
|
|
62
|
-
} = savedCardSlice.actions;
|
|
42
|
+
export const { setCards, setDeletionModalId, setDeletionModalVisible } =
|
|
43
|
+
savedCardSlice.actions;
|
|
63
44
|
|
|
64
45
|
export default savedCardSlice.reducer;
|
package/src/types/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
-
import { Control, FieldErrors } from 'react-hook-form';
|
|
3
2
|
|
|
4
3
|
export type InstallmentTexts = {
|
|
5
4
|
title?: string;
|
|
@@ -16,9 +15,6 @@ export type DeletePopupTexts = {
|
|
|
16
15
|
|
|
17
16
|
export type ErrorTexts = {
|
|
18
17
|
required?: string;
|
|
19
|
-
cardNumberLength?: string;
|
|
20
|
-
cvvLength?: string;
|
|
21
|
-
cardHolderMatches?: string;
|
|
22
18
|
};
|
|
23
19
|
|
|
24
20
|
export type SavedCardOptionTexts = {
|
|
@@ -29,29 +25,6 @@ export type SavedCardOptionTexts = {
|
|
|
29
25
|
errors?: ErrorTexts;
|
|
30
26
|
};
|
|
31
27
|
|
|
32
|
-
export type IyzicoSavedCardOptionTexts = {
|
|
33
|
-
title?: string;
|
|
34
|
-
button?: string;
|
|
35
|
-
installment?: InstallmentTexts;
|
|
36
|
-
errors?: ErrorTexts & {
|
|
37
|
-
saveCardRequired?: string;
|
|
38
|
-
};
|
|
39
|
-
label?: {
|
|
40
|
-
cardHolder?: string;
|
|
41
|
-
cardNumber?: string;
|
|
42
|
-
expiryDate?: string;
|
|
43
|
-
cvv?: string;
|
|
44
|
-
saveCardForFuture?: string;
|
|
45
|
-
};
|
|
46
|
-
placeholder?: {
|
|
47
|
-
cardHolder?: string;
|
|
48
|
-
cardMonth?: string;
|
|
49
|
-
cardYear?: string;
|
|
50
|
-
};
|
|
51
|
-
savedCardsTitle?: string;
|
|
52
|
-
paymentErrorMessage?: string;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
28
|
export type CardSelectionSectionProps = {
|
|
56
29
|
title: string;
|
|
57
30
|
cards: any[];
|
|
@@ -64,34 +37,15 @@ export type CardSelectionSectionProps = {
|
|
|
64
37
|
|
|
65
38
|
export type InstallmentSectionProps = {
|
|
66
39
|
title: string;
|
|
40
|
+
selectedCard: any;
|
|
67
41
|
installmentOptions: any;
|
|
68
42
|
translations: InstallmentTexts;
|
|
69
43
|
errors: any;
|
|
70
|
-
setFormValue?: any;
|
|
71
44
|
};
|
|
72
45
|
|
|
73
|
-
export
|
|
74
|
-
agreementCheckbox
|
|
75
|
-
control: Control<any>;
|
|
76
|
-
errors: FieldErrors;
|
|
77
|
-
buttonText: string;
|
|
78
|
-
formError?: {
|
|
79
|
-
non_field_errors?: string;
|
|
80
|
-
status?: string;
|
|
81
|
-
[key: string]: any;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export type CardFormSectionProps = {
|
|
86
|
-
register: any;
|
|
46
|
+
export type AgreementAndSubmitProps = {
|
|
47
|
+
agreementCheckbox: ReactElement | undefined;
|
|
87
48
|
control: any;
|
|
88
49
|
errors: any;
|
|
89
|
-
|
|
90
|
-
years: Array<{ label: string; value: string }>;
|
|
91
|
-
translations?: IyzicoSavedCardOptionTexts['label'];
|
|
92
|
-
setFormValue?: any;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export type IyzicoSavedCardsProps = {
|
|
96
|
-
title?: string;
|
|
50
|
+
buttonText: string;
|
|
97
51
|
};
|
|
@@ -183,6 +183,7 @@ const SavedCardOption = ({
|
|
|
183
183
|
{customRender?.installmentSection ? (
|
|
184
184
|
customRender.installmentSection({
|
|
185
185
|
title: mergedTexts.installment?.title,
|
|
186
|
+
selectedCard,
|
|
186
187
|
installmentOptions,
|
|
187
188
|
translations: mergedTexts.installment,
|
|
188
189
|
errors: errors.installment
|
|
@@ -190,6 +191,7 @@ const SavedCardOption = ({
|
|
|
190
191
|
) : (
|
|
191
192
|
<InstallmentSection
|
|
192
193
|
title={mergedTexts.installment?.title}
|
|
194
|
+
selectedCard={selectedCard}
|
|
193
195
|
installmentOptions={installmentOptions}
|
|
194
196
|
translations={mergedTexts.installment}
|
|
195
197
|
errors={errors.installment}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Input, Select, Icon, Image } from '@akinon/next/components';
|
|
3
|
-
import { Control, UseFormRegister, FieldErrors } from 'react-hook-form';
|
|
4
|
-
|
|
5
|
-
export interface CardFormSectionProps {
|
|
6
|
-
register: UseFormRegister<any>;
|
|
7
|
-
control: Control<any>;
|
|
8
|
-
errors: FieldErrors;
|
|
9
|
-
months: Array<{ label: string; value: string }>;
|
|
10
|
-
years: Array<{ label: string; value: string }>;
|
|
11
|
-
translations?: {
|
|
12
|
-
cardHolder?: string;
|
|
13
|
-
cardNumber?: string;
|
|
14
|
-
expiryDate?: string;
|
|
15
|
-
cvv?: string;
|
|
16
|
-
cvvTooltip?: string;
|
|
17
|
-
saveCardForFuture?: string;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const CardFormSection = ({
|
|
22
|
-
register,
|
|
23
|
-
control,
|
|
24
|
-
errors,
|
|
25
|
-
months,
|
|
26
|
-
years,
|
|
27
|
-
translations = {},
|
|
28
|
-
}: CardFormSectionProps) => {
|
|
29
|
-
return (
|
|
30
|
-
<div className="w-full bg-white">
|
|
31
|
-
<div className="px-4 my-2 w-full flex justify-between flex-wrap">
|
|
32
|
-
<div className="my-2 w-full sm:px-4">
|
|
33
|
-
<Input
|
|
34
|
-
label={translations.cardHolder}
|
|
35
|
-
{...register('card_holder')}
|
|
36
|
-
error={errors.card_holder}
|
|
37
|
-
/>
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
<div className="my-2 w-full flex flex-col sm:px-4">
|
|
41
|
-
<div className="text-xs text-gray-800 mb-2 w-full flex justify-between items-center">
|
|
42
|
-
<span>{translations.cardNumber}</span>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<Input
|
|
46
|
-
format="#### #### #### ####"
|
|
47
|
-
mask="_"
|
|
48
|
-
allowEmptyFormatting={true}
|
|
49
|
-
control={control}
|
|
50
|
-
{...register('card_number')}
|
|
51
|
-
error={errors.card_number}
|
|
52
|
-
/>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<div className="w-full my-2 sm:flex">
|
|
56
|
-
<div className="sm:w-2/3 sm:px-4">
|
|
57
|
-
<label
|
|
58
|
-
className="flex w-full text-xs text-start text-black-400 mb-1.5"
|
|
59
|
-
htmlFor="card_month"
|
|
60
|
-
>
|
|
61
|
-
{translations.expiryDate}
|
|
62
|
-
</label>
|
|
63
|
-
|
|
64
|
-
<div className="flex w-full h-10 space-x-2.5">
|
|
65
|
-
<div className="w-2/4">
|
|
66
|
-
<Select
|
|
67
|
-
className="w-full text-xs border-gray-400 sm:text-sm"
|
|
68
|
-
options={months}
|
|
69
|
-
{...register('card_month')}
|
|
70
|
-
error={errors.card_month}
|
|
71
|
-
/>
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<div className="w-2/4">
|
|
75
|
-
<Select
|
|
76
|
-
className="w-full text-xs border-gray-400 sm:text-sm"
|
|
77
|
-
options={years}
|
|
78
|
-
{...register('card_year')}
|
|
79
|
-
error={errors.card_year}
|
|
80
|
-
/>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
|
|
85
|
-
<div className="my-2 sm:w-1/3 sm:px-4 sm:my-0">
|
|
86
|
-
<label
|
|
87
|
-
className="flex w-full text-xs text-start text-black-400 mb-1.5"
|
|
88
|
-
htmlFor="card_cvv"
|
|
89
|
-
>
|
|
90
|
-
{translations.cvv}
|
|
91
|
-
</label>
|
|
92
|
-
<Input
|
|
93
|
-
format="###"
|
|
94
|
-
mask="_"
|
|
95
|
-
control={control}
|
|
96
|
-
allowEmptyFormatting={true}
|
|
97
|
-
{...register('card_cvv')}
|
|
98
|
-
error={errors.card_cvv}
|
|
99
|
-
/>
|
|
100
|
-
<div className="group relative flex items-center justify-start text-gray-600 cursor-pointer mt-2 transition-all hover:text-secondary">
|
|
101
|
-
<span className="text-xs underline">
|
|
102
|
-
{translations.cvv}
|
|
103
|
-
</span>
|
|
104
|
-
<Icon name="cvc" size={16} className="leading-none ml-2" />
|
|
105
|
-
<div className="hidden group-hover:block absolute right-0 bottom-5 w-[11rem] lg:w-[21rem] lg:left-auto lg:right-auto border-2">
|
|
106
|
-
<Image src="/cvv.jpg" alt="Cvv" width={385} height={264} />
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
<div className="my-2 w-full flex flex-col sm:px-4">
|
|
113
|
-
<label className="flex items-center space-x-2">
|
|
114
|
-
<input
|
|
115
|
-
type="checkbox"
|
|
116
|
-
{...register('register_consumer_card')}
|
|
117
|
-
className="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded"
|
|
118
|
-
/>
|
|
119
|
-
<span className="text-sm text-gray-700">
|
|
120
|
-
{translations.saveCardForFuture}
|
|
121
|
-
</span>
|
|
122
|
-
</label>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
</div>
|
|
126
|
-
);
|
|
127
|
-
};
|
|
@@ -1,427 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import * as yup from 'yup';
|
|
4
|
-
import { ObjectSchema } from 'yup';
|
|
5
|
-
import { yupResolver } from '@hookform/resolvers/yup';
|
|
6
|
-
import { useForm } from 'react-hook-form';
|
|
7
|
-
import {
|
|
8
|
-
FormHTMLAttributes,
|
|
9
|
-
HTMLAttributes,
|
|
10
|
-
ReactElement,
|
|
11
|
-
useEffect,
|
|
12
|
-
useMemo,
|
|
13
|
-
useState
|
|
14
|
-
} from 'react';
|
|
15
|
-
import { useAppSelector } from '@akinon/next/redux/hooks';
|
|
16
|
-
import {
|
|
17
|
-
useCompleteSavedCardMutation,
|
|
18
|
-
useSetSavedCardMutation
|
|
19
|
-
} from '../redux/api';
|
|
20
|
-
|
|
21
|
-
import {
|
|
22
|
-
AgreementAndSubmitProps,
|
|
23
|
-
CardFormSectionProps,
|
|
24
|
-
ErrorTexts,
|
|
25
|
-
InstallmentSectionProps,
|
|
26
|
-
IyzicoSavedCardOptionTexts,
|
|
27
|
-
IyzicoSavedCardsProps
|
|
28
|
-
} from '../types';
|
|
29
|
-
import { InstallmentSection } from '../components/installment-section';
|
|
30
|
-
import { AgreementAndSubmit } from '../components/agreement-and-submit';
|
|
31
|
-
import { CardFormSection } from '../components/card-form-section';
|
|
32
|
-
import Script from 'next/script';
|
|
33
|
-
|
|
34
|
-
type IyzicoSavedCardOptionProps = {
|
|
35
|
-
texts?: IyzicoSavedCardOptionTexts;
|
|
36
|
-
agreementCheckbox?: ReactElement;
|
|
37
|
-
customFormSchema?: {
|
|
38
|
-
'new-card'?: ObjectSchema<any>;
|
|
39
|
-
'existing-card'?: ObjectSchema<any>;
|
|
40
|
-
};
|
|
41
|
-
customRender?: {
|
|
42
|
-
cardFormSection?: (props: CardFormSectionProps) => ReactElement;
|
|
43
|
-
savedCardsSection?: (props: IyzicoSavedCardsProps) => ReactElement;
|
|
44
|
-
installmentSection?: (props: InstallmentSectionProps) => ReactElement;
|
|
45
|
-
agreementAndSubmit?: (props: AgreementAndSubmitProps) => ReactElement;
|
|
46
|
-
};
|
|
47
|
-
formWrapperClassName?: string;
|
|
48
|
-
cardSelectionWrapperClassName?: string;
|
|
49
|
-
installmentWrapperClassName?: string;
|
|
50
|
-
formProps?: FormHTMLAttributes<HTMLFormElement>;
|
|
51
|
-
cardSelectionWrapperProps?: HTMLAttributes<HTMLDivElement>;
|
|
52
|
-
installmentWrapperProps?: HTMLAttributes<HTMLDivElement>;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const defaultTranslations: IyzicoSavedCardOptionTexts = {
|
|
56
|
-
title: 'Pay with Iyzico',
|
|
57
|
-
button: 'Complete Payment',
|
|
58
|
-
installment: {
|
|
59
|
-
title: 'Installment Options'
|
|
60
|
-
},
|
|
61
|
-
errors: {
|
|
62
|
-
required: 'This field is required',
|
|
63
|
-
cardNumberLength: 'Card number must be 16 digits long.',
|
|
64
|
-
cvvLength: 'CVV must be 3 digits long.',
|
|
65
|
-
cardHolderMatches: 'Please enter a valid name',
|
|
66
|
-
saveCardRequired: 'Please select the Save My Card option'
|
|
67
|
-
},
|
|
68
|
-
label: {
|
|
69
|
-
cardHolder: 'Cardholder Name',
|
|
70
|
-
cardNumber: 'Card Number',
|
|
71
|
-
expiryDate: 'Expiration Date',
|
|
72
|
-
cvv: 'CVV',
|
|
73
|
-
saveCardForFuture: 'Save this card for future payments',
|
|
74
|
-
},
|
|
75
|
-
placeholder: {
|
|
76
|
-
cardHolder: 'Name on Card',
|
|
77
|
-
cardMonth: 'Month',
|
|
78
|
-
cardYear: 'Year'
|
|
79
|
-
},
|
|
80
|
-
savedCardsTitle: 'Select from your saved cards:',
|
|
81
|
-
paymentErrorMessage: 'An error occurred while processing your payment'
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const mergeTranslations = (
|
|
85
|
-
customTranslations: IyzicoSavedCardOptionTexts,
|
|
86
|
-
defaultTranslations: IyzicoSavedCardOptionTexts
|
|
87
|
-
) => {
|
|
88
|
-
return {
|
|
89
|
-
...defaultTranslations,
|
|
90
|
-
...customTranslations,
|
|
91
|
-
installment: {
|
|
92
|
-
...defaultTranslations.installment,
|
|
93
|
-
...customTranslations.installment
|
|
94
|
-
},
|
|
95
|
-
errors: {
|
|
96
|
-
...defaultTranslations.errors,
|
|
97
|
-
...customTranslations.errors
|
|
98
|
-
},
|
|
99
|
-
label: {
|
|
100
|
-
...defaultTranslations.label,
|
|
101
|
-
...customTranslations.label
|
|
102
|
-
},
|
|
103
|
-
placeholder: {
|
|
104
|
-
...defaultTranslations.placeholder,
|
|
105
|
-
...customTranslations.placeholder
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const createFormSchema = (
|
|
111
|
-
errors: ErrorTexts,
|
|
112
|
-
type: 'existing-card' | 'new-card'
|
|
113
|
-
) => {
|
|
114
|
-
const baseSchema = {
|
|
115
|
-
agreement: yup
|
|
116
|
-
.boolean()
|
|
117
|
-
.oneOf([true], errors?.required ?? defaultTranslations.errors.required),
|
|
118
|
-
register_consumer_card: yup.boolean().default(false)
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
if (type === 'new-card') {
|
|
122
|
-
return yup.object().shape({
|
|
123
|
-
...baseSchema,
|
|
124
|
-
card_holder: yup
|
|
125
|
-
.string()
|
|
126
|
-
.required(errors?.required ?? defaultTranslations.errors.required)
|
|
127
|
-
.matches(
|
|
128
|
-
/^[a-zA-ZğüşöçıİĞÜŞÖÇ\s]+$/,
|
|
129
|
-
errors?.cardHolderMatches ??
|
|
130
|
-
defaultTranslations.errors.cardHolderMatches
|
|
131
|
-
),
|
|
132
|
-
card_number: yup
|
|
133
|
-
.string()
|
|
134
|
-
.transform((value: string) => value.replace(/_/g, '').replace(/ /g, ''))
|
|
135
|
-
.length(
|
|
136
|
-
16,
|
|
137
|
-
errors?.cardNumberLength ??
|
|
138
|
-
defaultTranslations.errors.cardNumberLength
|
|
139
|
-
)
|
|
140
|
-
.required(errors?.required ?? defaultTranslations.errors.required),
|
|
141
|
-
card_month: yup
|
|
142
|
-
.string()
|
|
143
|
-
.required(errors?.required ?? defaultTranslations.errors.required),
|
|
144
|
-
card_year: yup
|
|
145
|
-
.string()
|
|
146
|
-
.required(errors?.required ?? defaultTranslations.errors.required),
|
|
147
|
-
card_cvv: yup
|
|
148
|
-
.string()
|
|
149
|
-
.transform((value: string) => value.replace(/_/g, '').replace(/ /g, ''))
|
|
150
|
-
.length(3, errors?.cvvLength ?? defaultTranslations.errors.cvvLength)
|
|
151
|
-
.required(errors?.required ?? defaultTranslations.errors.required)
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return yup.object().shape(baseSchema);
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const IyzicoSavedCardOption = ({
|
|
159
|
-
texts = defaultTranslations,
|
|
160
|
-
agreementCheckbox,
|
|
161
|
-
customFormSchema,
|
|
162
|
-
customRender,
|
|
163
|
-
formWrapperClassName = 'flex flex-wrap w-full',
|
|
164
|
-
cardSelectionWrapperClassName = 'w-full flex flex-col xl:w-6/10',
|
|
165
|
-
installmentWrapperClassName = 'w-full xl:w-4/10 xl:border-l xl:border-t-0',
|
|
166
|
-
formProps = {},
|
|
167
|
-
cardSelectionWrapperProps = {},
|
|
168
|
-
installmentWrapperProps = {}
|
|
169
|
-
}: IyzicoSavedCardOptionProps) => {
|
|
170
|
-
const mergedTexts = useMemo(
|
|
171
|
-
() => mergeTranslations(texts, defaultTranslations),
|
|
172
|
-
[texts]
|
|
173
|
-
);
|
|
174
|
-
const [completeSavedCard] = useCompleteSavedCardMutation();
|
|
175
|
-
const [setSavedCard] = useSetSavedCardMutation();
|
|
176
|
-
const installmentOptions = useAppSelector(
|
|
177
|
-
(state) => state.checkout.installmentOptions
|
|
178
|
-
);
|
|
179
|
-
const ucs = useAppSelector((state) => state.savedCard.ucs);
|
|
180
|
-
const [type, setType] = useState<'new-card' | 'existing-card'>('new-card');
|
|
181
|
-
const [months, setMonths] = useState([]);
|
|
182
|
-
const [years, setYears] = useState([]);
|
|
183
|
-
const [formError, setFormError] = useState(null);
|
|
184
|
-
|
|
185
|
-
const getFormSchema = () => {
|
|
186
|
-
if (customFormSchema?.[type]) {
|
|
187
|
-
return customFormSchema[type];
|
|
188
|
-
}
|
|
189
|
-
return createFormSchema(mergedTexts.errors, type);
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const {
|
|
193
|
-
register,
|
|
194
|
-
handleSubmit,
|
|
195
|
-
control,
|
|
196
|
-
formState: { errors },
|
|
197
|
-
setValue: setFormValue
|
|
198
|
-
} = useForm({
|
|
199
|
-
resolver: yupResolver(getFormSchema())
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
const onSubmit = async (data) => {
|
|
203
|
-
if (!window.iyziUcsInit) {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
setFormError(null);
|
|
208
|
-
|
|
209
|
-
try {
|
|
210
|
-
if (type === 'existing-card') {
|
|
211
|
-
const res = await completeSavedCard({
|
|
212
|
-
agreement: data.agreement,
|
|
213
|
-
consumer_token: window.universalCardStorage.consumerToken,
|
|
214
|
-
card_token: window.universalCardStorage.cardToken,
|
|
215
|
-
register_consumer_card: true
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
if ('data' in res && res.data?.errors) {
|
|
219
|
-
setFormError(res.data.errors);
|
|
220
|
-
}
|
|
221
|
-
} else {
|
|
222
|
-
const res = await completeSavedCard({
|
|
223
|
-
agreement: data.agreement,
|
|
224
|
-
card_holder: data.card_holder,
|
|
225
|
-
card_number: data.card_number.replaceAll(' ', ''),
|
|
226
|
-
card_month: data.card_month,
|
|
227
|
-
card_year: data.card_year,
|
|
228
|
-
card_cvv: data.card_cvv,
|
|
229
|
-
register_consumer_card: data.register_consumer_card || false
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
if ('data' in res && res.data?.errors) {
|
|
233
|
-
setFormError(res.data.errors);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
} catch (error) {
|
|
237
|
-
console.error('Error completing saved card:', error);
|
|
238
|
-
setFormError({
|
|
239
|
-
non_field_errors:
|
|
240
|
-
mergedTexts.paymentErrorMessage ??
|
|
241
|
-
defaultTranslations.paymentErrorMessage
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
const ucsScript = ucs?.script && (
|
|
247
|
-
<Script
|
|
248
|
-
id="saved_card"
|
|
249
|
-
strategy="afterInteractive"
|
|
250
|
-
dangerouslySetInnerHTML={{ __html: ucs.script }}
|
|
251
|
-
/>
|
|
252
|
-
);
|
|
253
|
-
|
|
254
|
-
useEffect(() => {
|
|
255
|
-
window.iyziUcsInit?.createTag();
|
|
256
|
-
|
|
257
|
-
const monthsList = [
|
|
258
|
-
{
|
|
259
|
-
label:
|
|
260
|
-
mergedTexts.placeholder?.cardMonth ??
|
|
261
|
-
defaultTranslations.placeholder.cardMonth,
|
|
262
|
-
value: ''
|
|
263
|
-
}
|
|
264
|
-
];
|
|
265
|
-
const yearsList = [
|
|
266
|
-
{
|
|
267
|
-
label:
|
|
268
|
-
mergedTexts.placeholder?.cardYear ??
|
|
269
|
-
defaultTranslations.placeholder.cardYear,
|
|
270
|
-
value: ''
|
|
271
|
-
}
|
|
272
|
-
];
|
|
273
|
-
const date = new Date();
|
|
274
|
-
const currentYear = date.getFullYear();
|
|
275
|
-
|
|
276
|
-
for (let i = 1; i <= 12; i++) {
|
|
277
|
-
monthsList.push({ label: i.toString(), value: i.toString() });
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
for (let i = currentYear; i < currentYear + 13; i++) {
|
|
281
|
-
yearsList.push({ label: i.toString(), value: i.toString() });
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
setMonths(monthsList);
|
|
285
|
-
setYears(yearsList);
|
|
286
|
-
|
|
287
|
-
if (window.iyziUcsInit?.ucsToken) {
|
|
288
|
-
setSavedCard({
|
|
289
|
-
card: window.iyziUcsInit.ucsToken
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
}, []);
|
|
293
|
-
|
|
294
|
-
useEffect(() => {
|
|
295
|
-
if (window.iyziUcsInit?.scriptType === 'CONSUMER_WITH_CARD_EXIST') {
|
|
296
|
-
if (
|
|
297
|
-
window.universalCardStorage?.cardToken
|
|
298
|
-
) {
|
|
299
|
-
setType('existing-card');
|
|
300
|
-
} else {
|
|
301
|
-
setType('new-card');
|
|
302
|
-
}
|
|
303
|
-
} else {
|
|
304
|
-
setType('new-card');
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const checkboxInterval = setInterval(() => {
|
|
308
|
-
if (window.universalCardStorage?.cardToken !== undefined) {
|
|
309
|
-
setType('existing-card');
|
|
310
|
-
} else {
|
|
311
|
-
setType('new-card');
|
|
312
|
-
}
|
|
313
|
-
}, 100);
|
|
314
|
-
|
|
315
|
-
return () => clearInterval(checkboxInterval);
|
|
316
|
-
}, [type]);
|
|
317
|
-
|
|
318
|
-
return (
|
|
319
|
-
<>
|
|
320
|
-
<form
|
|
321
|
-
className={formWrapperClassName}
|
|
322
|
-
onSubmit={handleSubmit(onSubmit)}
|
|
323
|
-
{...formProps}
|
|
324
|
-
>
|
|
325
|
-
<div
|
|
326
|
-
className={cardSelectionWrapperClassName}
|
|
327
|
-
{...cardSelectionWrapperProps}
|
|
328
|
-
>
|
|
329
|
-
{mergedTexts.title && (
|
|
330
|
-
<div className="border-solid border-gray-400 px-4 py-2">
|
|
331
|
-
<span className="text-black-800 text-lg font-medium">
|
|
332
|
-
{mergedTexts.title}
|
|
333
|
-
</span>
|
|
334
|
-
</div>
|
|
335
|
-
)}
|
|
336
|
-
|
|
337
|
-
{window.iyziUcsInit?.scriptType === 'CONSUMER_WITH_CARD_EXIST' && (
|
|
338
|
-
<>
|
|
339
|
-
{customRender?.savedCardsSection ? (
|
|
340
|
-
customRender.savedCardsSection({
|
|
341
|
-
title: mergedTexts.savedCardsTitle
|
|
342
|
-
})
|
|
343
|
-
) : (
|
|
344
|
-
<div>
|
|
345
|
-
<h3 className="text-sm font-medium text-gray-800 mb-3 px-4 sm:px-6">
|
|
346
|
-
{mergedTexts.savedCardsTitle}
|
|
347
|
-
</h3>
|
|
348
|
-
<div id="ucs-cards" className="mb-3 px-4 sm:px-6"></div>
|
|
349
|
-
</div>
|
|
350
|
-
)}
|
|
351
|
-
</>
|
|
352
|
-
)}
|
|
353
|
-
|
|
354
|
-
{type === 'new-card' && (
|
|
355
|
-
<>
|
|
356
|
-
{customRender?.cardFormSection ? (
|
|
357
|
-
customRender.cardFormSection({
|
|
358
|
-
register,
|
|
359
|
-
control,
|
|
360
|
-
errors,
|
|
361
|
-
months,
|
|
362
|
-
years,
|
|
363
|
-
translations: mergedTexts.label,
|
|
364
|
-
setFormValue
|
|
365
|
-
})
|
|
366
|
-
) : (
|
|
367
|
-
<CardFormSection
|
|
368
|
-
register={register}
|
|
369
|
-
control={control}
|
|
370
|
-
errors={errors}
|
|
371
|
-
months={months}
|
|
372
|
-
years={years}
|
|
373
|
-
translations={mergedTexts.label}
|
|
374
|
-
/>
|
|
375
|
-
)}
|
|
376
|
-
</>
|
|
377
|
-
)}
|
|
378
|
-
</div>
|
|
379
|
-
|
|
380
|
-
<div
|
|
381
|
-
className={installmentWrapperClassName}
|
|
382
|
-
{...installmentWrapperProps}
|
|
383
|
-
>
|
|
384
|
-
{customRender?.installmentSection ? (
|
|
385
|
-
customRender.installmentSection({
|
|
386
|
-
title: mergedTexts.installment?.title,
|
|
387
|
-
installmentOptions,
|
|
388
|
-
translations: mergedTexts.installment,
|
|
389
|
-
errors: errors.installment,
|
|
390
|
-
setFormValue
|
|
391
|
-
})
|
|
392
|
-
) : (
|
|
393
|
-
<InstallmentSection
|
|
394
|
-
title={mergedTexts.installment?.title}
|
|
395
|
-
installmentOptions={installmentOptions}
|
|
396
|
-
translations={mergedTexts.installment}
|
|
397
|
-
errors={errors.installment}
|
|
398
|
-
/>
|
|
399
|
-
)}
|
|
400
|
-
|
|
401
|
-
<div className="flex flex-col text-xs">
|
|
402
|
-
{customRender?.agreementAndSubmit ? (
|
|
403
|
-
customRender.agreementAndSubmit({
|
|
404
|
-
agreementCheckbox,
|
|
405
|
-
control,
|
|
406
|
-
errors,
|
|
407
|
-
buttonText: mergedTexts.button,
|
|
408
|
-
formError
|
|
409
|
-
})
|
|
410
|
-
) : (
|
|
411
|
-
<AgreementAndSubmit
|
|
412
|
-
agreementCheckbox={agreementCheckbox}
|
|
413
|
-
control={control}
|
|
414
|
-
errors={errors}
|
|
415
|
-
buttonText={mergedTexts.button}
|
|
416
|
-
formError={formError}
|
|
417
|
-
/>
|
|
418
|
-
)}
|
|
419
|
-
</div>
|
|
420
|
-
</div>
|
|
421
|
-
</form>
|
|
422
|
-
{ucsScript}
|
|
423
|
-
</>
|
|
424
|
-
);
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
export default IyzicoSavedCardOption;
|