@akinon/pz-credit-payment 2.0.0-beta.2 → 2.0.0-beta.20

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 CHANGED
@@ -1,18 +1,122 @@
1
1
  # @akinon/pz-credit-payment
2
2
 
3
- ## 2.0.0-beta.2
3
+ ## 2.0.0-beta.20
4
4
 
5
- ## 2.0.0-beta.1
5
+ ## 1.125.0
6
+
7
+ ## 1.124.0
8
+
9
+ ## 1.123.0
10
+
11
+ ## 1.122.0
12
+
13
+ ## 1.121.0
14
+
15
+ ## 1.120.0
16
+
17
+ ### Minor Changes
18
+
19
+ - 6ad72e8d: ZERO-4032: Add loading state management for payment submissions across multiple components and add safe guarding
20
+
21
+ ## 1.119.0
22
+
23
+ ## 1.118.0
24
+
25
+ ## 1.117.0
26
+
27
+ ## 1.116.0
28
+
29
+ ## 1.115.0
30
+
31
+ ## 1.114.0
32
+
33
+ ## 1.113.0
34
+
35
+ ## 1.112.0
36
+
37
+ ## 1.111.0
38
+
39
+ ## 1.110.0
40
+
41
+ ## 1.109.0
42
+
43
+ ## 1.108.0
44
+
45
+ ## 1.107.0
46
+
47
+ ## 1.106.0
48
+
49
+ ## 1.105.0
50
+
51
+ ## 1.104.0
52
+
53
+ ## 1.103.0
6
54
 
7
55
  ### Minor Changes
8
56
 
9
- - ZERO-3091: Upgrade Next.js to v15 and React to v19
57
+ - 310556e: ZERO-3372 :Add README and enhance CreditPayment component with renderer support
58
+
59
+ ## 1.102.0
60
+
61
+ ## 1.101.0
62
+
63
+ ## 1.100.0
64
+
65
+ ## 1.99.0
66
+
67
+ ### Minor Changes
68
+
69
+ - d58538b: ZERO-3638: Enhance RC pipeline: add fetch, merge, and pre-release setup with conditional commit
70
+
71
+ ## 1.98.0
72
+
73
+ ## 1.97.0
74
+
75
+ ## 1.96.0
76
+
77
+ ## 1.95.0
78
+
79
+ ## 1.94.0
80
+
81
+ ### Minor Changes
82
+
83
+ - fec9638: ZERO-3346 :Update data-testid for Credit Payment button
84
+
85
+ ## 1.93.0
86
+
87
+ ## 1.92.0
88
+
89
+ ## 1.91.0
90
+
91
+ ## 1.90.0
92
+
93
+ ## 1.89.0
94
+
95
+ ## 1.88.0
96
+
97
+ ## 1.87.0
98
+
99
+ ## 1.86.0
100
+
101
+ ## 1.85.0
102
+
103
+ ## 1.84.0
104
+
105
+ ## 1.83.0
106
+
107
+ ## 1.82.0
108
+
109
+ ## 1.81.0
110
+
111
+ ## 1.80.0
112
+
113
+ ## 1.79.0
10
114
 
11
- ## 2.0.0-beta.0
115
+ ## 1.78.0
12
116
 
13
- ### Major Changes
117
+ ## 1.77.0
14
118
 
15
- - be6c09d: ZERO-3114: Create beta version.
119
+ ## 1.76.0
16
120
 
17
121
  ## 1.75.0
