@akinon/projectzero 2.0.0-beta.13 → 2.0.0-beta.14

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,5 +1,7 @@
1
1
  # @akinon/projectzero
2
2
 
3
+ ## 2.0.0-beta.14
4
+
3
5
  ## 2.0.0-beta.13
4
6
 
5
7
  ## 1.118.0
@@ -1,5 +1,44 @@
1
1
  # projectzeronext
2
2
 
3
+ ## 2.0.0-beta.14
4
+
5
+ ### Minor Changes
6
+
7
+ - 6ad72e8d: ZERO-4032: Add loading state management for payment submissions across multiple components and add safe guarding
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [6ad72e8d]
12
+ - Updated dependencies [aef81c5d]
13
+ - Updated dependencies [0754c835]
14
+ - Updated dependencies [c6c5c1cd]
15
+ - @akinon/pz-pay-on-delivery@2.0.0-beta.14
16
+ - @akinon/pz-credit-payment@2.0.0-beta.14
17
+ - @akinon/pz-google-pay@2.0.0-beta.14
18
+ - @akinon/pz-masterpass@2.0.0-beta.14
19
+ - @akinon/pz-saved-card@2.0.0-beta.14
20
+ - @akinon/pz-apple-pay@2.0.0-beta.14
21
+ - @akinon/pz-hepsipay@2.0.0-beta.14
22
+ - @akinon/pz-gpay@2.0.0-beta.14
23
+ - @akinon/pz-bkm@2.0.0-beta.14
24
+ - @akinon/pz-otp@2.0.0-beta.14
25
+ - @akinon/next@2.0.0-beta.14
26
+ - @akinon/pz-virtual-try-on@2.0.0-beta.14
27
+ - @akinon/pz-akifast@2.0.0-beta.14
28
+ - @akinon/pz-b2b@2.0.0-beta.14
29
+ - @akinon/pz-basket-gift-pack@2.0.0-beta.14
30
+ - @akinon/pz-checkout-gift-pack@2.0.0-beta.14
31
+ - @akinon/pz-click-collect@2.0.0-beta.14
32
+ - @akinon/pz-cybersource-uc@2.0.0-beta.14
33
+ - @akinon/pz-flow-payment@2.0.0-beta.14
34
+ - @akinon/pz-haso@2.0.0-beta.14
35
+ - @akinon/pz-masterpass-rest@2.0.0-beta.14
36
+ - @akinon/pz-multi-basket@2.0.0-beta.14
37
+ - @akinon/pz-one-click-checkout@2.0.0-beta.14
38
+ - @akinon/pz-similar-products@2.0.0-beta.14
39
+ - @akinon/pz-tabby-extension@2.0.0-beta.14
40
+ - @akinon/pz-tamara-extension@2.0.0-beta.14
41
+
3
42
  ## 2.0.0-beta.13
4
43
 
5
44
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "projectzeronext",
3
- "version": "2.0.0-beta.13",
3
+ "version": "2.0.0-beta.14",
4
4
  "private": true,
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -24,32 +24,32 @@
24
24
  "test:middleware": "jest middleware-matcher.test.ts --bail"
25
25
  },
