@akinon/pz-pay-on-delivery 2.0.0-beta.9 → 2.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/CHANGELOG.md CHANGED
@@ -1,45 +1,144 @@
1
1
  # @akinon/pz-pay-on-delivery
2
2
 
3
- ## 2.0.0-beta.9
3
+ ## 2.0.0
4
+
5
+ ## 2.0.0-beta.27
6
+
7
+ ## 2.0.0-beta.26
8
+
9
+ ## 2.0.0-beta.25
10
+
11
+ ## 2.0.0-beta.24
12
+
13
+ ## 2.0.0-beta.23
14
+
15
+ ## 2.0.0-beta.22
16
+
17
+ ## 2.0.0-beta.21
18
+
19
+ ## 2.0.0-beta.20
20
+
21
+ ## 1.126.0
22
+
23
+ ## 1.125.2
24
+
25
+ ## 1.125.1
26
+
27
+ ## 1.125.0
28
+
29
+ ## 1.124.0
30
+
31
+ ## 1.123.0
32
+
33
+ ## 1.122.0
34
+
35
+ ## 1.121.0
36
+
37
+ ## 1.120.0
4
38
 
5
39
  ### Minor Changes
6
40
 
7
- - 0fe7711: ZERO-3387: Upgrade nextjs, eslint-config-next
41
+ - 6ad72e8d: ZERO-4032: Add loading state management for payment submissions across multiple components and add safe guarding
42
+
43
+ ## 1.119.0
44
+
45
+ ## 1.118.0
46
+
47
+ ## 1.117.0
48
+
49
+ ## 1.116.0
50
+
51
+ ## 1.115.0
52
+
53
+ ## 1.114.0
54
+
55
+ ## 1.113.0
56
+
57
+ ## 1.112.0
8
58
 
9
- ## 2.0.0-beta.8
59
+ ## 1.111.0
10
60
 
11
- ## 2.0.0-beta.7
61
+ ## 1.110.0
12
62
 
13
- ## 2.0.0-beta.6
63
+ ## 1.109.0
64
+
65
+ ## 1.108.0
66
+
67
+ ## 1.107.0
68
+
69
+ ## 1.106.0
70
+
71
+ ## 1.105.0
72
+
73
+ ## 1.104.0
74
+
75
+ ## 1.103.0
14
76
 
15
77
  ### Minor Changes
16
78
 
17
- - 8f05f9b: ZERO-3250: Beta branch synchronized with Main branch
79
+ - d0853b3: ZERO-2844 :Add README for PayOnDelivery component with installation and usage instructions
18
80
 
19
- ## 2.0.0-beta.5
81
+ ## 1.102.0
20
82
 
21
- ## 2.0.0-beta.4
83
+ ## 1.101.0
22
84
 
23
- ## 2.0.0-beta.3
85
+ ## 1.100.0
24
86
 
25
- ## 2.0.0-beta.2
87
+ ## 1.99.0
26
88
 
27
89
  ### Minor Changes
28
90
 
29
- - a006015: ZERO-3116: Add not-found page and update default middleware.
30
- - 1eeb3d8: ZERO-3116: Add not found page
91
+ - d58538b: ZERO-3638: Enhance RC pipeline: add fetch, merge, and pre-release setup with conditional commit
92
+
93
+ ## 1.98.0
94
+
95
+ ## 1.97.0
96
+
97
+ ## 1.96.0
98
+
99
+ ## 1.95.0
100
+
101
+ ## 1.94.0
102
+
103
+ ## 1.93.0
104
+
105
+ ## 1.92.0
31
106
 
32
- ## 2.0.0-beta.1
107
+ ## 1.91.0
108
+
109
+ ## 1.90.0
33
110
 
34
111
  ### Minor Changes
35
112
 
36
- - ZERO-3091: Upgrade Next.js to v15 and React to v19
113
+ - d662786: ZERO-3371: Refactor Pay On Delivery component
114
+
115
+ ## 1.89.0
116
+
117
+ ## 1.88.0
118
+
119
+ ## 1.87.0
120
+
121
+ ## 1.86.0
122
+
123
+ ## 1.85.0
124
+
125
+ ## 1.84.0
126
+
127
+ ## 1.83.0
128
+
129
+ ## 1.82.0
130
+
131
+ ## 1.81.0
132
+
133
+ ## 1.80.0
134
+
135
+ ## 1.79.0
37
136
 
38
- ## 2.0.0-beta.0
137
+ ## 1.78.0
39
138
 
