@akinon/next 1.82.0-rc.4 → 1.82.0-rc.6

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/.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,19 @@
1
1
  # @akinon/next
2
2
 
3
+ ## 1.82.0-rc.6
4
+
5
+ ### Minor Changes
6
+
7
+ - 0b1bd07f: ZERO-3240: Remove unused preOrderMiddleware
8
+
9
+ ## 1.82.0-rc.5
10
+
11
+ ### Minor Changes
12
+
13
+ - 6f506afc: ZERO-3229: Implement mini basket query for basket total quantity
14
+ - c0c19629: ZERO-3258: Add new API endpoints for fetching Bukalemun image URL and bundle product data
15
+ - 9be2c081: ZERO-3243: Improve basket update query handling with optimistic updates
16
+
3
17
  ## 1.82.0-rc.4
4
18
 
5
19
  ### Minor Changes
@@ -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: ['Basket']
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: ['MultiBasket']
46
+ }),
27
47
  getBasketDetail: build.query<Basket, { namespace: string }>({
28
48
  query: ({ namespace }) =>
29
49
  buildClientRequestUrl(basket.getBasketDetail(namespace)),
@@ -84,23 +104,45 @@ export const basketApi = api.injectEndpoints({
84
104
  method: 'PUT',
85
105
  body
86
106
  }),
87
- // TODO: It doesn't work with namespaced baskets. Fix it and remove invalidatesTags.
88
- invalidatesTags: ['MultiBasket', 'Basket']
107
+ async onQueryStarted(_, { dispatch, queryFulfilled }) {
108
+ try {
109
+ const { data } = await queryFulfilled;
110
+
111
+ dispatch(
112
+ basketApi.util.updateQueryData(
113
+ 'getBasket',
114
+ undefined,
115
+ () => data.basket
116
+ )
117
+ );
89
118
 
90
- // async onQueryStarted(_, { dispatch, queryFulfilled }) {
91
- // try {
92
- // const { data } = await queryFulfilled;
93
- // dispatch(
94
- // basketApi.util.updateQueryData(
95
- // 'getBasket',
96
- // undefined,
97
- // () => data.basket
98
- // )
99
- // );
100
- // } catch {
101
- // dispatch(basketApi.util.invalidateTags(['MultiBasket', 'Basket']));
102
- // }
103
- // }
119
+ if (data.basket.namespace) {
120
+ dispatch(
121
+ basketApi.util.updateQueryData(
122
+ 'getBasketDetail',
123
+ { namespace: data.basket.namespace },
124
+ () => data.basket
125
+ )
126
+ );
127
+ }
128
+
129
+ dispatch(
130
+ basketApi.util.updateQueryData(
131
+ 'getAllBaskets',
132
+ undefined,
133
+ (baskets) => {
134
+ if (!baskets) return baskets;
135
+
136
+ return baskets.map((basket) =>
137
+ basket.pk === data.basket.pk ? data.basket : basket
138
+ );
139
+ }
140
+ )
141
+ );
142
+ } catch (error) {
143
+ console.error('Error updating quantity:', error);
144
+ }
145
+ }
104
146
  }),