26
26
  "dependencies": {
27
- "@akinon/next": "2.0.0-beta.13",
28
- "@akinon/pz-akifast": "2.0.0-beta.13",
29
- "@akinon/pz-apple-pay": "2.0.0-beta.13",
30
- "@akinon/pz-b2b": "2.0.0-beta.13",
31
- "@akinon/pz-basket-gift-pack": "2.0.0-beta.13",
32
- "@akinon/pz-bkm": "2.0.0-beta.13",
33
- "@akinon/pz-checkout-gift-pack": "2.0.0-beta.13",
34
- "@akinon/pz-click-collect": "2.0.0-beta.13",
35
- "@akinon/pz-credit-payment": "2.0.0-beta.13",
36
- "@akinon/pz-cybersource-uc": "2.0.0-beta.13",
37
- "@akinon/pz-flow-payment": "2.0.0-beta.13",
38
- "@akinon/pz-google-pay": "2.0.0-beta.13",
39
- "@akinon/pz-gpay": "2.0.0-beta.13",
40
- "@akinon/pz-haso": "2.0.0-beta.13",
41
- "@akinon/pz-hepsipay": "2.0.0-beta.13",
42
- "@akinon/pz-masterpass": "2.0.0-beta.13",
43
- "@akinon/pz-masterpass-rest": "2.0.0-beta.13",
44
- "@akinon/pz-multi-basket": "2.0.0-beta.13",
45
- "@akinon/pz-one-click-checkout": "2.0.0-beta.13",
46
- "@akinon/pz-otp": "2.0.0-beta.13",
47
- "@akinon/pz-pay-on-delivery": "2.0.0-beta.13",
48
- "@akinon/pz-saved-card": "2.0.0-beta.13",
49
- "@akinon/pz-similar-products": "2.0.0-beta.13",
50
- "@akinon/pz-tabby-extension": "2.0.0-beta.13",
51
- "@akinon/pz-tamara-extension": "2.0.0-beta.13",
52
- "@akinon/pz-virtual-try-on": "2.0.0-beta.13",
27
+ "@akinon/next": "2.0.0-beta.14",
28
+ "@akinon/pz-akifast": "2.0.0-beta.14",
29
+ "@akinon/pz-apple-pay": "2.0.0-beta.14",
30
+ "@akinon/pz-b2b": "2.0.0-beta.14",
31
+ "@akinon/pz-basket-gift-pack": "2.0.0-beta.14",
32
+ "@akinon/pz-bkm": "2.0.0-beta.14",
33
+ "@akinon/pz-checkout-gift-pack": "2.0.0-beta.14",
34
+ "@akinon/pz-click-collect": "2.0.0-beta.14",
35
+ "@akinon/pz-credit-payment": "2.0.0-beta.14",
36
+ "@akinon/pz-cybersource-uc": "2.0.0-beta.14",
37
+ "@akinon/pz-flow-payment": "2.0.0-beta.14",
38
+ "@akinon/pz-google-pay": "2.0.0-beta.14",
39
+ "@akinon/pz-gpay": "2.0.0-beta.14",
40
+ "@akinon/pz-haso": "2.0.0-beta.14",
41
+ "@akinon/pz-hepsipay": "2.0.0-beta.14",
42
+ "@akinon/pz-masterpass": "2.0.0-beta.14",
43
+ "@akinon/pz-masterpass-rest": "2.0.0-beta.14",
44
+ "@akinon/pz-multi-basket": "2.0.0-beta.14",
45
+ "@akinon/pz-one-click-checkout": "2.0.0-beta.14",
46
+ "@akinon/pz-otp": "2.0.0-beta.14",
47
+ "@akinon/pz-pay-on-delivery": "2.0.0-beta.14",
48
+ "@akinon/pz-saved-card": "2.0.0-beta.14",
49
+ "@akinon/pz-similar-products": "2.0.0-beta.14",
50
+ "@akinon/pz-tabby-extension": "2.0.0-beta.14",
51
+ "@akinon/pz-tamara-extension": "2.0.0-beta.14",
52
+ "@akinon/pz-virtual-try-on": "2.0.0-beta.14",
53
53
  "@hookform/resolvers": "2.9.0",
54
54
  "@next/third-parties": "16.1.6",
55
55
  "@react-google-maps/api": "2.17.1",
@@ -72,7 +72,7 @@
72
72
  "yup": "0.32.11"
73
73
  },
74
74
  "devDependencies": {
75
- "@akinon/eslint-plugin-projectzero": "2.0.0-beta.13",
75
+ "@akinon/eslint-plugin-projectzero": "2.0.0-beta.14",
76
76
  "@semantic-release/changelog": "6.0.2",
77
77
  "@semantic-release/exec": "6.0.3",
78
78
  "@semantic-release/git": "10.0.1",
@@ -154,5 +154,10 @@
154
154
  "error": {
155
155
  "title": "An unexpected error has occurred. Please try again later.",
156
156
  "button": "Try Again"
157
+ },
158
+ "apple_pay": {
159
+ "processing": "Processing...",
160
+ "pay_button": "Pay with Apple Pay",
161
+ "payment_failed": "Payment failed"
157
162
  }
158
163
  }
@@ -154,5 +154,10 @@
154
154
  "error": {
155
155
  "title": "Beklenmeyen bir hata oluştu. Lütfen daha sonra tekrar deneyiniz.",
156
156
  "button": "Tekrar deneyin"
157
+ },
158
+ "apple_pay": {
159
+ "processing": "İşleniyor...",
160
+ "pay_button": "Apple Pay ile Öde",
161
+ "payment_failed": "Ödeme başarısız oldu"
157
162
  }
158
163
  }
@@ -16,7 +16,7 @@ import PaymentHeader from '../../payment-header';
16
16
  import CreditCardInstallments from './installments';
17
17
  import { useLocalization } from '@akinon/next/hooks';
18
18
  import { Image } from '@akinon/next/components/image';
19
- import { getPosError } from '@akinon/next/utils';
19
+ import { getPosError, checkPaymentWillRedirect } from '@akinon/next/utils';
20
20
  import PluginModule, { Component } from '@akinon/next/components/plugin-module';
21
21
  import { PaymentOption } from '@akinon/next/types';
22
22
 