18
122
 
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # @akinon/pz-credit-payment
2
+
3
+ ## Installation method
4
+
5
+ You can use the following command to install the extension with the latest plugins:
6
+
7
+ ```bash
8
+
9
+ npx @akinon/projectzero@latest --plugins
10
+
11
+ ```
12
+
13
+ ## CreditPayment
14
+
15
+ A customizable React component that enables customers to select a credit payment option during checkout and confirm their agreement to terms before placing the order.
16
+
17
+ ### Props
18
+
19
+ #### `CreditPaymentProps`
20
+
21
+ | Prop | Type | Required | Description |
22
+ | --- | --- | --- | --- |
23
+ | `translations` | `Record<string, CreditPaymentTranslationsProps>` | Optional | Localization texts for title, button and validation message |
24
+ | `agreementCheckbox` | `React.ReactElement` | Required | A controlled checkbox React element (e.g., terms agreement checkbox) |
25
+ | `titleClassName` | `string` | Optional | Optional custom CSS class for the title area |
26
+ | `buttonClassName` | `string` | Optional | Optional custom CSS class for the submit button |
27
+ | `renderer` | `{ Content?: (props: RendererProps) => JSX.Element }` | Optional | Optional override to fully control the rendering of the component |
28
+
29
+ #### `CreditPaymentTranslationsProps`
30
+
31
+ | Key | Type | Description |
32
+ | --- | --- | --- |
33
+ | `title` | `string` | Title text shown at the top of the section |
34
+ | `buttonName` | `string` | Submit button label |
35
+ | `requiredFieldMessage` | `string` | Error message when checkbox is not checked |
36
+
37
+ #### RendererProps (for `renderer.Content`)
38
+
39
+ | Prop | Type | Description |
40
+ | --- | --- | --- |
41
+ | `control` | `any` | React Hook Form control instance |
42
+ | `errors` | `any` | React Hook Form errors object |
43
+ | `onSubmit` | `() => void` | Submit handler |
44
+ | `creditPaymentOptions` | `any[]` | Available credit payment options |
45
+ | `selectedCreditPaymentPk` | `number \| null` | Currently selected option's primary key |
46
+ | `setCreditPaymentOption` | `(pk: number) => void` | Setter for selecting a payment option |
47
+ | `preOrder` | `RootState['checkout']['preOrder']` | Pre-order object from Redux |
48
+ | `agreementCheckbox` | `React.ReactElement` | Provided agreement checkbox component |
49
+ | `formError` | `string \| null` | Any error returned from the confirmation API |
50
+
51
+ ### Usage
52
+
53
+ ```bash
54
+ src/views/checkout/steps/payment/options/credit-payment/
55
+ ```
56
+
57
+ #### Default Usage
58
+
59
+ ```javascript
60
+ <PluginModule
61
+ component={Component.CreditPayment}
62
+ props={{
63
+ agreementCheckbox: (
64
+ <CheckoutAgreements control={null} error={null} fieldId="agreement" />
65
+ )
66
+ }}
67
+ />
68
+ ```
69
+
70
+ #### Customized Usage with `renderer`
71
+
72
+ ```javascript
73
+ <PluginModule
74
+ component={Component.CreditPayment}
75
+ props={{
76
+ agreementCheckbox: (
77
+ <CheckoutAgreements control={null} error={null} fieldId="agreement" />
78
+ ),
79
+ renderer: {
80
+ Content: ({
81
+ control,
82
+ errors,
83
+ onSubmit,
84
+ creditPaymentOptions,
85
+ selectedCreditPaymentPk,
86
+ setCreditPaymentOption,
87
+ preOrder,
88
+ agreementCheckbox,
89
+ formError
90
+ }) => (
91
+ <form onSubmit={onSubmit} className="p-6 bg-white rounded-lg space-y-6">
92
+ <h2 className="text-xl font-semibold">SHOPPING CREDIT</h2>
93
+ <div className="space-y-4">
94
+ {creditPaymentOptions.map((bank) => (
95
+ <label
96
+ key={bank.pk}
97
+ className="p-4 flex items-center cursor-pointer rounded-lg border-gray-480 border space-x-5 pl-5 mb-6"
98
+ >
99
+ <Radio
100
+ type="radio"
101
+ value={bank.pk}
102
+ checked={
103
+ bank.pk === selectedCreditPaymentPk ||
104
+ preOrder.credit_payment_option?.pk === bank.pk
105
+ }
106
+ onChange={() => setCreditPaymentOption(bank.pk)}
107
+ />
108
+ <span>{bank.name}</span>
109
+ </label>
110
+ ))}
111
+ </div>
112
+ {React.cloneElement(agreementCheckbox, {
113
+ control,
114
+ error: errors.agreement,
115
+ fieldId: 'agreement'
116
+ })}
117
+ {formError && <p className="text-xs text-error mt-2">{formError}</p>}
118
+ <Button type="submit" className="w-full bg-black text-white">
119
+ Place Order
120
+ </Button>
121
+ </form>
122
+ )
123
+ }
124
+ }}
125
+ />
126
+ ```
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@akinon/pz-credit-payment",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-beta.20",
4
4
  "license": "MIT",