40
- ### Major Changes
139
+ ## 1.77.0
41
140
 
42
- - be6c09d: ZERO-3114: Create beta version.
141
+ ## 1.76.0
43
142
 
44
143
  ## 1.75.0
45
144
 
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@akinon/pz-pay-on-delivery",
3
- "version": "2.0.0-beta.9",
3
+ "version": "2.0.0",
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.5",
15
+ "react-dom": "19.2.5",
16
+ "typescript": "^4.7.4",
17
17
  "react-hook-form": "7.31.3",
18
18
  "@hookform/resolvers": "2.9.0"
19
19
  }
package/readme.md ADDED
@@ -0,0 +1,130 @@
1
+ # @akinon/pz-pay-on-delivery
2
+
3
+ ## Installation method
4
+
5
+ You can use the following command to install the extension with the latest plugins:
6
+
7
+ ```bash
8
+ npx @akinon/projectzero@latest --plugins
9
+ ```
10
+
11
+ ## PayOnDelivery
12
+
13
+ A customizable React component that enables customers to select a "Pay on Delivery" payment method during checkout and confirm their agreement to terms before placing the order.
14
+
15
+ ---
16
+
17
+ ### Props
18
+
19
+ #### `PayOnDeliveryProps`
20
+
21
+ | Prop | Type | Required | Description |
22
+ | --- | --- | --- | --- |
23
+ | `translations` | `Record<string, PayOnDeliveryTranslationsProps>` | Optional | Localization texts for section titles, labels, and error messages |
24
+ | `agreementCheckbox` | `React.ReactElement` | Optional | A controlled checkbox React element (e.g., terms agreement checkbox) |
25
+ | `customUIRender` | `(props: RenderProps) => React.ReactNode` | Optional | Override default UI rendering with your own layout and logic |
26
+
27
+ ---
28
+
29
+ #### `PayOnDeliveryTranslationsProps`
30
+
31
+ | Key | Type | Description |
32
+ | ---------------------------- | -------- | ------------------------------ |
33
+ | `paymentInformationTitle` | `string` | Main section title |
34
+ | `paymentInformationSubtitle` | `string` | Subtitle for available options |
35
+ | `totalAmountText` | `string` | Label for total amount display |
36
+ | `serviceFeeText` | `string` | Label for service fee info |
37
+ | `returnInfoText` | `string` | Text about return process |
38
+ | `refundInfoText` | `string` | Text about refund process |
39
+ | `faqInfoText` | `string` | Link/label for FAQ section |
40
+ | `placeOrderText` | `string` | Button text |
41
+ | `errorMessageText` | `string` | API error display text |
42
+ | `requiredFieldMessage` | `string` | Field validation error message |
43
+
44
+ ---
45
+
46
+ #### RenderProps (for `customUIRender`)
47
+
48
+ | Prop | Type | Description |
49
+ | --- | --- | --- | --- |
50
+ | `handleSubmit` | `UseFormHandleSubmit` | Form submit handler |
51
+ | `onSubmit` | `SubmitHandler<PayOnDeliveryForm>` | Submit function |
52
+ | `register` | `UseFormRegister<PayOnDeliveryForm>` | Form field registrar |
53
+ | `control` | `Control<PayOnDeliveryForm>` | React Hook Form control instance |
54
+ | `errors` | `FieldErrors<PayOnDeliveryForm>` | Validation errors |
55
+ | `paymentChoices` | `any[]` | List of available payment choices |
56
+ | `preOrder` | `RootState['checkout']['preOrder']` | PreOrder data from Redux |
57
+ | `formError` | `string | null` | API error messages |
58
+ | `isLoading` | `boolean` | Loading state |
59
+ | `setPayOnDeliveryChoice` | `(value: string) => void` | Function to update payment selection |
60
+
61
+ ---
62
+
63
+ ## Usage
64
+
65
+ ```bash
66
+ src/views/checkout/steps/payment/options/pay-on-delivery/
67
+ ```
68
+
69
+ ---
70
+
71
+ ### Default Usage
72
+
73
+ ```tsx
74
+ <PluginModule
75
+ component={Component.PayOnDelivery}
76
+ props={{
77
+ agreementCheckbox: (
78
+ <CheckoutAgreements control={null} error={null} fieldId="agreement" />
79
+ )
80
+ }}
81
+ />
82
+ ```
83
+
84
+ ---
85
+
86
+ ### Customized Usage with `customUIRender`
87
+
88
+ ```tsx
89
+ <PluginModule
90
+ component={Component.PayOnDelivery}
91
+ props={{
92
+ customUIRender: ({
93
+ handleSubmit,
94
+ onSubmit,
95
+ control,
96
+ errors,
97
+ setPayOnDeliveryChoice,
98
+ paymentChoices,
99
+ preOrder,
100
+ formError
101
+ }) => (
102
+ <form
103
+ onSubmit={handleSubmit(onSubmit)}
104
+ className="p-6 bg-white rounded-lg space-y-6"
105
+ >
106
+ <h2 className="text-xl font-semibold">PAY ON DELIVERY</h2>
107
+ <div className="space-y-4">
108
+ {paymentChoices.map((choice) => (
109
+ <label key={choice.value} className="flex items-center space-x-4">
110
+ <Radio
111
+ type="radio"
112
+ value={choice.value}
113
+ checked={choice.value === preOrder.payment_choice?.value}
114
+ onChange={() => setPayOnDeliveryChoice(choice.value)}
115
+ />
116
+ <span>{choice.label}</span>
117
+ </label>
118
+ ))}
119
+ </div>
120
+ {formError && <p className="text-xs text-error mt-2">{formError}</p>}
121
+ <Button type="submit" className="w-full bg-black text-white">
122
+ Place Order
123
+ </Button>
124
+ </form>
125
+ )
126
+ }}
127
+ />
128
+ ```
129
+
130
+ ---
package/src/endpoints.ts CHANGED
@@ -15,7 +15,6 @@ interface CheckoutResponse {
15
15
  }
