@akinon/next 2.0.0-beta.1 → 2.0.0-beta.10

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.
Files changed (63) hide show
  1. package/.eslintrc.js +12 -0
  2. package/CHANGELOG.md +50 -0
  3. package/api/auth.ts +17 -0
  4. package/bin/run-prebuild-tests.js +46 -0
  5. package/components/accordion.tsx +1 -1
  6. package/components/button.tsx +51 -36
  7. package/components/client-root.tsx +20 -0
  8. package/components/input.tsx +1 -1
  9. package/components/modal.tsx +1 -1
  10. package/components/select.tsx +1 -1
  11. package/components/selected-payment-option-view.tsx +1 -1
  12. package/data/client/api.ts +2 -0
  13. package/data/client/basket.ts +27 -5
  14. package/data/client/checkout.ts +62 -7
  15. package/data/client/misc.ts +25 -1
  16. package/data/client/product.ts +19 -2
  17. package/data/client/user.ts +16 -8
  18. package/data/server/flatpage.ts +8 -4
  19. package/data/server/form.ts +12 -4
  20. package/data/server/landingpage.ts +8 -4
  21. package/data/server/menu.ts +7 -2
  22. package/data/server/product.ts +16 -5
  23. package/data/server/seo.ts +11 -4
  24. package/data/server/widget.ts +19 -4
  25. package/data/urls.ts +11 -3
  26. package/hooks/index.ts +1 -0
  27. package/hooks/use-router.ts +5 -2
  28. package/hooks/use-sentry-uncaught-errors.ts +24 -0
  29. package/instrumentation/index.ts +10 -0
  30. package/lib/cache-handler.mjs +2 -2
  31. package/lib/cache.ts +4 -4
  32. package/localization/index.ts +2 -1
  33. package/middlewares/default.ts +6 -15
  34. package/middlewares/locale.ts +31 -10
  35. package/middlewares/url-redirection.ts +16 -0
  36. package/package.json +4 -3
  37. package/plugins.js +2 -1
  38. package/redux/middlewares/checkout.ts +16 -144
  39. package/redux/middlewares/index.ts +4 -2
  40. package/redux/middlewares/pre-order/address.ts +50 -0
  41. package/redux/middlewares/pre-order/attribute-based-shipping-option.ts +46 -0
  42. package/redux/middlewares/pre-order/data-source-shipping-option.ts +43 -0
  43. package/redux/middlewares/pre-order/delivery-option.ts +40 -0
  44. package/redux/middlewares/pre-order/index.ts +29 -0
  45. package/redux/middlewares/pre-order/installment-option.ts +42 -0
  46. package/redux/middlewares/pre-order/payment-option.ts +34 -0
  47. package/redux/middlewares/pre-order/pre-order-validation.ts +24 -0
  48. package/redux/middlewares/pre-order/redirection.ts +40 -0
  49. package/redux/middlewares/pre-order/set-pre-order.ts +22 -0
  50. package/redux/middlewares/pre-order/shipping-option.ts +44 -0
  51. package/redux/middlewares/pre-order/shipping-step.ts +38 -0
  52. package/redux/reducers/checkout.ts +8 -2
  53. package/redux/reducers/index.ts +5 -3
  54. package/redux/reducers/root.ts +7 -2
  55. package/sentry/index.ts +36 -17
  56. package/types/commerce/account.ts +5 -1
  57. package/types/commerce/checkout.ts +23 -0
  58. package/types/index.ts +6 -2
  59. package/utils/index.ts +11 -8
  60. package/utils/localization.ts +4 -0
  61. package/utils/override-middleware.ts +25 -0
  62. package/views/error-page.tsx +93 -0
  63. package/with-pz-config.js +4 -3
package/.eslintrc.js CHANGED
@@ -24,6 +24,18 @@ module.exports = {
24
24
  parserOptions: {
25
25
  sourceType: 'script'
26
26
  }
27
+ },
28
+ {
29
+ env: {
30
+ node: true
31
+ },
32
+ files: ['redux/middlewares/pre-order/index.ts'],
33
+ rules: {
34
+ '@akinon/projectzero/check-pre-order-middleware-order': 'error'
35
+ },
36
+ parserOptions: {
37
+ sourceType: 'script'
38
+ }
27
39
  }