5
5
  "main": "src/index.tsx",
6
6
  "peerDependencies": {
7
- "react": "^19.0.0",
8
- "react-dom": "^19.0.0"
7
+ "react": "^18.0.0 || ^19.0.0",
8
+ "react-dom": "^18.0.0 || ^19.0.0"
9
9
  },
10
10
  "devDependencies": {
11
- "@types/node": "^22.10.2",
12
- "@types/react": "^19.0.2",
13
- "@types/react-dom": "^19.0.2",
14
- "react": "^19.0.0",
15
- "react-dom": "^19.0.0",
16
- "typescript": "^5.7.2",
11
+ "@types/node": "^18.7.8",
12
+ "@types/react": "^18.0.17",
13
+ "@types/react-dom": "^18.0.6",
14
+ "react": "^19.2.4",
15
+ "react-dom": "^19.2.4",
16
+ "typescript": "^4.7.4",
17
17
  "react-hook-form": "7.31.3",
18
18
  "@hookform/resolvers": "2.9.0"
19
19
  }
package/src/index.tsx CHANGED
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
2
  import { yupResolver } from '@hookform/resolvers/yup';
3
- import { useEffect, useState } from 'react';
3
+ import { JSX, useEffect, useState } from 'react';
4
4
  import { SubmitHandler, useForm } from 'react-hook-form';
5
5
  import { useAppSelector } from '@akinon/next/redux/hooks';
6
6
  import { RootState } from 'redux/store';
7
7
  import { Button, Icon, Radio } from '@akinon/next/components';
8
+ import { checkPaymentWillRedirect } from '@akinon/next/utils';
8
9
  import * as yup from 'yup';
9
10
  import clsx from 'clsx';
10
11
  import { twMerge } from 'tailwind-merge';
@@ -26,10 +27,23 @@ const defaultTranslations = {
26
27
  };
27
28
 
28
29
  export interface CreditPaymentProps {
29
- translations: Record<string, CreditPaymentTranslationsProps>;
30
+ translations?: Record<string, CreditPaymentTranslationsProps>;
30
31
  agreementCheckbox: React.ReactElement;
31
32
  titleClassName?: string;
32
33
  buttonClassName?: string;
34
+ renderer?: {
35
+ Content?: (props: {
36
+ control: any;
37
+ errors: any;
38
+ onSubmit: () => void;
39
+ creditPaymentOptions: any[];
40
+ selectedCreditPaymentPk: number | null;
41
+ setCreditPaymentOption: (pk: number) => void;
42
+ preOrder: RootState['checkout']['preOrder'];
43
+ agreementCheckbox: React.ReactElement;
44
+ formError: string | null;
45
+ }) => JSX.Element;
46
+ };
33
47
  }
34
48
 
35
49
  const creditPaymentFormSchema = (requiredFieldMessage) =>