@@ -101,7 +101,7 @@ const CheckoutCreditCard = () => {
101
101
  setValue: setFormValue,
102
102
  trigger: validateInput,
103
103
  control,
104
- formState: { errors },
104
+ formState: { errors, isSubmitting },
105
105
  setError,
106
106
  getValues,
107
107
  clearErrors
@@ -119,8 +119,12 @@ const CheckoutCreditCard = () => {
119
119
  const [years, setYears] = useState([]);
120
120
  const [formError, setFormError] = useState(null);
121
121
  const [cardBinNumber, setCardBinNumber] = useState(null);
122
+ const [isProcessing, setIsProcessing] = useState(false);
122
123
  const [setBinNumber] = useSetBinNumberMutation();
123
- const [completeCreditCardPayment] = useCompleteCreditCardPaymentMutation();
124
+ const [completeCreditCardPayment, { isLoading: isCompletingPayment }] =
125
+ useCompleteCreditCardPaymentMutation();
126
+
127
+ const isButtonDisabled = isSubmitting || isCompletingPayment || isProcessing;
124
128
 
125
129
  const handleCardNumberChange = (value) => {
126
130
  const binNumber = value.replace(/\D/g, '').substring(0, 6);
@@ -136,9 +140,20 @@ const CheckoutCreditCard = () => {
136
140
  };
137
141
 
138
142
  const onSubmit: SubmitHandler<CreditCardForm> = async (data) => {
139
- const response = await completeCreditCardPayment(data).unwrap();
143
+ if (isButtonDisabled) return;
144
+
145
+ setIsProcessing(true);
146
+
147
+ try {
148
+ const response = await completeCreditCardPayment(data).unwrap();
149
+ setFormError(response?.errors);
140
150
 
141
- setFormError(response?.errors);
151
+ if (response?.errors || !checkPaymentWillRedirect(response)) {
152
+ setIsProcessing(false);
153
+ }
154
+ } catch (error) {
155
+ setIsProcessing(false);
156
+ }
142
157
  };
143
158
 
144
159
  useEffect(() => {
@@ -392,6 +407,7 @@ const CheckoutCreditCard = () => {
392
407
  <Button
393
408
  className="group uppercase mt-4 inline-flex items-center justify-center"
394
409
  type="submit"
410
+ disabled={isButtonDisabled}
395
411
  data-testid="checkout-credit-card-place-order"
396
412
  >
397
413
  <span>{t('checkout.payment.credit_card.form.button')}</span>
@@ -12,6 +12,7 @@ import * as yup from 'yup';
12
12
  import CheckoutAgreements from '../agreements';
13
13
  import PaymentHeader from '../payment-header';
14
14
  import { useLocalization } from '@akinon/next/hooks';
15
+ import { checkPaymentWillRedirect } from '@akinon/next/utils';
15
16
  import { Image } from '@akinon/next/components/image';
16
17
  import { Trans } from '@akinon/next/components/trans';
17
18
 
@@ -25,21 +26,39 @@ const CheckoutFundsTransfer = () => {
25
26
  const {
26
27
  handleSubmit,
27
28
  control,
28
- formState: { errors }
29
+ formState: { errors, isSubmitting }
29
30
  } = useForm({
30
31
  resolver: yupResolver(fundsTransferFormSchema())
31
32
  });
32
33
  const [formError, setFormError] = useState(null);
34
+ const [isProcessing, setIsProcessing] = useState(false);
33
35
  const { bankAccounts, selectedBankAccountPk, preOrder } = useAppSelector(
34
36
  (state: RootState) => state.checkout
35
37
  );
36
38
  const [setFundsTransferOption] = useSetFundsTransferOptionMutation();
37
- const [completeFundsTransfer] = useCompleteFundsTransferMutation();
39
+ const [completeFundsTransfer, { isLoading: isCompletingPayment }] =
40
+ useCompleteFundsTransferMutation();
38
41
 
39
- const onSubmit: SubmitHandler<null> = async () => {
40
- const response = await completeFundsTransfer().unwrap();
42
+ const isButtonDisabled = isSubmitting || isCompletingPayment || isProcessing;
41
43
 
42
- setFormError(response?.errors?.non_field_errors);
44
+ const onSubmit: SubmitHandler<null> = async () => {
45
+ if (isButtonDisabled) return;
46
+
47
+ setIsProcessing(true);
48
+
49
+ try {
50
+ const response = await completeFundsTransfer().unwrap();
51
+ setFormError(response?.errors?.non_field_errors);
52
+
53
+ if (
54
+ response?.errors?.non_field_errors ||
55
+ !checkPaymentWillRedirect(response)
56
+ ) {
57
+ setIsProcessing(false);
58
+ }
59
+ } catch (error) {
60
+ setIsProcessing(false);
61
+ }
43
62
  };
44
63
 
45
64
  useEffect(() => {
@@ -155,6 +174,7 @@ const CheckoutFundsTransfer = () => {
155
174
  <Button
156
175
  className="group uppercase mt-4 inline-flex items-center justify-center w-full"
157
176
  type="submit"
177
+ disabled={isButtonDisabled}
158
178
  data-testid="checkout-bank-account-place-order"
159
179
  >
160
180
  <span> {t('checkout.payment.fund_transfer.button')}</span>
@@ -1,16 +1,35 @@
1
1
  'use client';
2
2
 
3
+ import { useState } from 'react';
3
4
  import { useCompleteLoyaltyPaymentMutation } from '@akinon/next/data/client/checkout';
4
5
  import { useAppSelector } from '@akinon/next/redux/hooks';
5
6
  import { useForm } from 'react-hook-form';
7
+ import { checkPaymentWillRedirect } from '@akinon/next/utils';
6
8
 
7
9
  export default function LoyaltyPayment() {
8
10
  const { payment_option } = useAppSelector((state) => state.checkout.preOrder);
9
11
  const { handleSubmit } = useForm();
10
- const [completeLoyaltyPayment] = useCompleteLoyaltyPaymentMutation();
12
+ const [completeLoyaltyPayment, { isLoading: isCompletingPayment }] =
13
+ useCompleteLoyaltyPaymentMutation();
14
+ const [isProcessing, setIsProcessing] = useState(false);
15
+
16
+ const isButtonDisabled = isCompletingPayment || isProcessing;
11
17
 
12
18
  const onSubmit = async () => {
13
- completeLoyaltyPayment();
19
+ if (isButtonDisabled) return;
20
+
21
+ setIsProcessing(true);
22
+
23
+ try {
24
+ const response = await completeLoyaltyPayment().unwrap();
25
+
26
+ if (response?.errors || !checkPaymentWillRedirect(response)) {
27
+ setIsProcessing(false);
28
+ }
29
+ } catch (error) {
30
+ console.error('Error completing loyalty payment:', error);
31
+ setIsProcessing(false);
32
+ }
14
33
  };
15
34
 
16
35
  return (
@@ -8,7 +8,7 @@ import { useForm } from 'react-hook-form';
8
8
  import { twMerge } from 'tailwind-merge';
9
9
  import * as yup from 'yup';
10
10
  import { useEffect, useState } from 'react';
11
- import { getPosError } from '@akinon/next/utils';
11
+ import { getPosError, checkPaymentWillRedirect } from '@akinon/next/utils';
12
12
  import { useMessageListener } from '@akinon/next/hooks';
13
13
 
14
14
  interface FormValues {
@@ -26,16 +26,33 @@ const formSchema = () =>
26
26
  export default function RedirectionPayment() {
27
27
  const { payment_option } = useAppSelector((state) => state.checkout.preOrder);
28
28
  const [formError, setFormError] = useState(null);
29
+ const [isProcessing, setIsProcessing] = useState(false);
29
30
  const {
30
31
  register,
31
32
  handleSubmit,
32
- formState: { errors }
33
+ formState: { errors, isSubmitting }
33
34
  } = useForm<FormValues>({
34
35
  resolver: yupResolver(formSchema())
35
36
  });
36
- const [completeRedirectionPayment] = useCompleteRedirectionPaymentMutation();
37
+ const [completeRedirectionPayment, { isLoading: isCompletingPayment }] =
38
+ useCompleteRedirectionPaymentMutation();
39
+
40
+ const isButtonDisabled = isSubmitting || isCompletingPayment || isProcessing;
41
+
37
42
  const onSubmit = async () => {
38
- completeRedirectionPayment();
43
+ if (isButtonDisabled) return;
44
+
45
+ setIsProcessing(true);
46
+
47
+ try {
48
+ const response = await completeRedirectionPayment().unwrap();
49
+
50
+ if (response?.errors || !checkPaymentWillRedirect(response)) {
51
+ setIsProcessing(false);
52
+ }
53
+ } catch (error) {
54
+ setIsProcessing(false);
55
+ }
39
56
  };
40
57
 
41
58
  useMessageListener();
@@ -91,6 +108,7 @@ export default function RedirectionPayment() {
91
108
 
92
109
  <Button
93
110
  data-testid="checkout-submit-button"
111
+ disabled={isButtonDisabled}
94
112
  className={twMerge('w-full md:w-36 px-4 md:px-0')}
95
113
  >
96
114
  {payment_option.name}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/projectzero",
3
- "version": "2.0.0-beta.13",
3
+ "version": "2.0.0-beta.14",
4
4
  "private": false,
5
5
  "description": "CLI tool to manage your Project Zero Next project",
6
6
  "bin": {