28
40
  ],
29
41
  parser: '@typescript-eslint/parser',
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # @akinon/next
2
2
 
3
+ ## 2.0.0-beta.10
4
+
5
+ ### Minor Changes
6
+
7
+ - 2806320: ZERO-3390: Update version tailwindcss, autoprefixer, tailwind-merge, postcss
8
+
9
+ ## 2.0.0-beta.9
10
+
11
+ ### Minor Changes
12
+
13
+ - 0fe7711: ZERO-3387: Upgrade nextjs, eslint-config-next
14
+
15
+ ## 2.0.0-beta.8
16
+
17
+ ### Minor Changes
18
+
19
+ - 071d0f5: ZERO-3352: Resolve Single item size exceeds maxSize error and upgrade dependencies
20
+
21
+ ## 2.0.0-beta.7
22
+
23
+ ## 2.0.0-beta.6
24
+
25
+ ### Minor Changes
26
+
27
+ - 8f05f9b: ZERO-3250: Beta branch synchronized with Main branch
28
+
29
+ ## 2.0.0-beta.5
30
+
31
+ ### Minor Changes
32
+
33
+ - e791eab: ZERO-3133: Add fallbackReducer for handling missing plugin reducers
34
+
35
+ ## 2.0.0-beta.4
36
+
37
+ ## 2.0.0-beta.3
38
+
39
+ ### Minor Changes
40
+
41
+ - 5536b80: ZERO-3104: Add optional headers parameter
42
+
43
+ ## 2.0.0-beta.2
44
+
45
+ ### Minor Changes
46
+
47
+ - a006015: ZERO-3116: Add not-found page and update default middleware.
48
+ - 999168d: ZERO-3104: Remove local cache handler from CacheHandler initialization
49
+ - 1eeb3d8: ZERO-3116: Add not found page
50
+ - 86a5a62: ZERO-3104: Add optional headers parameter to data fetching functions
51
+ - dd69cc6: ZERO-3079: Modularize pre-order middleware
52
+
3
53
  ## 2.0.0-beta.1
4
54
 
5
55
  ### Minor Changes
package/api/auth.ts CHANGED
@@ -92,11 +92,28 @@ const nextAuthOptions = (req: NextApiRequest, res: NextApiResponse) => {
92
92
  req.headers['x-app-device']?.toString() ?? ''
93
93
  );
94
94
 
95
+ headers.set('x-frontend-id', req.cookies['pz-frontend-id'] || '');
96
+
95
97
  logger.debug('Trying to login/register', {
96
98
  formType: credentials.formType,
97
99
  userIp
98
100
  });
99
101
 