@@ -41,7 +55,8 @@ export const CreditPayment = ({
41
55
  translations,
42
56
  agreementCheckbox,
43
57
  titleClassName,
44
- buttonClassName
58
+ buttonClassName,
59
+ renderer
45
60
  }: CreditPaymentProps) => {
46
61
  const _translations = {
47
62
  ...defaultTranslations,
@@ -52,26 +67,43 @@ export const CreditPayment = ({
52
67
  handleSubmit,
53
68
  control,
54
69
  register,
55
- formState: { errors }
70
+ formState: { errors, isSubmitting }
56
71
  } = useForm({
57
72
  resolver: yupResolver(
58
73
  creditPaymentFormSchema(_translations.requiredFieldMessage)
59
- )
74
+ ) as any
60
75
  });
61
76
  const [formError, setFormError] = useState<string | null>(null);
77
+ const [isProcessing, setIsProcessing] = useState(false);
62
78
 
63
79
  const [setCreditPaymentOption] = useSetCreditPaymentOptionMutation();
64
- const [confirmationCreditPayment] = useConfirmationCreditPaymentMutation();
80
+ const [confirmationCreditPayment, { isLoading: isCompleting }] =
81
+ useConfirmationCreditPaymentMutation();
82
+
83
+ const isButtonDisabled = isSubmitting || isCompleting || isProcessing;
65
84
 
66
85
  const { creditPaymentOptions, selectedCreditPaymentPk, preOrder } =
67
86
  useAppSelector((state: RootState) => state.checkout);
68
87
 
69
88
  const onSubmit: SubmitHandler<any> = async () => {
70
- const response = await confirmationCreditPayment().unwrap();
89
+ if (isButtonDisabled) return;
90
+
91
+ setIsProcessing(true);
71
92
 
72
- if (response?.errors?.non_field_errors) {
73
- setFormError(response?.errors?.non_field_errors);
74
- return;
93
+ try {
94
+ const response = await confirmationCreditPayment().unwrap();
95
+
96
+ if (response?.errors?.non_field_errors) {
97
+ setFormError(response?.errors?.non_field_errors);
98
+ setIsProcessing(false);
99
+ return;
100
+ }
101
+
102
+ if (response?.errors || !checkPaymentWillRedirect(response)) {
103
+ setIsProcessing(false);
104
+ }
105
+ } catch (error) {
106
+ setIsProcessing(false);
75
107
  }
76
108
  };
77
109
 
@@ -86,6 +118,20 @@ export const CreditPayment = ({
86
118
  setCreditPaymentOption
87
119
  ]);
88
120
 
121
+ if (renderer?.Content) {
122
+ return renderer.Content({
123
+ control,
124
+ errors,
125
+ onSubmit: handleSubmit(onSubmit),
126
+ creditPaymentOptions,
127
+ selectedCreditPaymentPk,
128
+ setCreditPaymentOption,
129
+ preOrder,
130
+ agreementCheckbox,
131
+ formError
132
+ });
133
+ }
134
+
89
135
  return (
90
136
  <form className="flex flex-col w-full" onSubmit={handleSubmit(onSubmit)}>
91
137
  <div
@@ -132,9 +178,8 @@ export const CreditPayment = ({
132
178
  <div className="px-4 sm:px-6">
133
179
  <div className="flex items-start flex-col py-4 space-y-4">
134
180
  {agreementCheckbox &&
135
- React.cloneElement(agreementCheckbox, {
136
- // @ts-ignore
137
- control,
181
+ React.cloneElement(agreementCheckbox as any, {
182
+ control: control as any,
138
183
  error: errors.agreement,
139
184
  fieldId: 'agreement'
140
185
  })}
@@ -147,7 +192,8 @@ export const CreditPayment = ({
147
192
 
148
193
  <Button
149
194
  type="submit"
150
- data-testid="checkout-bank-account-place-order"
195
+ disabled={isButtonDisabled}
196
+ data-testid="checkout-credit-payment-button"
151
197
  className={clsx(
152
198
  twMerge(
153
199
  'group uppercase mt-4 inline-flex items-center justify-center w-full',