105
147
  clearBasket: build.mutation<Basket, void>({
106
148
  query: (body) => ({
@@ -141,6 +183,8 @@ export const basketApi = api.injectEndpoints({
141
183
 
142
184
  export const {
143
185
  useGetBasketQuery,
186
+ useGetMiniBasketQuery,
187
+ useGetMiniBasketDetailQuery,
144
188
  useLazyGetBasketDetailQuery,
145
189
  useGetAllBasketsQuery,
146
190
  useRemoveBasketMutation,
@@ -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;
@@ -75,6 +75,21 @@ export const productApi = api.injectEndpoints({
75
75
  query: (productPk) => ({
76
76
  url: buildClientRequestUrl(product.installments(productPk))
77
77
  })
78
+ }),
79
+ getBundleProductData: build.query<
80
+ any,
81
+ { productPk: string; queryString: string }
82
+ >({
83
+ query: ({ productPk, queryString }) => {
84
+ return {
85
+ url: buildClientRequestUrl(
86
+ product.bundleProduct(productPk, queryString),
87
+ {
88
+ responseType: 'json'
89
+ }
90
+ )
91
+ };
92
+ }
78
93
  })
79
94
  }),
80
95
  overrideExisting: true
@@ -85,5 +100,6 @@ export const {
85
100
  useGetProductByPkQuery,
86
101
  useGetRetailStoreStockMutation,
87
102
  useGetInstallmentsQuery,
88
- useGetProductByParamsQuery
103
+ useGetProductByParamsQuery,
104
+ useGetBundleProductDataQuery
89
105
  } = productApi;
package/data/urls.ts CHANGED
@@ -74,7 +74,10 @@ export const address = {
74
74
 
75
75
  export const basket = {
76
76
  getBasket: '/baskets/basket/',
77
+ getMiniBasket: '/baskets/basket/mini/',
77
78
  getBasketDetail: (namespace: string) => `/baskets/basket/${namespace}/`,
79
+ getMiniBasketDetail: (namespace: string) =>
80
+ `/baskets/basket/${namespace}/mini/`,
78
81
  getAllBaskets: '/baskets/basket-list/',
79
82
  removeBasket: (pk: number) => `/baskets/basket-list/${pk}/`,
80
83
  selectMainBasket: (pk: number) => `/baskets/basket-list/id/${pk}/main/`,
@@ -162,7 +165,8 @@ export const misc = {
162
165
  parent ? `&parent=${parent}` : ''
163
166
  }`,
164
167
  cmsSeo: (slug: string | string[]) => `/cms/seo/?url=${slug ? slug : '/'}`,
165
- setCurrency: '/users/activate-currency/'
168
+ setCurrency: '/users/activate-currency/',
169
+ bukalemunImageUrl: (params: string) => `/bukalemun/?${params}`
166
170
  };
167
171
 
168
172
  export const product = {
@@ -176,7 +180,9 @@ export const product = {
176
180
  slug: (slug: string) => `/${slug}/`,
177
181
  categoryUrl: (pk: number) => `/products/${pk}/category_nodes/?limit=1`,
178
182
  breadcrumbUrl: (menuitemmodel: string) =>
179
- `/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`
183
+ `/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`,
184
+ bundleProduct: (productPk: string, queryString: string) =>
185
+ `/bundle-product/${productPk}/?${queryString}`
180
186
  };
181
187
 
182
188
  export const wishlist = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@akinon/next",
3
3
  "description": "Core package for Project Zero Next",
4
- "version": "1.82.0-rc.4",
4
+ "version": "1.82.0-rc.6",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -30,7 +30,7 @@
30
30
  "set-cookie-parser": "2.6.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@akinon/eslint-plugin-projectzero": "1.82.0-rc.4",
33
+ "@akinon/eslint-plugin-projectzero": "1.82.0-rc.6",
34
34
  "@types/react-redux": "7.1.30",
35
35
  "@types/set-cookie-parser": "2.4.7",
36
36
  "@typescript-eslint/eslint-plugin": "6.7.4",
@@ -16,10 +16,8 @@ import {
16
16
  setLoyaltyBalance,
17
17
  setPaymentChoices,
18
18
  setPaymentOptions,
19
- setPreOrder,
20
19
  setRetailStores,
21
20
  setShippingOptions,
22
- setShippingStepCompleted,
23
21
  setHepsipayAvailability,
24
22
  setWalletPaymentData,
25
23
  setPayOnDeliveryOtpModalActive
@@ -59,146 +57,6 @@ export const errorMiddleware: Middleware = ({ dispatch }: MiddlewareParams) => {
59
57
  };
60
58
  };
61
59
 
62
- export const preOrderMiddleware: Middleware = ({
63
- getState,
64
- dispatch
65
- }: MiddlewareParams) => {
66
- return (next) => (action) => {
67
- const result: CheckoutResult = next(action);
68
- const preOrder = result?.payload?.pre_order;
69
-
70
- if (
71
- !preOrder ||
72
- action?.meta?.arg?.endpointName === 'guestLogin' ||
73
- action?.meta?.arg?.endpointName === 'getCheckoutLoyaltyBalance'
74
- ) {
75
- return result;
76
- }
77
-
78
- const {
79
- deliveryOptions,
80
- addressList: addresses,
81
- shippingOptions,
82
- dataSourceShippingOptions,
83
- paymentOptions,
84
- installmentOptions,
85
- attributeBasedShippingOptions
86
- } = getState().checkout;
87
- const { endpoints: apiEndpoints } = checkoutApi;
88
-
89
- if (preOrder.is_redirected) {
90
- const contextList = result?.payload?.context_list;
91
-
92
- if (
93
- contextList.find(
94
- (ctx) => ctx.page_name === 'RedirectionPaymentSelectedPage'
95
- )
96
- ) {
97
- dispatch(
98
- apiEndpoints.setPaymentOption.initiate(preOrder.payment_option?.pk)
99
- );
100
- return;
101
- }
102
- }
103
-
104
- dispatch(setPreOrder(preOrder));
105
-
106
- if (!preOrder.delivery_option && deliveryOptions.length > 0) {
107
- dispatch(
108
- apiEndpoints.setDeliveryOption.initiate(
109
- deliveryOptions.find((opt) => opt.delivery_option_type === 'customer')
110
- ?.pk
111
- )
112
- );
113
- }
114
-
115
- if (
116
- (!preOrder.shipping_address || !preOrder.billing_address) &&
117
- addresses.length > 0 &&
118
- (!preOrder.delivery_option ||
119
- preOrder.delivery_option.delivery_option_type === 'customer')
120
- ) {
121
- dispatch(
122
- apiEndpoints.setAddresses.initiate({
123
- shippingAddressPk: addresses[0].pk,
124
- billingAddressPk: addresses[0].pk
125
- })
126
- );
127
- }
128
-
129
- if (
130
- shippingOptions.length > 0 &&
131
- (!preOrder.shipping_option ||
132
- !shippingOptions.find((opt) => opt.pk === preOrder.shipping_option?.pk))
133
- ) {
134
- dispatch(apiEndpoints.setShippingOption.initiate(shippingOptions[0].pk));
135
- }
136
-
137
- if (
138
- dataSourceShippingOptions.length > 0 &&
139
- !preOrder.data_source_shipping_options
140
- ) {
141
- const selectedDataSourceShippingOptionsPks =
142
- dataSourceShippingOptions.map(
143
- (opt) => opt.data_source_shipping_options[0].pk
144
- );
145
-
146
- dispatch(
147
- apiEndpoints.setDataSourceShippingOptions.initiate(
148
- selectedDataSourceShippingOptionsPks
149
- )
150
- );
151
- }
152
-
153
- if (
154
- Object.keys(attributeBasedShippingOptions).length > 0 &&
155
- !preOrder.attribute_based_shipping_options
156
- ) {
157
- const initialSelectedOptions: Record<string, number> = Object.fromEntries(
158
- Object.entries(attributeBasedShippingOptions).map(([key, options]) => [
159
- key,
160
- options.attribute_based_shipping_options[0].pk
161
- ])
162
- );
163
-
164
- dispatch(
165
- apiEndpoints.setAttributeBasedShippingOptions.initiate(
166
- initialSelectedOptions
167
- )
168
- );
169
- }
170
-
171
- if (!preOrder.payment_option && paymentOptions.length > 0) {
172
- dispatch(apiEndpoints.setPaymentOption.initiate(paymentOptions[0].pk));
173
- }
174
-
175
- if (
176
- !preOrder.installment &&
177
- preOrder.payment_option?.payment_type !== 'saved_card' &&
178
- installmentOptions.length > 0
179
- ) {
180
- dispatch(
181
- apiEndpoints.setInstallmentOption.initiate(installmentOptions[0].pk)
182
- );
183
- }
184
-
185
- dispatch(
186
- setShippingStepCompleted(
187
- [
188
- preOrder.delivery_option?.delivery_option_type === 'retail_store'
189
- ? true
190
- : preOrder.shipping_address?.pk,
191
- preOrder.billing_address?.pk,
192
- preOrder.shipping_option?.pk,
193
- addresses.length > 0
194
- ].every(Boolean)
195
- )
196
- );
197
-
198
- return result;
199
- };
200
- };
201
-
202
60
  export const contextListMiddleware: Middleware = ({
203
61
  dispatch,
204
62
  getState
@@ -37,6 +37,8 @@ export const setAddressMiddleware: Middleware = ({
37
37
  billingAddressPk: firstAddressPk
38
38
  })
39
39
  );
40
+
41
+ return null;
40
42
  }
41
43
 
42
44
  return result;
@@ -33,6 +33,8 @@ export const attributeBasedShippingOptionMiddleware: Middleware = ({
33
33
  initialSelectedOptions
34
34
  )
35
35
  );
36
+
37
+ return null;
36
38
  }
37
39
 
38
40
  return result;
@@ -29,6 +29,8 @@ export const dataSourceShippingOptionMiddleware: Middleware = ({
29
29
  dispatch(
30
30
  apiEndpoints.setDataSourceShippingOptions.initiate(selectedPks)
31
31
  );
32
+
33
+ return null;
32
34
  }
33
35
  }
34
36
 
@@ -26,6 +26,8 @@ export const deliveryOptionMiddleware: Middleware = ({
26
26
  dispatch(
27
27
  apiEndpoints.setDeliveryOption.initiate(customerDeliveryOption)
28
28
  );
29
+
30
+ return null;
29
31
  }
30
32
  }
31
33
 
@@ -10,16 +10,20 @@ import { paymentOptionMiddleware } from './payment-option';
10
10
  import { installmentOptionMiddleware } from './installment-option';
11
11
  import { shippingStepMiddleware } from './shipping-step';
12
12
 
13
+ // ⚠️ WARNING: Redux Toolkit applies middlewares in reverse order (from last to first).
14
+ // This list is written **in reverse execution order** to ensure they run in the correct sequence.
15
+ // If you add a new middleware, make sure to insert it **in reverse order** based on execution priority.
16
+
13
17
  export const preOrderMiddlewares = [
14
- preOrderValidationMiddleware,
15
- redirectionMiddleware,
16
- setPreOrderMiddleware,
17
- deliveryOptionMiddleware,
18
- setAddressMiddleware,
19
- shippingOptionMiddleware,
20
- dataSourceShippingOptionMiddleware,
21
- attributeBasedShippingOptionMiddleware,
22
- paymentOptionMiddleware,
18
+ shippingStepMiddleware,
23
19
  installmentOptionMiddleware,
24
- shippingStepMiddleware
20
+ paymentOptionMiddleware,
21
+ attributeBasedShippingOptionMiddleware,
22
+ dataSourceShippingOptionMiddleware,
23
+ shippingOptionMiddleware,
24
+ setAddressMiddleware,
25
+ deliveryOptionMiddleware,
26
+ setPreOrderMiddleware,
27
+ redirectionMiddleware,
28
+ preOrderValidationMiddleware
25
29
  ];
@@ -28,6 +28,8 @@ export const installmentOptionMiddleware: Middleware = ({
28
28
  dispatch(
29
29
  apiEndpoints.setInstallmentOption.initiate(firstInstallmentOptionPk)
30
30
  );
31
+
32
+ return null;
31
33
  }
32
34
  }
33
35
 
@@ -21,6 +21,8 @@ export const paymentOptionMiddleware: Middleware = ({
21
21
  const firstPaymentOptionPk = paymentOptions[0]?.pk;
22
22
 
23
23
  dispatch(apiEndpoints.setPaymentOption.initiate(firstPaymentOptionPk));
24
+
25
+ return null;
24
26
  }
25
27
 
26
28
  return result;
@@ -26,6 +26,8 @@ export const redirectionMiddleware: Middleware = ({
26
26
  preOrder.payment_option?.pk
27
27
  )
28
28
  );
29
+
30
+ return null;
29
31
  }
30
32
  }
31
33
 
@@ -30,6 +30,8 @@ export const shippingOptionMiddleware: Middleware = ({
30
30
  dispatch(
31
31
  apiEndpoints.setShippingOption.initiate(defaultShippingOption)
32
32
  );
33
+
34
+ return null;
33
35
  }
34
36
  }
35
37