102
+ const checkCurrentUser = await getCurrentUser(
103
+ req.cookies['osessionid'] ?? '',
104
+ req.cookies['pz-currency'] ?? ''
105
+ );
106
+
107
+ if (checkCurrentUser?.pk) {
108
+ const sessionCookie = headers
109
+ .get('cookie')
110
+ ?.match(/osessionid=\w+/)?.[0]
111
+ .replace(/osessionid=/, '');
112
+ if (sessionCookie) {
113
+ headers.set('cookie', sessionCookie);
114
+ }
115
+ }
116
+
100
117
  const apiRequest = await fetch(
101
118
  `${Settings.commerceUrl}${user[credentials.formType]}`,
102
119
  {
@@ -0,0 +1,46 @@
1
+ const path = require('path')
2
+ const fs = require('fs')
3
+
4
+ function runPrebuildTests() {
5
+ const workspaceRoot = process.cwd()
6
+ const configPath = path.join(workspaceRoot, 'config/prebuild-tests.json')
7
+
8
+ try {
9
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
10
+
11
+ if (config.tests && Array.isArray(config.tests)) {
12
+ for (const testScript of config.tests) {
13
+ console.log(`🧪 Running test script: ${testScript}`)
14
+ const result = require('child_process').spawnSync('yarn', [testScript], {
15
+ stdio: 'inherit',
16
+ shell: true
17
+ })
18
+
19
+ if (result.status !== 0) {
20
+ console.error(`❌ Test script '${testScript}' failed`)
21
+ process.exit(1)
22
+ }
23
+ }
24
+ console.log('✅ All prebuild tests passed successfully!')
25
+ }
26
+ } catch (error) {
27
+ if (error.code === 'ENOENT') {
28
+ console.log('🧪 Running default test: test:middleware')
29
+ const result = require('child_process').spawnSync('yarn', ['test:middleware'], {
30
+ stdio: 'inherit',
31
+ shell: true
32
+ })
33
+
34
+ if (result.status !== 0) {
35
+ console.error('❌ Middleware test failed')
36
+ process.exit(1)
37
+ }
38
+ console.log('✅ Default test passed successfully!')
39
+ } else {
40
+ console.error('❌ Error reading test configuration:', error)
41
+ process.exit(1)
42
+ }
43
+ }
44
+ }
45
+
46
+ module.exports = runPrebuildTests
@@ -22,7 +22,7 @@ export const Accordion = ({
22
22
  return (
23
23
  <div
24
24
  className={twMerge(
25
- 'flex flex-col justify-center border-b pb-4 mb-4 last:border-none',
25
+ 'flex flex-col justify-center border-b border-gray-200 pb-4 mb-4 last:border-none',
26
26
  className
27
27
  )}
28
28
  >
@@ -1,46 +1,61 @@
1
1
  'use client';
2
2
 
3
- import { ButtonProps } from '../types/index';
3
+ import { ButtonProps } from '../types';
4
4
  import clsx from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
+ import { Link } from './link';
6
7
 
7
8
  export const Button = (props: ButtonProps) => {
8
- return (
9
- <button
10
- {...props}
11
- className={twMerge(
12
- clsx(
13
- [
14
- 'px-4',
15
- 'h-10',
16
- 'text-xs',
17
- 'bg-primary',
18
- 'text-primary-foreground',
19
- 'border',
20
- 'border-primary',
21
- 'transition-all',
22
- 'hover:bg-white',
23
- 'hover:border-primary',
24
- 'hover:text-primary'
25
- ],
26
- props.appearance === 'outlined' && [
27
- 'bg-transparent ',
28
- 'text-primary ',
29
- 'hover:bg-primary ',
30
- 'hover:text-primary-foreground'
31
- ],
32
- props.appearance === 'ghost' && [
33
- 'bg-transparent',
34
- 'border-transparent',
35
- 'text-primary',
36
- 'hover:bg-primary',
37
- 'hover:text-primary-foreground'
38
- ]
39
- ),
40
- props.className
41
- )}
9
+ const {
10
+ appearance = 'filled',
11
+ size = 'md',
12
+ href,
13
+ target,
14
+ children,
15
+ className,
16
+ ...rest
17
+ } = props;
18
+
19
+ const variants = {
20
+ filled:
21
+ 'bg-primary text-primary-foreground border border-primary hover:bg-white hover:border-primary hover:text-primary',
22
+ outlined:
23
+ 'bg-transparent text-primary hover:bg-primary hover:text-primary-foreground',
24
+ ghost:
25
+ 'bg-transparent border-transparent text-primary hover:bg-primary hover:text-primary-foreground',
26
+ link: 'px-0 h-auto underline underline-offset-2'
27
+ };
28
+
29
+ const sizes = {
30
+ sm: 'h-8',
31
+ md: 'h-10',
32
+ lg: 'h-12',
33
+ xl: 'h-14'
34
+ };
35
+
36
+ const buttonClasses = twMerge(
37
+ clsx(
38
+ 'px-4 text-xs transition-all duration-200',
39
+ 'inline-flex gap-2 justify-center items-center',
40
+ variants[appearance],
41
+ sizes[size],
42
+ className
43
+ ),
44
+ className
45
+ );
46
+
47
+ return props.href ? (
48
+ <Link
49
+ prefetch={false}
50
+ target={target}
51
+ href={href}
52
+ className={buttonClasses}
42
53
  >
43
- {props.children}
54
+ {children}
55
+ </Link>
56
+ ) : (
57
+ <button {...rest} className={buttonClasses}>
58
+ {children}
44
59
  </button>
45
60
  );
46
61
  };
@@ -1,6 +1,9 @@
1
1
  'use client';
2
2
 
3
3
  import { useMobileIframeHandler } from '../hooks';
4
+ import * as Sentry from '@sentry/nextjs';
5
+ import { initSentry } from '../sentry';
6
+ import { useEffect } from 'react';
4
7
 
5
8
  export default function ClientRoot({
6
9
  children,
@@ -11,6 +14,23 @@ export default function ClientRoot({
11
14
  }) {
12
15
  const { preventPageRender } = useMobileIframeHandler({ sessionId });
13
16
 
17
+ const initializeSentry = async () => {
18
+ const response = await fetch('/api/sentry', { next: { revalidate: 0 } });
19
+ const data = await response.json();
20
+
21
+ const options = {
22
+ dsn: data.dsn
23
+ };
24
+
25
+ initSentry('Client', options);
26
+ };
27
+
28
+ useEffect(() => {
29
+ if (!Sentry.isInitialized()) {
30
+ initializeSentry();
31
+ }
32
+ }, []);
33
+
14
34
  if (preventPageRender) {
15
35
  return null;
16
36
  }
@@ -40,7 +40,7 @@ export const Input = forwardRef<
40
40
  const inputClass = twMerge(
41
41
  clsx(
42
42
  'text-xs border px-2.5 h-10 placeholder:text-gray-600 peer',
43
- 'focus-visible:outline-none', // disable outline on focus
43
+ 'focus-visible:outline-hidden', // disable outline on focus
44
44
  error
45
45
  ? 'border-error focus:border-error'
46
46
  : 'border-gray-500 hover:border-black focus:border-black'
@@ -38,7 +38,7 @@ export const Modal = (props: ModalProps) => {
38
38
 
39
39
  return (
40
40
  <ReactPortal wrapperId={portalId}>
41
- <div className="fixed top-0 left-0 w-screen h-screen bg-primary bg-opacity-60 z-50" />
41
+ <div className="fixed top-0 left-0 w-screen h-screen bg-primary/60 z-50" />
42
42
  <section
43
43
  className={twMerge(
44
44
  'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 bg-white',
@@ -41,7 +41,7 @@ const Select = forwardRef<HTMLSelectElement, SelectProps>((props, ref) => {
41
41
  ref={ref}
42
42
  className={twMerge(
43
43
  clsx(
44
- 'cursor-pointer truncate h-10 w-40 px-2.5 shrink-0 outline-none',
44
+ 'cursor-pointer truncate h-10 w-40 px-2.5 shrink-0 outline-hidden',
45
45
  !borderless &&
46
46
  'border border-gray-200 transition-all duration-150 hover:border-primary'
47
47
  ),
@@ -4,7 +4,7 @@ import { RootState } from 'redux/store';
4
4
  import { useAppSelector } from '../redux/hooks';
5
5
  import dynamic, { DynamicOptionsLoadingProps } from 'next/dynamic';
6
6
  import { PaymentOptionViews } from 'views/checkout/steps/payment';
7
- import { useMemo } from 'react';
7
+ import { JSX, useMemo } from 'react';
8
8
 
9
9
  const fallbackView = () => <></>;
10
10
 
@@ -68,10 +68,12 @@ export const api = createApi({
68
68
  tagTypes: [
69
69
  'Basket',
70
70
  'MultiBasket',
71
+ 'MiniBasket',
71
72
  'BasketB2b',
72
73
  'DraftsB2b',
73
74
  'Product',
74
75
  'Checkout',
76
+ 'PaymentOptions',
75
77
  'Favorite',
76
78
  'Addresses',
77
79
  'Profile',
@@ -24,6 +24,26 @@ export const basketApi = api.injectEndpoints({
24
24
  transformResponse: (response: { basket: Basket }) => response.basket,
25
25
  providesTags: ['Basket']
26
26
  }),
27
+ getMiniBasket: build.query<
28
+ { pk: number | null; total_quantity: number },
29
+ void
30
+ >({
31
+ query: () =>
32
+ buildClientRequestUrl(basket.getMiniBasket, {
33
+ contentType: 'application/json'
34
+ }),
35
+ providesTags: ['MiniBasket']
36
+ }),
37
+ getMiniBasketDetail: build.query<
38
+ { pk: number | null; total_quantity: number },
39
+ { namespace: string }
40
+ >({
41
+ query: ({ namespace }) =>
42
+ buildClientRequestUrl(basket.getMiniBasketDetail(namespace), {
43
+ contentType: 'application/json'
44
+ }),
45
+ providesTags: ['MiniBasket']
46
+ }),
27
47
  getBasketDetail: build.query<Basket, { namespace: string }>({
28
48
  query: ({ namespace }) =>
29
49
  buildClientRequestUrl(basket.getBasketDetail(namespace)),
@@ -46,7 +66,7 @@ export const basketApi = api.injectEndpoints({
46
66
  method: 'DELETE',
47
67
  body: { pk }
48
68
  }),
49
- invalidatesTags: ['MultiBasket', 'Basket']
69
+ invalidatesTags: ['MultiBasket', 'Basket', 'MiniBasket']
50
70
  }),
51
71
  selectMainBasket: build.mutation<Basket, { pk: number }>({
52
72
  query: ({ pk }) => ({
@@ -57,7 +77,7 @@ export const basketApi = api.injectEndpoints({
57
77
  body: { pk }
58
78
  }),
59
79
  transformResponse: (response: { baskets: Basket }) => response.baskets,
60
- invalidatesTags: ['MultiBasket', 'Basket']
80
+ invalidatesTags: ['MultiBasket', 'Basket', 'MiniBasket']
61
81
  }),
62
82
  selectNameSpaceMainBasket: build.mutation<Basket, { namespace: string }>({
63
83
  query: ({ namespace }) => ({
@@ -71,7 +91,7 @@ export const basketApi = api.injectEndpoints({
71
91
  body: { namespace }
72
92
  }),
73
93
  transformResponse: (response: { baskets: Basket }) => response.baskets,
74
- invalidatesTags: ['MultiBasket', 'Basket']
94
+ invalidatesTags: ['MultiBasket', 'Basket', 'MiniBasket']
75
95
  }),
76
96
  updateQuantity: build.mutation<
77
97
  UpdateQuantityResponse,
@@ -84,7 +104,7 @@ export const basketApi = api.injectEndpoints({
84
104
  method: 'PUT',
85
105
  body
86
106
  }),
87
- invalidatesTags: ['MultiBasket', 'Basket']
107
+ invalidatesTags: ['MultiBasket', 'Basket', 'MiniBasket']
88
108
  }),
89
109
  clearBasket: build.mutation<Basket, void>({
90
110
  query: (body) => ({
@@ -95,7 +115,7 @@ export const basketApi = api.injectEndpoints({
95
115
  body
96
116
  }),
97
117
  transformResponse: (response: { basket: Basket }) => response.basket,
98
- invalidatesTags: ['Basket']
118
+ invalidatesTags: ['Basket', 'MiniBasket', 'MiniBasket']
99
119
  }),
100
120
  applyVoucherCode: build.mutation<Basket, { voucher_code: string }>({
101
121
  query: (body) => ({
@@ -125,6 +145,8 @@ export const basketApi = api.injectEndpoints({
125
145
 
126
146
  export const {
127
147
  useGetBasketQuery,
148
+ useGetMiniBasketQuery,
149
+ useGetMiniBasketDetailQuery,
128
150
  useLazyGetBasketDetailQuery,
129
151
  useGetAllBasketsQuery,
130
152
  useRemoveBasketMutation,
@@ -2,6 +2,7 @@ import {
2
2
  setBankAccounts,
3
3
  setCardType,
4
4
  setInstallmentOptions,
5
+ setPaymentOptions,
5
6
  setPaymentStepBusy,
6
7
  setSelectedBankAccountPk,
7
8
  setSelectedCreditPaymentPk,
@@ -12,7 +13,9 @@ import {
12
13
  ExtraField,
13
14
  GuestLoginFormParams,
14
15
  Order,
15
- PreOrder
16
+ PreOrder,
17
+ SendSmsType,
18
+ VerifySmsType
16
19
  } from '../../types';
17
20
  import { buildClientRequestUrl } from '../../utils';
18
21
  import { api } from './api';
@@ -182,6 +185,11 @@ export const checkoutApi = api.injectEndpoints({
182
185
  }),
183
186
  providesTags: ['Checkout']
184
187
  }),
188
+ resetCheckoutState: build.query<CheckoutResponse, void>({
189
+ query: () => ({
190
+ url: buildClientRequestUrl(checkout.guestLogin, {})
191
+ })
192
+ }),
185
193
  fetchCheckoutResult: build.query<{ order: Order }, string>({
186
194
  query: (token: string) =>
187
195
  buildClientRequestUrl(checkout.fetchCheckoutResult(token))
@@ -419,6 +427,12 @@ export const checkoutApi = api.injectEndpoints({
419
427
  }
420
428
  })
421
429
  }),
430
+ fetchPaymentOptions: build.query<CheckoutResponse, void>({
431
+ query: () => ({
432
+ url: buildClientRequestUrl(checkout.setPaymentOption)
433
+ }),
434
+ providesTags: ['PaymentOptions']
435
+ }),
422
436
  setPaymentOption: build.mutation<CheckoutResponse, number>({
423
437
  query: (pk: number) => ({
424
438
  url: buildClientRequestUrl(checkout.setPaymentOption, {
@@ -467,16 +481,15 @@ export const checkoutApi = api.injectEndpoints({
467
481
  CheckoutResponse,
468
482
  {
469
483
  payment_token?: string;
484
+ [key: string]: any;
470
485
  }
471
486
  >({
472
- query: ({ payment_token }) => ({
487
+ query: (requestBody) => ({
473
488
  url: buildClientRequestUrl(checkout.setWalletPaymentPage, {
474
489
  useFormData: true
475
490
  }),
476
491
  method: 'POST',
477
- body: {
478
- payment_token
479
- }
492
+ body: requestBody
480
493
  }),
481
494
  async onQueryStarted(arg, { dispatch, queryFulfilled }) {
482
495
  dispatch(setPaymentStepBusy(true));
@@ -732,7 +745,27 @@ export const checkoutApi = api.injectEndpoints({
732
745
  body: {
733
746
  loyalty_amount_to_use: amount
734
747
  }
735
- })
748
+ }),
749
+ async onQueryStarted(arg, { dispatch, queryFulfilled }) {
750
+ dispatch(setPaymentStepBusy(true));
751
+ dispatch(setPaymentOptions([]));
752
+ await queryFulfilled;
753
+
754
+ const paymentOptionsData = await dispatch(
755
+ checkoutApi.endpoints.fetchPaymentOptions.initiate()
756
+ ).unwrap();
757
+
758
+ const paymentOptions = paymentOptionsData?.context_list?.find(
759
+ (context) => context?.page_name === 'PaymentOptionSelectionPage'
760
+ )?.page_context?.payment_options;
761
+
762
+ if (paymentOptions) {
763
+ dispatch(setPaymentOptions(paymentOptions));
764
+ }
765
+
766
+ dispatch(setPaymentStepBusy(false));
767
+ },
768
+ invalidatesTags: ['PaymentOptions']
736
769
  }),
737
770
  setOrderNote: build.mutation<CheckoutResponse, string>({
738
771
  query: (notes) => ({
@@ -816,6 +849,24 @@ export const checkoutApi = api.injectEndpoints({
816
849
  selected_loyalty_amount: amount
817
850
  }
818
851
  })
852
+ }),
853
+ sendSms: build.mutation<CheckoutResponse, SendSmsType>({
854
+ query: (body) => ({
855
+ url: buildClientRequestUrl(checkout.sendSmsPage, {
856
+ useFormData: true
857
+ }),
858
+ method: 'POST',
859
+ body
860
+ })
861
+ }),
862
+ verifySms: build.mutation<CheckoutResponse, VerifySmsType>({
863
+ query: (body) => ({
864
+ url: buildClientRequestUrl(checkout.verifySmsPage, {
865
+ useFormData: true
866
+ }),
867
+ method: 'POST',
868
+ body
869
+ })
819
870
  })
820
871
  }),
821
872
  overrideExisting: false
@@ -835,6 +886,7 @@ export const {
835
886
  useSetAddressesMutation,
836
887
  useSetShippingOptionMutation,
837
888
  useSetDataSourceShippingOptionsMutation,
889
+ useFetchPaymentOptionsQuery,
838
890
  useSetPaymentOptionMutation,
839
891
  useSetBinNumberMutation,
840
892
  useSetInstallmentOptionMutation,
@@ -859,5 +911,8 @@ export const {
859
911
  useSetLoyaltyDataMutation,
860
912
  useSetWalletSelectionPageMutation,
861
913
  useSetWalletPaymentPageMutation,
862
- useSetWalletCompletePageMutation
914
+ useSetWalletCompletePageMutation,
915
+ useSendSmsMutation,
916
+ useVerifySmsMutation,
917
+ useResetCheckoutStateQuery
863
918
  } = checkoutApi;
@@ -92,6 +92,29 @@ export const miscApi = api.injectEndpoints({
92
92
  transformResponse: (response: { menu: MenuItemType[] }) => {
93
93
  return response.menu;
94
94
  }
95
+ }),
96
+ getBukalemunImageUrl: builder.query<
97
+ any,
98
+ { current_chapter: string; sku: string; selected_attributes: any }
99
+ >({
100
+ query: ({ current_chapter, sku, selected_attributes }) => {
101
+ const data = {
102
+ ...selected_attributes,
103
+ current_chapter,
104
+ sku
105
+ };
106
+
107
+ const params = new URLSearchParams(data);
108
+
109
+ return {
110
+ url: buildClientRequestUrl(
111
+ misc.bukalemunImageUrl(params.toString()),
112
+ {
113
+ responseType: 'json'
114
+ }
115
+ )
116
+ };
117
+ }
95
118
  })
96
119
  }),
97
120
  overrideExisting: true
@@ -102,5 +125,6 @@ export const {
102
125
  useEmailSubscriptionMutation,
103
126
  useSetLanguageMutation,
104
127
  useGetWidgetQuery,
105
- useGetMenuQuery
128
+ useGetMenuQuery,
129
+ useGetBukalemunImageUrlQuery
106
130
  } = miscApi;
@@ -69,12 +69,28 @@ export const productApi = api.injectEndpoints({
69
69
  }),
70
70
  method: 'POST',
71
71
  body
72
- })
72
+ }),
73
+ invalidatesTags: ['MiniBasket']
73
74
  }),
74
75
  getInstallments: build.query<any, any>({
75
76
  query: (productPk) => ({
76
77
  url: buildClientRequestUrl(product.installments(productPk))
77
78
  })
79
+ }),
80
+ getBundleProductData: build.query<
81
+ any,
82
+ { productPk: string; queryString: string }
83
+ >({
84
+ query: ({ productPk, queryString }) => {
85
+ return {
86
+ url: buildClientRequestUrl(
87
+ product.bundleProduct(productPk, queryString),
88
+ {
89
+ responseType: 'json'
90
+ }
91
+ )
92
+ };
93
+ }
78
94
  })
79
95
  }),
80
96
  overrideExisting: true
@@ -85,5 +101,6 @@ export const {
85
101
  useGetProductByPkQuery,
86
102
  useGetRetailStoreStockMutation,
87
103
  useGetInstallmentsQuery,
88
- useGetProductByParamsQuery
104
+ useGetProductByParamsQuery,
105
+ useGetBundleProductDataQuery
89
106
  } = productApi;
@@ -1,7 +1,7 @@
1
1
  import { api } from './api';
2
2
  import { user } from '../urls';
3
3
  import { ForgotPasswordFormType, Order } from '../../types';
4
- import { buildClientRequestUrl } from '../../utils';
4
+ import { buildClientRequestUrl, getCookie } from '../../utils';
5
5
 
6
6
  interface GetCaptchaResponse {
7
7
  siteKey: string;
@@ -64,13 +64,21 @@ const userApi = api.injectEndpoints({
64
64
  })
65
65
  }),
66
66
  forgotPassword: build.mutation<void, ForgotPasswordFormType>({
67
- query: (body) => ({
68
- url: buildClientRequestUrl(user.forgotPassword, {
69
- contentType: 'application/json'
70
- }),
71
- method: 'POST',
72
- body
73
- })
67
+ query: (body) => {
68
+ const frontendId = getCookie('pz-frontend-id');
69
+ const headers = frontendId
70
+ ? { 'x-frontend-id': frontendId }
71
+ : undefined;
72
+
73
+ return {
74
+ url: buildClientRequestUrl(user.forgotPassword, {
75
+ contentType: 'application/json'
76
+ }),
77
+ method: 'POST',
78
+ body,
79
+ headers
80
+ };
81
+ }
74
82
  }),
75
83
  otpLogin: build.mutation<void, { phone: string }>({
76
84
  query: ({ phone }) => ({