@akinon/pz-credit-payment 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/.prettierrc +13 -0
- package/package.json +20 -0
- package/src/index.tsx +162 -0
package/.prettierrc
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"bracketSameLine": false,
|
3
|
+
"tabWidth": 2,
|
4
|
+
"singleQuote": true,
|
5
|
+
"jsxSingleQuote": false,
|
6
|
+
"bracketSpacing": true,
|
7
|
+
"semi": true,
|
8
|
+
"useTabs": false,
|
9
|
+
"arrowParens": "always",
|
10
|
+
"endOfLine": "lf",
|
11
|
+
"proseWrap": "never",
|
12
|
+
"trailingComma": "none"
|
13
|
+
}
|
package/package.json
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"name": "@akinon/pz-credit-payment",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"license": "MIT",
|
5
|
+
"main": "src/index.tsx",
|
6
|
+
"peerDependencies": {
|
7
|
+
"react": "^18.0.0",
|
8
|
+
"react-dom": "^18.0.0"
|
9
|
+
},
|
10
|
+
"devDependencies": {
|
11
|
+
"@types/node": "^18.7.8",
|
12
|
+
"@types/react": "^18.0.17",
|
13
|
+
"@types/react-dom": "^18.0.6",
|
14
|
+
"react": "^18.2.0",
|
15
|
+
"react-dom": "^18.2.0",
|
16
|
+
"typescript": "^4.7.4",
|
17
|
+
"react-hook-form": "7.31.3",
|
18
|
+
"@hookform/resolvers": "2.9.0"
|
19
|
+
}
|
20
|
+
}
|
package/src/index.tsx
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
|
2
|
+
import React from 'react';
|
3
|
+
import { yupResolver } from '@hookform/resolvers/yup';
|
4
|
+
import { useEffect, useState } from 'react';
|
5
|
+
import { SubmitHandler, useForm } from 'react-hook-form';
|
6
|
+
import { useAppSelector } from '@akinon/next/redux/hooks';
|
7
|
+
import { RootState } from 'redux/store';
|
8
|
+
import { Button, Icon, Radio } from '@akinon/next/components';
|
9
|
+
import * as yup from 'yup';
|
10
|
+
import clsx from 'clsx';
|
11
|
+
import { twMerge } from 'tailwind-merge';
|
12
|
+
import {
|
13
|
+
useSetCreditPaymentOptionMutation,
|
14
|
+
useConfirmationCreditPaymentMutation
|
15
|
+
} from '@akinon/next/data/client/checkout';
|
16
|
+
|
17
|
+
interface CreditPaymentTranslationsProps {
|
18
|
+
title: string;
|
19
|
+
buttonName: string;
|
20
|
+
requiredFieldMessage: string;
|
21
|
+
}
|
22
|
+
|
23
|
+
const defaultTranslations = {
|
24
|
+
title: 'SHOPPING CREDIT',
|
25
|
+
buttonName: 'Place Order',
|
26
|
+
requiredFieldMessage: 'This field is required'
|
27
|
+
};
|
28
|
+
|
29
|
+
export interface CreditPaymentProps {
|
30
|
+
translations: Record<string, CreditPaymentTranslationsProps>;
|
31
|
+
agreementCheckbox: React.ReactElement;
|
32
|
+
titleClassName?: string;
|
33
|
+
buttonClassName?: string;
|
34
|
+
}
|
35
|
+
|
36
|
+
const creditPaymentFormSchema = (requiredFieldMessage) =>
|
37
|
+
yup.object().shape({
|
38
|
+
agreement: yup.boolean().oneOf([true], requiredFieldMessage)
|
39
|
+
});
|
40
|
+
|
41
|
+
export const CreditPayment = (
|
42
|
+
{
|
43
|
+
translations,
|
44
|
+
agreementCheckbox,
|
45
|
+
titleClassName,
|
46
|
+
buttonClassName
|
47
|
+
}: CreditPaymentProps
|
48
|
+
) => {
|
49
|
+
const _translations = {
|
50
|
+
...defaultTranslations,
|
51
|
+
...translations
|
52
|
+
};
|
53
|
+
|
54
|
+
const {
|
55
|
+
handleSubmit,
|
56
|
+
control,
|
57
|
+
register,
|
58
|
+
formState: { errors }
|
59
|
+
} = useForm({
|
60
|
+
resolver: yupResolver(creditPaymentFormSchema(_translations.requiredFieldMessage))
|
61
|
+
});
|
62
|
+
const [formError, setFormError] = useState<string | null>(null);
|
63
|
+
|
64
|
+
const [setCreditPaymentOption] = useSetCreditPaymentOptionMutation();
|
65
|
+
const [confirmationCreditPayment] = useConfirmationCreditPaymentMutation();
|
66
|
+
|
67
|
+
const { creditPaymentOptions, selectedCreditPaymentPk, preOrder } = useAppSelector(
|
68
|
+
(state: RootState) => state.checkout
|
69
|
+
);
|
70
|
+
|
71
|
+
const onSubmit: SubmitHandler<any> = async () => {
|
72
|
+
const response = await confirmationCreditPayment().unwrap();
|
73
|
+
|
74
|
+
if(response?.errors?.non_field_errors) {
|
75
|
+
setFormError(response?.errors?.non_field_errors);
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
};
|
79
|
+
|
80
|
+
useEffect(() => {
|
81
|
+
if (creditPaymentOptions?.length && !preOrder.credit_payment_option) {
|
82
|
+
setCreditPaymentOption(creditPaymentOptions[0].pk);
|
83
|
+
}
|
84
|
+
}, [creditPaymentOptions, selectedCreditPaymentPk, preOrder.credit_payment_option, setCreditPaymentOption]);
|
85
|
+
|
86
|
+
return (
|
87
|
+
<form className="flex flex-col w-full" onSubmit={handleSubmit(onSubmit)}>
|
88
|
+
<div className={clsx(
|
89
|
+
twMerge(
|
90
|
+
'flex justify-start items-center border-solid border-gray-400 px-4 py-2 sm:px-6 sm:py-3 sm:min-h-15',
|
91
|
+
'text-black-800 text-lg font-medium sm:text-2xl',
|
92
|
+
titleClassName
|
93
|
+
)
|
94
|
+
)}>
|
95
|
+
{_translations.title}
|
96
|
+
</div>
|
97
|
+
|
98
|
+
<div className="border-t border-solid border-gray-400 px-4 sm:px-6">
|
99
|
+
{creditPaymentOptions.map((bank) => (
|
100
|
+
<div
|
101
|
+
key={`bank-account-${bank.pk}`}
|
102
|
+
className="w-full border-b border-solid border-gray-400 py-4"
|
103
|
+
>
|
104
|
+
<label className="w-full flex items-center justify-start">
|
105
|
+
<Radio
|
106
|
+
type="radio"
|
107
|
+
value={bank.pk}
|
108
|
+
checked={bank.pk === selectedCreditPaymentPk || preOrder.credit_payment_option?.pk === bank.pk}
|
109
|
+
{...register('paymentType')}
|
110
|
+
onChange={() => {
|
111
|
+
setCreditPaymentOption(bank.pk);
|
112
|
+
}}
|
113
|
+
data-testid={`checkout-bank-account-${bank.pk}`}
|
114
|
+
></Radio>
|
115
|
+
|
116
|
+
<span className="w-full flex items-start justify-start flex-col pl-3">
|
117
|
+
{bank.name}
|
118
|
+
</span>
|
119
|
+
</label>
|
120
|
+
</div>
|
121
|
+
))}
|
122
|
+
</div>
|
123
|
+
|
124
|
+
<div className="px-4 sm:px-6">
|
125
|
+
<div className="flex items-start flex-col py-4 space-y-4">
|
126
|
+
{agreementCheckbox &&
|
127
|
+
React.cloneElement(agreementCheckbox, {
|
128
|
+
control,
|
129
|
+
error: errors.agreement,
|
130
|
+
fieldId: 'agreement'
|
131
|
+
})}
|
132
|
+
|
133
|
+
{formError && (
|
134
|
+
<div className="w-full text-xs text-start px-1 mt-3 text-error">
|
135
|
+
{formError}
|
136
|
+
</div>
|
137
|
+
)}
|
138
|
+
|
139
|
+
<Button
|
140
|
+
type="submit"
|
141
|
+
data-testid="checkout-bank-account-place-order"
|
142
|
+
className={clsx(
|
143
|
+
twMerge(
|
144
|
+
'group uppercase mt-4 inline-flex items-center justify-center w-full',
|
145
|
+
buttonClassName
|
146
|
+
)
|
147
|
+
)}
|
148
|
+
>
|
149
|
+
<span>{_translations.buttonName}</span>
|
150
|
+
|
151
|
+
<Icon
|
152
|
+
name="chevron-end"
|
153
|
+
size={12}
|
154
|
+
className="fill-primary-foreground ml-2 h-3 group-hover:fill-primary"
|
155
|
+
/>
|
156
|
+
</Button>
|
157
|
+
</div>
|
158
|
+
</div>
|
159
|
+
</form>
|
160
|
+
);
|
161
|
+
};
|
162
|
+
|