16
16
 
17
17
  export interface PayOnDeliveryParams {
18
- agreement: string;
19
18
  paymentType: string;
20
19
  }
21
20
 
package/src/index.tsx CHANGED
@@ -1,8 +1,16 @@
1
1
  import { useAppSelector } from '@akinon/next/redux/hooks';
2
2
  import { yupResolver } from '@hookform/resolvers/yup';
3
3
  import { Button, Icon, Price, Radio } from '@akinon/next/components';
4
+ import { checkPaymentWillRedirect } from '@akinon/next/utils';
4
5
  import React, { useEffect, useState } from 'react';
5
- import { SubmitHandler, useForm } from 'react-hook-form';
6
+ import {
7
+ SubmitHandler,
8
+ useForm,
9
+ UseFormHandleSubmit,
10
+ UseFormRegister,
11
+ Control,
12
+ FieldErrors
13
+ } from 'react-hook-form';
6
14
  import { RootState } from 'redux/store';
7
15
  import * as yup from 'yup';
8
16
  import {
@@ -10,6 +18,11 @@ import {
10
18
  useSetPayOnDeliveryChoiceMutation
11
19
  } from './endpoints';
12
20
 
21
+ interface PayOnDeliveryForm {
22
+ agreement: boolean;
23
+ paymentType: string;
24
+ }
25
+
13
26
  interface PayOnDeliveryTranslationsProps {
14
27
  paymentInformationTitle: string;
15
28
  paymentInformationSubtitle: string;
@@ -43,59 +56,77 @@ const defaultTranslations = {
43
56
  interface PayOnDeliveryProps {
44
57
  translations: Record<string, PayOnDeliveryTranslationsProps>;
45
58
  agreementCheckbox?: React.ReactElement;
59
+ customUIRender?: (props: {
60
+ handleSubmit: UseFormHandleSubmit<PayOnDeliveryForm>;
61
+ onSubmit: SubmitHandler<any>;
62
+ paymentChoices: any[];
63
+ preOrder: any;
64
+ formError: string | null;
65
+ isLoading: boolean;
66
+ register: UseFormRegister<PayOnDeliveryForm>;
67
+ control: Control<PayOnDeliveryForm>;
68
+ errors: FieldErrors<PayOnDeliveryForm>;
69
+ setPayOnDeliveryChoice: (value: string) => void;
70
+ }) => React.ReactNode;
46
71
  }
47
72
 
48
73
  export const PayOnDelivery = ({
49
74
  translations,
50
- agreementCheckbox
75
+ agreementCheckbox,
76
+ customUIRender
51
77
  }: PayOnDeliveryProps) => {
52
78
  const _translations = {
53
79
  ...defaultTranslations,
54
80
  ...translations
55
81
  };
56
82
 
57
- const createPayOnDeliveryFormSchema = (
58
- _translations: PayOnDeliveryTranslationsProps
59
- ) => {
60
- return yup.object().shape({
61
- agreement: yup
62
- .boolean()
63
- .oneOf([true], _translations.requiredFieldMessage),
64
- paymentType: yup.string()
65
- });
66
- };
67
-
68
- const payOnDeliveryFormSchema = createPayOnDeliveryFormSchema(_translations);
83
+ const payOnDeliveryFormSchema = yup.object().shape({
84
+ agreement: yup.boolean().oneOf([true], _translations.requiredFieldMessage),
85
+ paymentType: yup.string()
86
+ });
69
87
 
70
88
  const {
71
89
  handleSubmit,
72
90
  control,
73
91
  register,
74
- formState: { errors },
92
+ formState: { errors, isSubmitting },
75
93
  setValue
76
- } = useForm({
77
- resolver: yupResolver(payOnDeliveryFormSchema)
94
+ } = useForm<PayOnDeliveryForm>({
95
+ resolver: yupResolver(payOnDeliveryFormSchema) as any
78
96
  });
79
97
 
80
- const [setCompletePayOnDelivery] = useSetCompletePayOnDeliveryMutation();
81
-
98
+ const [setCompletePayOnDelivery, { isLoading: isCompleting }] =
99
+ useSetCompletePayOnDeliveryMutation();
82
100
  const [setPayOnDeliveryPaymentChoice, { isLoading }] =
83
101
  useSetPayOnDeliveryChoiceMutation();
84
102
  const [formError, setFormError] = useState(null);
103
+ const [isProcessing, setIsProcessing] = useState(false);
104
+
105
+ const isButtonDisabled = isSubmitting || isCompleting || isProcessing;
85
106
 
86
107
  const { preOrder, paymentChoices } = useAppSelector(
87
108
  (state: RootState) => state.checkout
88
109
  );
89
110
 
90
- const onSubmit: SubmitHandler<null> = async (data) => {
91
- const response = await setCompletePayOnDelivery(data).unwrap();
111
+ const onSubmit: SubmitHandler<PayOnDeliveryForm> = async (data) => {
112
+ if (isButtonDisabled) return;
92
113
 
93
- setFormError(response?.errors?.non_field_errors);
114
+ setIsProcessing(true);
115
+
116
+ try {
117
+ const response = await setCompletePayOnDelivery(data).unwrap();
118
+ setFormError(response?.errors?.non_field_errors);
119
+
120
+ if (response?.errors || !checkPaymentWillRedirect(response)) {
121
+ setIsProcessing(false);
122
+ }
123
+ } catch (error) {
124
+ setIsProcessing(false);
125
+ }
94
126
  };
95
127
 
96
128
  const setPayOnDeliveryChoice = async (value: string) => {
97
129
  if (isLoading) return;
98
-
99
130
  const response = await setPayOnDeliveryPaymentChoice(value).unwrap();
100
131
  setFormError(response?.errors?.non_field_errors);
101
132
  };
@@ -108,6 +139,21 @@ export const PayOnDelivery = ({
108
139
  }
109
140
  }, [paymentChoices, preOrder?.payment_choice]);
110
141
 
142
+ if (customUIRender) {
143
+ return customUIRender({
144
+ handleSubmit,
145
+ onSubmit,
146
+ register,
147
+ control,
148
+ errors,
149
+ paymentChoices,
150
+ preOrder,
151
+ formError,
152
+ isLoading: isButtonDisabled,
153
+ setPayOnDeliveryChoice
154
+ });
155
+ }
156
+
111
157
  return (
112
158
  <form
113
159
  id="pay_on_delivery"
@@ -163,9 +209,8 @@ export const PayOnDelivery = ({
163
209
  <div className="px-4 sm:px-6">
164
210
  <div className="flex items-start flex-col border-solid border-gray-400 py-4 space-y-4">
165
211
  {agreementCheckbox &&
166
- React.cloneElement(agreementCheckbox, {
167
- // @ts-ignore
168
- control,
212
+ React.cloneElement(agreementCheckbox as any, {
213
+ control: control as any,
169
214
  error: errors.agreement,
170
215
  fieldId: 'agreement'
171
216
  })}
@@ -178,6 +223,7 @@ export const PayOnDelivery = ({
178
223
  <Button
179
224
  className="group uppercase mt-4 inline-flex items-center justify-center w-full"
180
225
  type="submit"
226
+ disabled={isButtonDisabled}
181
227
  data-testid="checkout-bank-account-place-order"
182
228
  >
183
229
  <span>{_translations.placeOrderText}</span>