@akinon/projectzero 2.0.0-beta.12 → 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 +102 -23
- package/app-template/.env.example +1 -0
- package/app-template/.github/instructions/account.instructions.md +749 -0
- package/app-template/.github/instructions/checkout.instructions.md +678 -0
- package/app-template/.github/instructions/default.instructions.md +279 -0
- package/app-template/.github/instructions/edge-cases.instructions.md +73 -0
- package/app-template/.github/instructions/routing.instructions.md +603 -0
- package/app-template/.github/instructions/settings.instructions.md +338 -0
- package/app-template/.gitignore +3 -0
- package/app-template/AGENTS.md +7 -0
- package/app-template/CHANGELOG.md +1387 -310
- package/app-template/Procfile +1 -1
- package/app-template/akinon.json +0 -3
- package/app-template/build.sh +10 -0
- package/app-template/docs/advanced-usage.md +101 -0
- package/app-template/docs/sentry-usage.md +35 -0
- package/app-template/next-env.d.ts +1 -0
- package/app-template/{next.config.ts → next.config.mjs} +6 -6
- package/app-template/package.json +58 -51
- package/app-template/postcss.config.mjs +1 -4
- package/app-template/public/locales/en/checkout.json +11 -0
- package/app-template/public/locales/en/common.json +50 -1
- package/app-template/public/locales/en/product.json +62 -1
- package/app-template/public/locales/tr/checkout.json +11 -0
- package/app-template/public/locales/tr/common.json +50 -1
- package/app-template/public/locales/tr/product.json +63 -0
- package/app-template/public/masterpass-javascript-sdk-web.min.js +1 -0
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/[...prettyurl]/page.tsx +9 -9
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/layout.tsx +2 -2
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/orders/[id]/cancellation/page.tsx +6 -6
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/orders/[id]/page.tsx +6 -6
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/page.tsx +1 -1
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/profile/page.tsx +2 -2
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/address/stores/page.tsx +2 -2
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/auth/page.tsx +1 -1
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/basket/page.tsx +2 -2
- package/app-template/src/app/[pz]/category/[pk]/page.tsx +27 -0
- package/app-template/src/app/[pz]/flat-page/[pk]/page.tsx +23 -0
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/forms/[pk]/generate/page.tsx +2 -3
- package/app-template/src/app/[pz]/group-product/[pk]/page.tsx +93 -0
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/landing-page/[pk]/page.tsx +2 -4
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/layout.tsx +3 -10
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/list/page.tsx +2 -4
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/not-found.tsx +5 -7
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/orders/completed/[token]/page.tsx +6 -4
- package/app-template/src/app/[pz]/product/[pk]/page.tsx +102 -0
- package/app-template/src/app/[pz]/special-page/[pk]/page.tsx +35 -0
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/users/email-set-primary/[[...id]]/page.tsx +3 -4
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/users/registration/account-confirm-email/[[...id]]/page.tsx +3 -3
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/users/reset/[[...id]]/page.tsx +6 -12
- package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/xml-sitemap/[node]/route.ts +2 -2
- package/app-template/src/app/api/auth/[...nextauth]/route.ts +3 -0
- package/app-template/src/app/api/form/[...id]/route.ts +1 -7
- package/app-template/src/app/api/image-proxy/route.ts +1 -0
- package/app-template/src/app/api/product-categories/route.ts +1 -0
- package/app-template/src/app/api/similar-product-list/route.ts +1 -0
- package/app-template/src/app/api/similar-products/route.ts +1 -0
- package/app-template/src/app/api/virtual-try-on/limited-categories/route.ts +1 -0
- package/app-template/src/app/api/virtual-try-on/route.ts +1 -0
- package/app-template/src/assets/globals.scss +4 -133
- package/app-template/src/auth.ts +3 -0
- package/app-template/src/components/__tests__/badge.test.tsx +2 -2
- package/app-template/src/components/__tests__/link.test.tsx +2 -0
- package/app-template/src/components/accordion.tsx +23 -20
- package/app-template/src/components/button.tsx +1 -1
- package/app-template/src/components/carousel-core.tsx +4 -11
- package/app-template/src/components/checkbox.tsx +1 -1
- package/app-template/src/components/currency-select.tsx +1 -0
- package/app-template/src/components/file-input.tsx +27 -7
- package/app-template/src/components/generate-form-fields.tsx +49 -10
- package/app-template/src/components/input.tsx +11 -5
- package/app-template/src/components/modal.tsx +32 -16
- package/app-template/src/components/pagination.tsx +1 -0
- package/app-template/src/components/price.tsx +1 -1
- package/app-template/src/components/pwa-tags.tsx +1 -0
- package/app-template/src/components/select.tsx +39 -27
- package/app-template/src/components/shimmer.tsx +1 -1
- package/app-template/src/components/types/index.ts +25 -1
- package/app-template/src/hooks/use-fav-button.tsx +4 -8
- package/app-template/src/hooks/use-product-cart.ts +77 -0
- package/app-template/src/hooks/use-stock-alert.ts +74 -0
- package/app-template/src/plugins.js +12 -2
- package/app-template/src/redux/middlewares/category.ts +5 -4
- package/app-template/src/redux/store.ts +21 -1
- package/app-template/src/routes/index.ts +2 -1
- package/app-template/src/settings.js +3 -1
- package/app-template/src/types/index.ts +74 -3
- package/app-template/src/types/next-auth.d.ts +2 -2
- package/app-template/src/utils/variant-validation.ts +41 -0
- package/app-template/src/views/account/address-form.tsx +8 -4
- package/app-template/src/views/account/contact-form.tsx +2 -2
- package/app-template/src/views/account/content-header.tsx +4 -3
- package/app-template/src/views/account/faq/faq-tabs.tsx +8 -2
- package/app-template/src/views/account/order.tsx +1 -1
- package/app-template/src/views/account/orders/order-cancellation-item.tsx +1 -1
- package/app-template/src/views/anonymous-tracking/order-detail/index.tsx +1 -1
- package/app-template/src/views/basket/basket-item.tsx +6 -1
- package/app-template/src/views/basket/summary.tsx +16 -0
- package/app-template/src/views/breadcrumb.tsx +2 -2
- package/app-template/src/views/category/category-info.tsx +2 -1
- package/app-template/src/views/category/filters/index.tsx +1 -1
- package/app-template/src/views/checkout/auth.tsx +1 -1
- package/app-template/src/views/checkout/layout/header.tsx +1 -1
- package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +22 -6
- package/app-template/src/views/checkout/steps/payment/options/funds-transfer.tsx +25 -5
- package/app-template/src/views/checkout/steps/payment/options/loyalty.tsx +21 -2
- package/app-template/src/views/checkout/steps/payment/options/redirection.tsx +22 -4
- package/app-template/src/views/checkout/steps/payment/options/store-credit.tsx +121 -0
- package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +4 -4
- package/app-template/src/views/checkout/steps/shipping/address-box.tsx +3 -3
- package/app-template/src/views/checkout/steps/shipping/addresses.tsx +1 -1
- package/app-template/src/views/checkout/summary.tsx +12 -2
- package/app-template/src/views/find-in-store/index.tsx +2 -2
- package/app-template/src/views/header/action-menu.tsx +2 -6
- package/app-template/src/views/header/band.tsx +2 -2
- package/app-template/src/views/header/index.tsx +1 -1
- package/app-template/src/views/header/mini-basket.tsx +2 -2
- package/app-template/src/views/header/mobile-menu.tsx +6 -6
- package/app-template/src/views/header/navbar.tsx +1 -1
- package/app-template/src/views/header/pwa-back-button.tsx +1 -1
- package/app-template/src/views/header/search/index.tsx +13 -3
- package/app-template/src/views/header/search/results.tsx +1 -1
- package/app-template/src/views/header/user-menu.tsx +1 -3
- package/app-template/src/views/login/index.tsx +14 -13
- package/app-template/src/views/otp-login/index.tsx +11 -6
- package/app-template/src/views/product/layout.tsx +15 -1
- package/app-template/src/views/product/product-actions.tsx +165 -0
- package/app-template/src/views/product/product-info.tsx +69 -261
- package/app-template/src/views/product/product-share.tsx +56 -0
- package/app-template/src/views/product/product-variants.tsx +26 -0
- package/app-template/src/views/product/slider.tsx +22 -1
- package/app-template/src/views/product-pointer-banner-item.tsx +1 -1
- package/app-template/src/views/register/index.tsx +17 -21
- package/app-template/src/views/sales-contract-modal/index.tsx +17 -17
- package/app-template/src/widgets/footer-info.tsx +1 -1
- package/app-template/src/widgets/footer-menu.tsx +7 -3
- package/app-template/src/widgets/footer-subscription/index.tsx +1 -1
- package/app-template/src/widgets/home-stories-eng.tsx +43 -35
- package/app-template/tailwind.config.js +129 -1
- package/app-template/tsconfig.json +29 -11
- package/codemods/migrate-segments/index.js +591 -0
- package/commands/plugins.ts +62 -14
- package/dist/commands/plugins.js +62 -14
- package/package.json +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/category/[pk]/page.tsx +0 -22
- package/app-template/src/app/[commerce]/[locale]/[currency]/flat-page/[pk]/page.tsx +0 -20
- package/app-template/src/app/[commerce]/[locale]/[currency]/group-product/[pk]/page.tsx +0 -74
- package/app-template/src/app/[commerce]/[locale]/[currency]/product/[pk]/page.tsx +0 -84
- package/app-template/src/app/[commerce]/[locale]/[currency]/special-page/[pk]/page.tsx +0 -27
- package/app-template/src/pages/api/auth/[...nextauth].ts +0 -3
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/address/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/change-email/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/change-password/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/contact/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/coupons/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/email-verification/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/faq/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/favourite-products/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/my-quotations/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/orders/[id]/layout.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/account/orders/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/anonymous-tracking/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/auth/oauth-login/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/basket-b2b/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/category/[pk]/loading.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/client-root.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/contact-us/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/error.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/flat-page/[pk]/loading.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/group-product/[pk]/loading.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/landing-page/[pk]/loading.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/list/loading.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/orders/checkout/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/orders/completed/[token]/layout.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/special-page/[pk]/loading.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/template.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/users/password/reset/page.tsx +0 -0
- /package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/xml-sitemap/route.ts +0 -0
|
@@ -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] =
|
|
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
|
-
|
|
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
|
-
|
|
151
|
+
if (response?.errors || !checkPaymentWillRedirect(response)) {
|
|
152
|
+
setIsProcessing(false);
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
setIsProcessing(false);
|
|
156
|
+
}
|
|
142
157
|
};
|
|
143
158
|
|
|
144
159
|
useEffect(() => {
|
|
@@ -319,7 +334,7 @@ const CheckoutCreditCard = () => {
|
|
|
319
334
|
size={16}
|
|
320
335
|
className="leading-none ml-2"
|
|
321
336
|
/>
|
|
322
|
-
<div className="hidden group-hover:block absolute right-0 bottom-5 w-[11rem] lg:w-[21rem] lg:left-auto lg:right-auto border-2
|
|
337
|
+
<div className="hidden group-hover:block absolute right-0 bottom-5 w-[11rem] lg:w-[21rem] lg:left-auto lg:right-auto border-2">
|
|
323
338
|
{/* TODO: Fix this */}
|
|
324
339
|
<Image
|
|
325
340
|
src="/cvv.jpg"
|
|
@@ -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] =
|
|
39
|
+
const [completeFundsTransfer, { isLoading: isCompletingPayment }] =
|
|
40
|
+
useCompleteFundsTransferMutation();
|
|
38
41
|
|
|
39
|
-
const
|
|
40
|
-
const response = await completeFundsTransfer().unwrap();
|
|
42
|
+
const isButtonDisabled = isSubmitting || isCompletingPayment || isProcessing;
|
|
41
43
|
|
|
42
|
-
|
|
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] =
|
|
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
|
-
|
|
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] =
|
|
37
|
+
const [completeRedirectionPayment, { isLoading: isCompletingPayment }] =
|
|
38
|
+
useCompleteRedirectionPaymentMutation();
|
|
39
|
+
|
|
40
|
+
const isButtonDisabled = isSubmitting || isCompletingPayment || isProcessing;
|
|
41
|
+
|
|
37
42
|
const onSubmit = async () => {
|
|
38
|
-
|
|
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}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import {
|
|
3
|
+
useGetCheckoutLoyaltyBalanceQuery,
|
|
4
|
+
usePayWithLoyaltyBalanceMutation
|
|
5
|
+
} from '@akinon/next/data/client/checkout';
|
|
6
|
+
import { useAppSelector } from '@akinon/next/redux/hooks';
|
|
7
|
+
import { useMemo, useState } from 'react';
|
|
8
|
+
import { useLocalization } from '@akinon/next/hooks';
|
|
9
|
+
import { twMerge } from 'tailwind-merge';
|
|
10
|
+
import { Icon, Price } from '@theme/components';
|
|
11
|
+
import { Trans } from '@akinon/next/components';
|
|
12
|
+
import { LoaderSpinner } from '@theme/components';
|
|
13
|
+
|
|
14
|
+
export const StoreCredits = () => {
|
|
15
|
+
const { t } = useLocalization();
|
|
16
|
+
|
|
17
|
+
const [payWithLoyaltyBalance, { isLoading: isPayWithLoyaltyBalanceLoading }] =
|
|
18
|
+
usePayWithLoyaltyBalanceMutation();
|
|
19
|
+
|
|
20
|
+
const { loyaltyBalance, preOrder } = useAppSelector(
|
|
21
|
+
(state) => state.checkout
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const { isLoading: isLoyaltyBalanceLoading } =
|
|
25
|
+
useGetCheckoutLoyaltyBalanceQuery(undefined, {
|
|
26
|
+
refetchOnMountOrArgChange: true,
|
|
27
|
+
skip: !preOrder?.payment_option
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const isLoyaltyBalanceUsed = useMemo(() => {
|
|
31
|
+
return parseFloat(preOrder?.loyalty_money ?? '0') > 0;
|
|
32
|
+
}, [preOrder?.loyalty_money]);
|
|
33
|
+
|
|
34
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
35
|
+
|
|
36
|
+
const handleClick = async () => {
|
|
37
|
+
if (isLoading) return;
|
|
38
|
+
setIsLoading(true);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
await payWithLoyaltyBalance(isLoyaltyBalanceUsed ? '0' : loyaltyBalance);
|
|
42
|
+
} finally {
|
|
43
|
+
setIsLoading(false);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (preOrder?.is_guest) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isLoyaltyBalanceLoading) {
|
|
52
|
+
return (
|
|
53
|
+
<div className="mb-3 px-4 py-3 xs:px-0">
|
|
54
|
+
<LoaderSpinner />
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (parseFloat(loyaltyBalance) <= 0) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return (
|
|
63
|
+
<div
|
|
64
|
+
className={twMerge(
|
|
65
|
+
'hidden flex-col w-full mb-4 border border-solid border-gray-400 px-0 md:p-4',
|
|
66
|
+
isPayWithLoyaltyBalanceLoading && 'pointer-events-none opacity-30',
|
|
67
|
+
parseFloat(loyaltyBalance) > 0 && 'block'
|
|
68
|
+
)}
|
|
69
|
+
>
|
|
70
|
+
<div className="flex w-full items-center">
|
|
71
|
+
<button onClick={handleClick}>
|
|
72
|
+
<span
|
|
73
|
+
className={clsx(
|
|
74
|
+
'flex h-5 w-5 items-center justify-center rounded border border-solid border-primary',
|
|
75
|
+
isLoyaltyBalanceUsed ? 'bg-primary' : 'bg-white'
|
|
76
|
+
)}
|
|
77
|
+
>
|
|
78
|
+
<Icon
|
|
79
|
+
name={isLoyaltyBalanceUsed ? 'check' : ''}
|
|
80
|
+
size={10}
|
|
81
|
+
className={clsx({ 'text-white': isLoyaltyBalanceUsed })}
|
|
82
|
+
/>
|
|
83
|
+
</span>
|
|
84
|
+
</button>
|
|
85
|
+
|
|
86
|
+
<div className="w-full pl-4">
|
|
87
|
+
<p className="cursor-pointer text-sm" onClick={handleClick}>
|
|
88
|
+
{t('checkout.payment.store_credit.use_my_store_credits')}
|
|
89
|
+
</p>
|
|
90
|
+
<p className="flex text-sm text-[#606060]">
|
|
91
|
+
{t('checkout.payment.store_credit.available_balance')}:
|
|
92
|
+
<Price
|
|
93
|
+
value={loyaltyBalance}
|
|
94
|
+
currencyCode={preOrder?.currency_type_label}
|
|
95
|
+
className="pe-1 font-bold"
|
|
96
|
+
/>
|
|
97
|
+
</p>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
{isLoyaltyBalanceUsed && parseFloat(preOrder?.unpaid_amount) > 0 && (
|
|
102
|
+
<p className="my-4 text-[15px] font-light italic text-[#707070] max-xs:text-xs">
|
|
103
|
+
<Trans
|
|
104
|
+
i18nKey="checkout.payment.store_credit.insufficient_balance"
|
|
105
|
+
components={{
|
|
106
|
+
Amount: (
|
|
107
|
+
<div className="inline-flex">
|
|
108
|
+
<Price
|
|
109
|
+
value={preOrder?.unpaid_amount}
|
|
110
|
+
currencyCode={preOrder?.currency_type_label}
|
|
111
|
+
className="text-primary"
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
)
|
|
115
|
+
}}
|
|
116
|
+
/>
|
|
117
|
+
</p>
|
|
118
|
+
)}
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
@@ -44,7 +44,7 @@ const PaymentOptionButtons = () => {
|
|
|
44
44
|
{displayedPaymentOptions.map((option) => (
|
|
45
45
|
<label
|
|
46
46
|
key={`payment-option-${option.pk}`}
|
|
47
|
-
className="border
|
|
47
|
+
className="border px-4 py-3 mt-3 flex h-12"
|
|
48
48
|
onClick={scrollToTop}
|
|
49
49
|
>
|
|
50
50
|
<Radio
|
|
@@ -69,10 +69,10 @@ const PaymentOptionButtons = () => {
|
|
|
69
69
|
onClick={() => onClickHandler(option)}
|
|
70
70
|
className={clsx(
|
|
71
71
|
'flex items-center justify-center border-r border-b border-solid',
|
|
72
|
-
'border-gray-400 text-xs uppercase text-black-800
|
|
73
|
-
'bg-white h-11 px-5 transition-colors sm:h-15 sm:px-8 sm:py-8 hover:text-secondary',
|
|
72
|
+
'border-gray-400 text-xs uppercase text-black-800 font-medium',
|
|
73
|
+
'text-opacity-60 bg-white h-11 px-5 transition-colors sm:h-15 sm:px-8 sm:py-8 hover:text-secondary',
|
|
74
74
|
{
|
|
75
|
-
'text-
|
|
75
|
+
'text-opacity-100 border-b-transparent':
|
|
76
76
|
preOrder?.payment_option?.pk === option.pk
|
|
77
77
|
}
|
|
78
78
|
)}
|
|
@@ -130,7 +130,7 @@ const AddressBox = ({
|
|
|
130
130
|
onClick={() => handleAddressClick(addressType, address)}
|
|
131
131
|
key={address.pk}
|
|
132
132
|
className={clsx(
|
|
133
|
-
'cursor-pointer relative w-full border
|
|
133
|
+
'cursor-pointer relative w-full border shadow p-4 min-h-[8rem]',
|
|
134
134
|
"hover:after:content-[''] hover:after:border-4 hover:after:opacity-30 hover:after:transition-opacity",
|
|
135
135
|
'after:border-secondary-400 after:absolute after:inset-0 after:duration-150 after:-z-10',
|
|
136
136
|
{
|
|
@@ -167,7 +167,7 @@ const AddressBox = ({
|
|
|
167
167
|
<div className="text-xs flex justify-between">
|
|
168
168
|
<Button
|
|
169
169
|
appearance="ghost"
|
|
170
|
-
className="italic underline hover:text-secondary-500 hover
|
|
170
|
+
className="italic underline hover:text-secondary-500 hover:!bg-white hover:!border-white p-0 h-auto"
|
|
171
171
|
onClick={() => setIsEditAddressModalOpen(true)}
|
|
172
172
|
data-testid="checkout-address-edit"
|
|
173
173
|
>
|
|
@@ -193,7 +193,7 @@ const AddressBox = ({
|
|
|
193
193
|
</Modal>
|
|
194
194
|
<Button
|
|
195
195
|
appearance="ghost"
|
|
196
|
-
className="italic underline hover:text-secondary-500 hover
|
|
196
|
+
className="italic underline hover:text-secondary-500 hover:!bg-white hover:!border-white p-0 h-auto"
|
|
197
197
|
onClick={() => setRemoveAddressModalOpen(true)}
|
|
198
198
|
data-testid="checkout-address-remove"
|
|
199
199
|
>
|
|
@@ -153,7 +153,7 @@ const Addresses = () => {
|
|
|
153
153
|
role="button"
|
|
154
154
|
onClick={() => setIsModalOpen(true)}
|
|
155
155
|
className={clsx(
|
|
156
|
-
'relative cursor-pointer w-full min-h-[8rem] border
|
|
156
|
+
'relative cursor-pointer w-full min-h-[8rem] border shadow p-4',
|
|
157
157
|
"hover:after:content-[''] hover:after:border-4 hover:after:opacity-30 hover:after:transition-opacity",
|
|
158
158
|
'after:border-secondary-400 after:absolute after:inset-0 after:opacity-0 after:duration-150 after:-z-10',
|
|
159
159
|
{
|
|
@@ -8,6 +8,7 @@ import PluginModule, { Component } from '@akinon/next/components/plugin-module';
|
|
|
8
8
|
import { twMerge } from 'tailwind-merge';
|
|
9
9
|
import { Image } from '@akinon/next/components/image';
|
|
10
10
|
import { Trans } from '@akinon/next/components/trans';
|
|
11
|
+
import { StoreCredits } from './steps/payment/options/store-credit';
|
|
11
12
|
|
|
12
13
|
export const Summary = () => {
|
|
13
14
|
const { t } = useLocalization();
|
|
@@ -38,6 +39,7 @@ export const Summary = () => {
|
|
|
38
39
|
'flex flex-col w-full mb-4 border border-solid border-gray-400'
|
|
39
40
|
}}
|
|
40
41
|
/>
|
|
42
|
+
<StoreCredits />
|
|
41
43
|
<div className="flex flex-col w-full border border-solid border-gray-400">
|
|
42
44
|
<div className="flex justify-between items-center flex-row border-b border-solid border-gray-400 px-4 py-2 sm:px-5 sm:py-4 sm:min-h-15">
|
|
43
45
|
<span className="text-black-800 text-xl font-light sm:text-2xl">
|
|
@@ -118,6 +120,14 @@ export const Summary = () => {
|
|
|
118
120
|
<Price value={preOrder?.shipping_amount} />
|
|
119
121
|
</span>
|
|
120
122
|
</div>
|
|
123
|
+
{parseFloat(preOrder?.loyalty_money) > 0 && (
|
|
124
|
+
<div className="flex items-center justify-between w-full text-xs text-black-800 py-1 px-4 sm:px-5">
|
|
125
|
+
<span>{t('checkout.summary.loyalty_money_total')}</span>
|
|
126
|
+
<span>
|
|
127
|
+
<Price value={preOrder?.loyalty_money} />
|
|
128
|
+
</span>
|
|
129
|
+
</div>
|
|
130
|
+
)}
|
|
121
131
|
<div className="flex items-center justify-between w-full text-xs text-black-800 py-1 px-4 sm:px-5">
|
|
122
132
|
<span>{t('checkout.summary.discounts_total')}</span>
|
|
123
133
|
<span>
|
|
@@ -149,7 +159,7 @@ export const Summary = () => {
|
|
|
149
159
|
</div>
|
|
150
160
|
</div>
|
|
151
161
|
<div className="flex flex-col py-4 px-4 text-black-800 text-xs sm:px-5">
|
|
152
|
-
<div className="w-full overflow-hidden
|
|
162
|
+
<div className="w-full overflow-hidden overflow-ellipsis mb-1 last:mb-0">
|
|
153
163
|
<Trans
|
|
154
164
|
i18nKey="checkout.summary.info"
|
|
155
165
|
components={{
|
|
@@ -162,7 +172,7 @@ export const Summary = () => {
|
|
|
162
172
|
}}
|
|
163
173
|
/>
|
|
164
174
|
</div>
|
|
165
|
-
<div className="w-full overflow-hidden
|
|
175
|
+
<div className="w-full overflow-hidden overflow-ellipsis mb-1 last:mb-0">
|
|
166
176
|
{preOrder.shipping_address?.line}{' '}
|
|
167
177
|
{preOrder.shipping_address?.postcode}{' '}
|
|
168
178
|
{preOrder.shipping_address?.district && (
|
|
@@ -123,14 +123,14 @@ export const FindInStore = ({ productPk, productName, variants }) => {
|
|
|
123
123
|
className="w-full"
|
|
124
124
|
options={retailStoreOptions}
|
|
125
125
|
{...register('city_id')}
|
|
126
|
-
error={errors.city_id}
|
|
126
|
+
error={errors.city_id as any}
|
|
127
127
|
/>
|
|
128
128
|
{sizeOptions.length > 1 && (
|
|
129
129
|
<Select
|
|
130
130
|
className="w-full"
|
|
131
131
|
options={sizeOptions}
|
|
132
132
|
{...register('size')}
|
|
133
|
-
error={errors.size}
|
|
133
|
+
error={errors.size as any}
|
|
134
134
|
/>
|
|
135
135
|
)}
|
|
136
136
|
</div>
|
|
@@ -76,7 +76,7 @@ export default function ActionMenu() {
|
|
|
76
76
|
: 'bg-secondary-500 text-white'
|
|
77
77
|
)}
|
|
78
78
|
>
|
|
79
|
-
{totalQuantity}
|
|
79
|
+
<span data-testid="header-basket-count">{totalQuantity}</span>
|
|
80
80
|
</Badge>
|
|
81
81
|
),
|
|
82
82
|
miniBasket: <MiniBasket />
|
|
@@ -92,11 +92,7 @@ export default function ActionMenu() {
|
|
|
92
92
|
ref={menu.miniBasket ? miniBasketRef : null}
|
|
93
93
|
>
|
|
94
94
|
{menu.action ? (
|
|
95
|
-
<button
|
|
96
|
-
onClick={menu.action}
|
|
97
|
-
data-testid={menu.dataTestId}
|
|
98
|
-
className="cursor-pointer"
|
|
99
|
-
>
|
|
95
|
+
<button onClick={menu.action} data-testid={menu.dataTestId}>
|
|
100
96
|
<Icon name={menu.icon} size={24} />
|
|
101
97
|
{menu.badge}
|
|
102
98
|
</button>
|
|
@@ -16,13 +16,13 @@ export default function HeaderBand() {
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div className="header-grid-area-nav bg-gray-100 h-auto p-3 sm:header-grid-area-band-m sm:h-9 sm:py-0">
|
|
19
|
-
<div className="text-center
|
|
19
|
+
<div className="text-center overflow-ellipsis line-clamp-2 h-full flex items-center justify-center">
|
|
20
20
|
<HeaderBandText />
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
24
|
<div className="header-grid-area-main-r h-full pr-4 sm:header-grid-area-band-r sm:pr-0">
|
|
25
|
-
<div className="flex items-center justify-end h-full
|
|
25
|
+
<div className="flex items-center justify-end h-full">
|
|
26
26
|
<UserMenu isMobile={false} />
|
|
27
27
|
<ActionMenu />
|
|
28
28
|
</div>
|
|
@@ -13,7 +13,7 @@ import { getMenu } from '@akinon/next/data/server';
|
|
|
13
13
|
import { Image } from '@akinon/next/components/image';
|
|
14
14
|
|
|
15
15
|
export default async function Header() {
|
|
16
|
-
const response = await getMenu();
|
|
16
|
+
const response = await getMenu({ depth: 3 });
|
|
17
17
|
const menu = menuGenerator(response);
|
|
18
18
|
|
|
19
19
|
return (
|
|
@@ -203,7 +203,7 @@ export default function MiniBasket() {
|
|
|
203
203
|
miniBasketOpen
|
|
204
204
|
? 'opacity-100 visible lg:invisible'
|
|
205
205
|
: 'opacity-0 invisible',
|
|
206
|
-
'fixed top-0 left-0 z-50 w-screen h-screen bg-black
|
|
206
|
+
'fixed top-0 left-0 z-50 w-screen h-screen bg-black bg-opacity-80 transition-all duration-300'
|
|
207
207
|
)}
|
|
208
208
|
onClick={() => {
|
|
209
209
|
dispatch(closeMiniBasket());
|
|
@@ -217,7 +217,7 @@ export default function MiniBasket() {
|
|
|
217
217
|
'fixed lg:absolute bottom-0 lg:-bottom-1 right-0 w-80 h-screen lg:h-auto bg-white lg:border-l lg:border-t lg:border-r-2 lg:border-b-2 lg:border-gray-500 p-5 z-50 transition-all duration-300'
|
|
218
218
|
)}
|
|
219
219
|
>
|
|
220
|
-
<header className="flex items-center gap-2 pb-3 border-b
|
|
220
|
+
<header className="flex items-center gap-2 pb-3 border-b">
|
|
221
221
|
<h3 className="text-xl font-bold">
|
|
222
222
|
{t('basket.mini_basket.my_bag')}
|
|
223
223
|
</h3>
|
|
@@ -58,9 +58,9 @@ export default function MobileMenu(props: MobileMenuProps) {
|
|
|
58
58
|
<>
|
|
59
59
|
<div
|
|
60
60
|
className={clsx(
|
|
61
|
-
'fixed top-0 left-0 z-30 w-screen h-screen invisible opacity-0 bg-black
|
|
61
|
+
'fixed top-0 left-0 z-30 w-screen h-screen invisible opacity-0 bg-black bg-opacity-80 transition duration-500',
|
|
62
62
|
{
|
|
63
|
-
'visible!
|
|
63
|
+
'!visible !opacity-100 scroll-lock': isMobileMenuOpen
|
|
64
64
|
}
|
|
65
65
|
)}
|
|
66
66
|
/>
|
|
@@ -70,7 +70,7 @@ export default function MobileMenu(props: MobileMenuProps) {
|
|
|
70
70
|
className={clsx(
|
|
71
71
|
'fixed top-0 left-0 z-50 flex flex-col bg-white w-72 pt-4 h-screen invisible opacity-0 transition duration-500 transform -translate-x-72',
|
|
72
72
|
{
|
|
73
|
-
'visible!
|
|
73
|
+
'!visible !opacity-100 translate-x-0': isMobileMenuOpen
|
|
74
74
|
}
|
|
75
75
|
)}
|
|
76
76
|
>
|
|
@@ -106,15 +106,15 @@ export default function MobileMenu(props: MobileMenuProps) {
|
|
|
106
106
|
className={clsx(
|
|
107
107
|
'absolute top-0 left-0 right-0 px-8 bg-white invisible opacity-0 transition duration-500 transform translate-x-full',
|
|
108
108
|
{
|
|
109
|
-
'visible!
|
|
109
|
+
'!visible !opacity-100 !translate-x-0': selectedSubMenu
|
|
110
110
|
}
|
|
111
111
|
)}
|
|
112
112
|
>
|
|
113
|
-
<header className="flex items-center justify-between border-b
|
|
113
|
+
<header className="flex items-center justify-between border-b h-[61px] py-4 mb-4">
|
|
114
114
|
<Button
|
|
115
115
|
appearance="ghost"
|
|
116
116
|
onClick={() => setSelectedSubMenu(null)}
|
|
117
|
-
className="underline text-xs font-semibold flex items-center gap-2 p-0
|
|
117
|
+
className="underline text-xs font-semibold flex items-center gap-2 !p-0"
|
|
118
118
|
>
|
|
119
119
|
<Icon name="chevron-start" size={12} className="shrink-0" />
|
|
120
120
|
{t('common.mobile_menu.back')}
|
|
@@ -34,7 +34,7 @@ export const PwaBackButton = () => {
|
|
|
34
34
|
return (
|
|
35
35
|
<div className="relative z-10 md:top-0 md:left-0 md:fixed">
|
|
36
36
|
<button
|
|
37
|
-
className="bg-secondary-600 text-white flex items-center justify-center shrink-0 w-12 h-12 md:w-10 md:h-9 active:bg-secondary-700"
|
|
37
|
+
className="bg-secondary-600 text-white flex items-center justify-center flex-shrink-0 w-12 h-12 md:w-10 md:h-9 active:bg-secondary-700"
|
|
38
38
|
onClick={() => router.back()}
|
|
39
39
|
>
|
|
40
40
|
<svg
|
|
@@ -9,6 +9,7 @@ import { Icon } from '@theme/components';
|
|
|
9
9
|
import Results from './results';
|
|
10
10
|
import { ROUTES } from '@theme/routes';
|
|
11
11
|
import { useLocalization, useRouter } from '@akinon/next/hooks';
|
|
12
|
+
import PluginModule, { Component } from '@akinon/next/components/plugin-module';
|
|
12
13
|
|
|
13
14
|
export default function Search() {
|
|
14
15
|
const { t } = useLocalization();
|
|
@@ -46,7 +47,7 @@ export default function Search() {
|
|
|
46
47
|
<div
|
|
47
48
|
className={clsx(
|
|
48
49
|
// 177px is the height of the header
|
|
49
|
-
'absolute bg-black
|
|
50
|
+
'absolute bg-black opacity-75 w-screen h-screen transition duration-500 left-0 bottom-0 translate-y-full z-30',
|
|
50
51
|
isSearchOpen && searchText
|
|
51
52
|
? 'visible opacity-100'
|
|
52
53
|
: 'invisible opacity-0'
|
|
@@ -60,7 +61,7 @@ export default function Search() {
|
|
|
60
61
|
isSearchOpen ? 'visible opacity-100' : 'invisible opacity-0'
|
|
61
62
|
)}
|
|
62
63
|
>
|
|
63
|
-
<div className="max-w-
|
|
64
|
+
<div className="max-w-screen-2xl mx-auto flex flex-col gap-12">
|
|
64
65
|
<div className="border-b border-gray-400 flex flex-col py-1.5 gap-2 self-center items-center md:flex-row">
|
|
65
66
|
<span className="text-xl lg:text-2xl">
|
|
66
67
|
{t('common.search.results_for')}
|
|
@@ -74,10 +75,19 @@ export default function Search() {
|
|
|
74
75
|
router.push(`${ROUTES.LIST}/?search_text=${searchText}`);
|
|
75
76
|
}
|
|
76
77
|
}}
|
|
77
|
-
className="border-0 text-2xl outline-
|
|
78
|
+
className="border-0 text-2xl outline-none text-secondary placeholder:text-xl placeholder:lg:text-2xl"
|
|
78
79
|
placeholder={t('common.search.placeholder')}
|
|
79
80
|
ref={inputRef}
|
|
80
81
|
/>
|
|
82
|
+
|
|
83
|
+
<PluginModule
|
|
84
|
+
component={Component.HeaderImageSearchFeature}
|
|
85
|
+
props={{
|
|
86
|
+
enableTextSearch: true,
|
|
87
|
+
isEnabled: true
|
|
88
|
+
}}
|
|
89
|
+
/>
|
|
90
|
+
|
|
81
91
|
<Icon
|
|
82
92
|
name="close"
|
|
83
93
|
size={14}
|
|
@@ -80,7 +80,7 @@ export default function Results(props: ResultsProps) {
|
|
|
80
80
|
<div className="grid grid-cols-2 sm:grid-cols-4 gap-8">
|
|
81
81
|
{products.map((product, index) => (
|
|
82
82
|
<Link href={product?.url} key={index} className="flex flex-col">
|
|
83
|
-
<div className="relative aspect-315/448">
|
|
83
|
+
<div className="relative aspect-[315/448]">
|
|
84
84
|
{product.extra.image ? (
|
|
85
85
|
<Image
|
|
86
86
|
src={product.extra.image}
|