@evenicanpm/storefront-core 1.0.0-alpha → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/package.json +1 -1
  2. package/src/api-manager/api-manager.config.json +1 -1
  3. package/src/api-manager/datasources/d365/d365-address.datasource.ts +4 -4
  4. package/src/api-manager/datasources/d365/d365-cart.datasource.ts +100 -7
  5. package/src/api-manager/datasources/d365/d365-product.datasource.ts +39 -17
  6. package/src/api-manager/datasources/d365/d365-user.datasource.ts +220 -49
  7. package/src/api-manager/datasources/d365/utils/decode-jwt.ts +2 -2
  8. package/src/api-manager/datasources/e4/e4-cart.datasource.ts +6 -0
  9. package/src/api-manager/datasources/e4/e4-product.datasource.ts +5 -0
  10. package/src/api-manager/datasources/e4/e4-user.datasource.ts +39 -15
  11. package/src/api-manager/datasources/e4/e4.datasource.ts +1 -0
  12. package/src/api-manager/datasources/e4/e4.translator.ts +2 -1
  13. package/src/api-manager/datasources/e4/graphqlRequestSdk.ts +5231 -38282
  14. package/src/api-manager/index.ts +58 -11
  15. package/src/api-manager/lib/get-graphql-client.ts +7 -7
  16. package/src/api-manager/schemas/address.schema.ts +1 -19
  17. package/src/api-manager/schemas/cart.schema.ts +18 -0
  18. package/src/api-manager/schemas/product.schema.ts +7 -0
  19. package/src/api-manager/schemas/user.schema.ts +52 -1
  20. package/src/api-manager/services/address/queries/get-states.ts +1 -1
  21. package/src/api-manager/services/cart/mutations/checkout.ts +16 -1
  22. package/src/api-manager/services/cart/queries/get-cart-lines-inventory.ts +15 -0
  23. package/src/api-manager/services/create-extension-query.ts +26 -0
  24. package/src/api-manager/services/create-mutation.ts +5 -1
  25. package/src/api-manager/services/create-query.ts +0 -1
  26. package/src/api-manager/services/organization/queries/get-channel-configuration.ts +1 -1
  27. package/src/api-manager/services/product/queries/get-product-prices.ts +16 -0
  28. package/src/api-manager/services/product/queries/search-products.ts +1 -0
  29. package/src/api-manager/services/user/mutations/add-to-wishlist.ts +24 -0
  30. package/src/api-manager/services/user/mutations/copy-cart-to-wishlist.ts +23 -0
  31. package/src/api-manager/services/user/mutations/create-wishlist.ts +4 -4
  32. package/src/api-manager/services/user/mutations/delete-wishlist.ts +4 -3
  33. package/src/api-manager/services/user/mutations/remove-from-wishlist.ts +21 -0
  34. package/src/api-manager/services/user/mutations/update-wishlist.ts +23 -0
  35. package/src/api-manager/services/user/queries/get-wishlist-details.ts +11 -4
  36. package/src/api-manager/services/user/queries/get-wishlists.ts +4 -3
  37. package/src/api-manager/types/Datasource.ts +33 -5
  38. package/src/auth/auth-options.ts +2 -2
  39. package/src/auth/msal.ts +9 -9
  40. package/src/auth/next-auth-cookie-manager.ts +5 -3
  41. package/src/auth/providers/aadb2c-provider.ts +3 -4
  42. package/src/cms/endpoints.ts +2 -3
  43. package/src/components/_components/LazyImage.tsx +5 -2
  44. package/src/components/_components/header/components/user.tsx +1 -2
  45. package/src/components/_components/product-cards/product-card-1/components/quantity-buttons.tsx +17 -8
  46. package/src/components/_components/product-cards/product-card-1/product-card-1-wrapper.tsx +304 -0
  47. package/src/components/_components/product-cards/product-card-1/product-card.tsx +16 -55
  48. package/src/components/_components/product-cards/product-card-8/product-card.tsx +80 -60
  49. package/src/components/_components/product-cards/product-card-8/styles/index.ts +10 -0
  50. package/src/components/_components/product-cards/product-card-wishlist/components/hover-actions.tsx +37 -0
  51. package/src/components/_components/product-cards/product-card-wishlist/index.ts +1 -0
  52. package/src/components/_components/product-cards/product-card-wishlist/product-card.tsx +118 -0
  53. package/src/components/_components/product-cards/product-card-wishlist/styles/index.ts +51 -0
  54. package/src/components/_components/products-view/product-view-dialog.tsx +48 -10
  55. package/src/components/_components/products-view/products-grid-view.tsx +31 -17
  56. package/src/components/_components/products-view/products-list-view.tsx +30 -16
  57. package/src/components/_components/search-box/__test__/search-input-category.test.tsx +110 -0
  58. package/src/components/_components/search-box/__test__/search-input.test.tsx +137 -0
  59. package/src/components/_components/search-box/__test__/search-results.json +165 -0
  60. package/src/components/_components/search-box/components/search-result.tsx +66 -12
  61. package/src/components/_components/search-box/search-input-category.tsx +135 -32
  62. package/src/components/_components/search-box/styles/index.ts +2 -0
  63. package/src/components/_components/section-header/section-creator.tsx +1 -0
  64. package/src/components/_components/wishlist/add-to-wishlist-dialog.tsx +161 -0
  65. package/src/components/_components/wishlist/components/create-new-list.tsx +167 -0
  66. package/src/components/_components/wishlist/components/create-wishlist-button.tsx +40 -0
  67. package/src/components/_components/wishlist/components/dashboard-header.tsx +123 -0
  68. package/src/components/_components/wishlist/components/navigation.tsx +87 -0
  69. package/src/components/_components/wishlist/components/no-records.tsx +20 -0
  70. package/src/components/_components/wishlist/components/wishlist-modal-item.tsx +66 -0
  71. package/src/components/_components/wishlist/remove-from-wishlist-dialog.tsx +174 -0
  72. package/src/components/_components/wishlist/styles.ts +61 -0
  73. package/src/components/countries-input.tsx +6 -12
  74. package/src/lib/cart-cookie-handler-constants.ts +8 -0
  75. package/src/lib/cart-cookie-handler.ts +27 -5
  76. package/src/lib/create-graphql-client.ts +1 -2
  77. package/src/lib/product-list-types.ts +41 -0
  78. package/src/config.ts +0 -47
@@ -4,6 +4,7 @@ import { D365Datasource } from "./datasources/d365/index";
4
4
  import rawConfig from "./api-manager.config.json";
5
5
  import { z } from "zod";
6
6
  import { getContextFromCookie } from "./datasources/d365/utils/get-context-cookie";
7
+
7
8
  type EntityNames = keyof DatasourceApis;
8
9
 
9
10
  interface Config {
@@ -18,9 +19,25 @@ const Config = z.object({
18
19
  overrides: z.record(z.string(), z.string()),
19
20
  });
20
21
 
22
+ const OVERRIDES_FILE = "./overrides.datasource.ts";
23
+ const CORE_DATASOURCES = [
24
+ "user",
25
+ "session",
26
+ "cart",
27
+ "product",
28
+ "categories",
29
+ "order",
30
+ "address",
31
+ "organization",
32
+ ];
21
33
  /**
22
34
  * Loads up all specified apis/datasources based on parsed config
23
- * and returns the ApiManager object.
35
+ * and returns the ApiManager object. Also handles "project" overrides
36
+ * by checking inside a specific folder for API's. Will grab default export
37
+ * from specified folder, validate the API schema and then prioritize returning
38
+ * that from api-manager.
39
+ *
40
+ * In this way, we have two levels of configuration of the api-manager.
24
41
  * @returns ApiManager object.
25
42
  */
26
43
  async function createApiManager() {
@@ -32,6 +49,26 @@ async function createApiManager() {
32
49
  }
33
50
  }
34
51
 
52
+ const storefrontOverrides: { [key: string]: any } = {};
53
+
54
+ // @ts-ignore
55
+ function importAll(r) {
56
+ r.keys().forEach(
57
+ (key: keyof typeof storefrontOverrides) =>
58
+ (storefrontOverrides[key] = r(key)),
59
+ );
60
+ }
61
+
62
+ // Arguments must be literals not variables.
63
+ importAll(
64
+ // @ts-ignore
65
+ require.context(
66
+ "@storefront/extensions/api-manager-overrides",
67
+ true,
68
+ /overrides\.datasource\.ts/,
69
+ ),
70
+ );
71
+
35
72
  const context = await getContextFromCookie();
36
73
  const datasourceMap: Record<string, Datasource> = {
37
74
  d365: new D365Datasource("d365", context),
@@ -46,6 +83,11 @@ async function createApiManager() {
46
83
  );
47
84
 
48
85
  const getDatasource = (entityName: EntityNames) => {
86
+ // Overrides from storefront
87
+ if (storefrontOverrides?.[OVERRIDES_FILE]?.["default"]?.[entityName]) {
88
+ return storefrontOverrides[OVERRIDES_FILE]["default"];
89
+ }
90
+
49
91
  const override = config?.overrides?.[entityName];
50
92
  if (override) {
51
93
  return (
@@ -55,17 +97,22 @@ async function createApiManager() {
55
97
  }
56
98
  return primaryDatasource;
57
99
  };
100
+ const datasources = {};
58
101
 
59
- return {
60
- user: getDatasource("user").user,
61
- session: getDatasource("session").session,
62
- cart: getDatasource("cart").cart,
63
- product: getDatasource("product").product,
64
- categories: getDatasource("categories").categories,
65
- order: getDatasource("order").order,
66
- address: getDatasource("address").address,
67
- organization: getDatasource("organization").organization,
68
- };
102
+ CORE_DATASOURCES.forEach((entityName) => {
103
+ const datasource = getDatasource(entityName as EntityNames);
104
+ datasources[entityName] = datasource[entityName];
105
+ });
106
+ storefrontOverrides[OVERRIDES_FILE]?.default &&
107
+ Object.keys(storefrontOverrides[OVERRIDES_FILE]["default"]).forEach(
108
+ (key) => {
109
+ if (!CORE_DATASOURCES.includes(key)) {
110
+ datasources[key] =
111
+ storefrontOverrides[OVERRIDES_FILE]["default"][key];
112
+ }
113
+ },
114
+ );
115
+ return datasources;
69
116
  }
70
117
 
71
118
  export default createApiManager;
@@ -6,9 +6,6 @@ import { getServerSession } from "next-auth/next";
6
6
  // TODO: Get auth inside client packages
7
7
  import authOptions from "@/auth/auth-options";
8
8
  import { cookies } from "next/headers";
9
-
10
- const API_URL = process.env.REACT_APP_E4_API_ENDPOINT; //`https://api.e4.local/graphql`;
11
-
12
9
  /**
13
10
  * Initializes and returns a cached GraphQL client
14
11
  * @param withAuth (optional) - If true, includes the authorization token
@@ -41,10 +38,13 @@ const getGraphQLClient = async (withAuth = false) => {
41
38
 
42
39
  // Best Practice: Never reuse a GraphQL client that mutates headers across different requests in server environments.
43
40
  // When we resuse the client instance, sometimes the token is missing in e4 backend.
44
- const client = new GraphQLClient(API_URL, {
45
- headers,
46
- credentials: "include",
47
- });
41
+ const client = new GraphQLClient(
42
+ process.env.NEXT_PUBLIC_E4_API_ENDPOINT || "",
43
+ {
44
+ headers,
45
+ credentials: "include",
46
+ },
47
+ );
48
48
 
49
49
  client.setHeaders(headers);
50
50
  return getSdk(client);
@@ -9,25 +9,6 @@ export const addressTypeSchema = z
9
9
  })
10
10
  .optional();
11
11
 
12
- // export const addressSchema = z.object({
13
- // Id:z.string().optional(),
14
- // Name:z.string().optional(),
15
- // FirstName: z.string().optional(),
16
- // LastName: z.string().optional(),
17
- // IsPrimary:z.boolean().optional(),
18
- // AddressType: addressTypeSchema,
19
- // AddressLine1: z.string().optional(),
20
- // AddressLine2: z.string().optional(),
21
- // City: z.string().optional(),
22
- // StateId: z.string().optional(),
23
- // StateName: z.string().optional(),
24
- // CountryId: z.string().optional(),
25
- // CountryName: z.string().optional(),
26
- // CountryCode: z.string().optional(),
27
- // ZipCode: z.string().optional(),
28
- // Phone: z.string().optional(),
29
- // });
30
-
31
12
  const getCountriesInput = z.object({
32
13
  locale: z.string().optional(),
33
14
  });
@@ -40,6 +21,7 @@ const getDeliveryOptionsInput = z.object({
40
21
  shippingAddress: addressSchema,
41
22
  cartLineIds: z.array(z.string()),
42
23
  });
24
+
43
25
  export type GetCountriesInput = z.infer<typeof getCountriesInput>;
44
26
  export type GetStatesInput = z.infer<typeof getStatesInput>;
45
27
  export type GetDeliveryOptionsInput = z.infer<typeof getDeliveryOptionsInput>;
@@ -4,6 +4,7 @@ import {
4
4
  cartLineSchema,
5
5
  cartSchema,
6
6
  retrievePaymentResultSettingsSchema,
7
+ searchAreaSchema,
7
8
  simpleProductSchema,
8
9
  tokenizedPaymentCardSchema,
9
10
  } from "./d365.schema";
@@ -67,6 +68,20 @@ export const removeCartLineDeliveryModeInput = z.object({
67
68
  cart: extendedCartSchema.partial(),
68
69
  });
69
70
 
71
+ const SimpleCartLinesSearchCriteria = z.object({
72
+ productId: z.number(),
73
+ deliveryMode: z.string().optional(),
74
+ inventLocationId: z.string().optional(),
75
+ });
76
+
77
+ const InventorySearchCartLinesCriteriaInput = z.object({
78
+ searchCriteria: z.object({
79
+ cartLines: SimpleCartLinesSearchCriteria.array(),
80
+ searchArea: searchAreaSchema.optional(),
81
+ }),
82
+ allDimensionsSelected: z.boolean(),
83
+ });
84
+
70
85
  // Typescript Types
71
86
  // export type Cart = z.infer<typeof cartSchema>;
72
87
  // export type CartLine = z.infer<typeof cartLineSchema>;
@@ -90,3 +105,6 @@ export type RemoveCartLineDeliveryModeInput = z.infer<
90
105
  typeof removeCartLineDeliveryModeInput
91
106
  >;
92
107
  export type CheckoutInput = z.infer<typeof checkoutInput>;
108
+ export type InventorySearchCartLinesCriteriaInput = z.infer<
109
+ typeof InventorySearchCartLinesCriteriaInput
110
+ >;
@@ -6,6 +6,7 @@ import {
6
6
  productSearchResultSchema,
7
7
  queryResultSettingsSchema,
8
8
  searchAreaSchema,
9
+ productPriceSchema,
9
10
  } from "./d365.schema";
10
11
  import {
11
12
  AttributeValue,
@@ -117,6 +118,10 @@ const InventorySearchCriteriaInput = z.object({
117
118
  allDimensionsSelected: z.boolean(),
118
119
  });
119
120
 
121
+ const productPriceInput = z.object({
122
+ productIds: z.number().array(),
123
+ });
124
+
120
125
  // entities
121
126
  export type Product = z.infer<typeof productSchema>;
122
127
  export type ProductDetails = SimpleProduct & {
@@ -138,3 +143,5 @@ export type SearchByCriteriaResponse = z.infer<typeof searchByCriteriaResponse>;
138
143
  export type InventorySearchCriteriaInput = z.infer<
139
144
  typeof InventorySearchCriteriaInput
140
145
  >;
146
+ export type ProductPrice = z.infer<typeof productPriceSchema>;
147
+ export type ProductPriceInput = z.infer<typeof productPriceInput>;
@@ -1,5 +1,10 @@
1
1
  import z from "zod";
2
- import { customerSchema } from "./d365.schema";
2
+ import {
3
+ customerSchema,
4
+ productListLineSchema,
5
+ productListSchema,
6
+ simpleProductSchema,
7
+ } from "./d365.schema";
3
8
 
4
9
  export const userCountsSchema = z.object({
5
10
  orderCount: z.number().optional(),
@@ -12,3 +17,49 @@ export const extendedCustomerSchema = customerSchema.extend({
12
17
 
13
18
  export type User = z.infer<typeof extendedCustomerSchema>;
14
19
  export type UserCounts = z.infer<typeof userCountsSchema>;
20
+
21
+ // Wishlist
22
+
23
+ export const extendedProductListLineSchema = productListLineSchema.extend({
24
+ Product: simpleProductSchema.optional(),
25
+ });
26
+
27
+ export const extendedWishlistSchema = productListSchema
28
+ .omit({ ProductListLines: true })
29
+ .extend({ ProductListLines: extendedProductListLineSchema.array() });
30
+
31
+ const wishlistBaseInput = z.object({
32
+ Id: z.string(),
33
+ });
34
+
35
+ export const wishlistCreateInput = wishlistBaseInput.extend({
36
+ Name: z.string(),
37
+ Comment: z.string().optional(),
38
+ IsPublic: z.boolean().optional(),
39
+ });
40
+
41
+ const updateWishlistInput = wishlistBaseInput.extend({
42
+ Name: z.string(),
43
+ });
44
+
45
+ const wishlistLinesInput = wishlistBaseInput.extend({
46
+ ProductListLines: productListLineSchema.array(),
47
+ });
48
+
49
+ const copyCartToWishlistInput = z.object({
50
+ Id: z.string(),
51
+ CartID: z.string(),
52
+ IsRewrite: z.boolean(),
53
+ IsQuantityAggregate: z.boolean(),
54
+ });
55
+
56
+ export type Wishlist = z.infer<typeof productListSchema>;
57
+ export type ExtendedWishlist = z.infer<typeof extendedWishlistSchema>;
58
+ export type ExtendedProductListLine = z.infer<
59
+ typeof extendedProductListLineSchema
60
+ >;
61
+ export type WishlistDetailInput = z.infer<typeof wishlistBaseInput>;
62
+ export type WishlistCreateInput = z.infer<typeof wishlistCreateInput>;
63
+ export type UpdateWishlistInput = z.infer<typeof updateWishlistInput>;
64
+ export type WishlistLinesInput = z.infer<typeof wishlistLinesInput>;
65
+ export type CopyCartToWishlistInput = z.infer<typeof copyCartToWishlistInput>;
@@ -5,7 +5,7 @@ import { createQuery, createApiPath } from "../../create-query";
5
5
  const apiPath = createApiPath("address", "getStates");
6
6
  const config = {
7
7
  queryKey: "states",
8
- disablePropertis: ["countryId"],
8
+ disableProperties: ["countryId"],
9
9
  };
10
10
 
11
11
  const getStates = createQuery<GetStatesInput, StateProvinceInfo[]>(
@@ -1,11 +1,26 @@
1
1
  import { Cart, CheckoutInput } from "@/api-manager/schemas/cart.schema";
2
2
  import { createApiPath } from "../../create-query";
3
3
  import { useCreateMutation } from "../../create-mutation";
4
+ import { deleteCartCookie } from "@/api-manager/lib/cart-cookie-handler";
5
+ import getCart from "../queries/get-cart";
6
+ import { useQueryClient } from "@tanstack/react-query";
4
7
 
5
8
  const apiPath = createApiPath("cart", "checkout");
6
9
 
7
10
  const useCheckout = () => {
8
- return useCreateMutation<CheckoutInput, Cart>(apiPath);
11
+ const queryClient = useQueryClient();
12
+ return useCreateMutation<CheckoutInput, Cart>(apiPath, {
13
+ onSuccess: async (_data, variables) => {
14
+ // Delete old cart cookie
15
+ await deleteCartCookie();
16
+
17
+ queryClient.invalidateQueries({ queryKey: ["cart"] });
18
+ },
19
+ onError: (error) => {
20
+ console.error("Checkout failed:", error);
21
+ // Handle error appropriately, e.g., show a notification
22
+ },
23
+ });
9
24
  };
10
25
 
11
26
  export default useCheckout;
@@ -0,0 +1,15 @@
1
+ import { ProductWarehouseInventoryInformation } from "@msdyn365-commerce/retail-proxy";
2
+ import { InventorySearchCartLinesCriteriaInput } from "@/api-manager/schemas/cart.schema";
3
+ import { createApiPath, createQuery } from "../../create-query";
4
+
5
+ const apiPath = createApiPath("cart", "getCartLinesInventory");
6
+
7
+ const getCartLinesInventory = createQuery<
8
+ InventorySearchCartLinesCriteriaInput,
9
+ ProductWarehouseInventoryInformation
10
+ >(apiPath, {
11
+ queryKey: "cart-lines-Inventory",
12
+ disableProperties: ["allDimensionsSelected", "searchCriteria"],
13
+ });
14
+
15
+ export default getCartLinesInventory;
@@ -0,0 +1,26 @@
1
+ import { QueryFunction } from "@tanstack/react-query";
2
+
3
+ /**
4
+ * This is a wrapper function for building an extension query.
5
+ * We don't require full-blown api-manager instance for extensions,
6
+ * because there is no data switching. Also not exporting all the react-query
7
+ * methods to keep the code flexible and adaptable for projects. This wrapper
8
+ * handles client side mutex to prevent multiple requests firing after refresh
9
+ * token has been found to be expired.
10
+ *
11
+ * During development, any additional hooks, events and extensions can be added to
12
+ * this function without affecting project.
13
+ *
14
+ * @param queryKey
15
+ * @param queryFn
16
+ * @returns
17
+ */
18
+ const buildQueryData = <TQueryFnData = unknown, TQueryFnInput = unknown>(
19
+ queryKey: string,
20
+ queryFn: QueryFunction<TQueryFnData>,
21
+ ) => {
22
+ // TODO: insert mutex stuff here
23
+ return { queryKey: [queryKey], queryFn };
24
+ };
25
+
26
+ export default buildQueryData;
@@ -31,7 +31,11 @@ export const useCreateMutation = <TInput, TOutput>(
31
31
  body: JSON.stringify({ input, apiManagerPath }),
32
32
  });
33
33
  if (!response.ok) {
34
- throw new Error("Mutation failed");
34
+ const error = await response.json();
35
+ let errorMsg = `${error.error}`;
36
+ if (error.message) errorMsg += ` - ${error.message}`;
37
+
38
+ throw new Error(errorMsg);
35
39
  }
36
40
  return response.json();
37
41
  },
@@ -79,7 +79,6 @@ export const createQuery = <TInput, TOutput>(
79
79
  queryFn,
80
80
  enabled,
81
81
  };
82
-
83
82
  return data;
84
83
  };
85
84
 
@@ -6,7 +6,7 @@ const config = {
6
6
  queryKey: "channelConfiguration",
7
7
  };
8
8
 
9
- const getChannelConfiguration = createQuery<null, ChannelConfiguration[]>(
9
+ const getChannelConfiguration = createQuery<null, ChannelConfiguration>(
10
10
  apiPath,
11
11
  config,
12
12
  );
@@ -0,0 +1,16 @@
1
+ import {
2
+ ProductPriceInput,
3
+ ProductPrice,
4
+ } from "@/api-manager/schemas/product.schema";
5
+ import { createApiPath, createQuery } from "../../create-query";
6
+
7
+ const apiPath = createApiPath("product", "getProductPrices");
8
+
9
+ const getProductPrices = createQuery<ProductPriceInput, ProductPrice[]>(
10
+ apiPath,
11
+ {
12
+ queryKey: "product-prices",
13
+ },
14
+ );
15
+
16
+ export default getProductPrices;
@@ -5,6 +5,7 @@ import { createApiPath, createQuery } from "../../create-query";
5
5
  const apiPath = createApiPath("product", "searchProducts");
6
6
  const searchProducts = createQuery<searchProductsInput, ProductSearchResult[]>(
7
7
  apiPath,
8
+ { disableProperties: ["searchText"] },
8
9
  );
9
10
 
10
11
  export default searchProducts;
@@ -0,0 +1,24 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import {
3
+ Wishlist,
4
+ WishlistLinesInput,
5
+ } from "@/api-manager/schemas/user.schema";
6
+ import { createApiPath } from "../../create-query";
7
+ import { useCreateMutation } from "../../create-mutation";
8
+ import { getWishlistsQueryKey } from "../queries/get-wishlists";
9
+
10
+ const apiPath = createApiPath("user", "addProductsToWishlist");
11
+
12
+ const useAddToWishlist = () => {
13
+ const queryClient = useQueryClient();
14
+
15
+ return useCreateMutation<WishlistLinesInput, Wishlist>(apiPath, {
16
+ onSuccess: (_data, variables) => {
17
+ queryClient.invalidateQueries({
18
+ queryKey: [getWishlistsQueryKey, variables.Id],
19
+ });
20
+ },
21
+ });
22
+ };
23
+
24
+ export default useAddToWishlist;
@@ -0,0 +1,23 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import {
3
+ CopyCartToWishlistInput,
4
+ Wishlist,
5
+ } from "@/api-manager/schemas/user.schema";
6
+ import { createApiPath } from "../../create-query";
7
+ import { useCreateMutation } from "../../create-mutation";
8
+
9
+ const apiPath = createApiPath("user", "copyCartToWishlist");
10
+
11
+ const useCopyCartToWishlist = () => {
12
+ const queryClient = useQueryClient();
13
+
14
+ return useCreateMutation<CopyCartToWishlistInput, Wishlist>(apiPath, {
15
+ onSuccess: (_data, _variables) => {
16
+ queryClient.invalidateQueries({
17
+ queryKey: ["wishlistDetails", _variables.Id],
18
+ });
19
+ },
20
+ });
21
+ };
22
+
23
+ export default useCopyCartToWishlist;
@@ -2,16 +2,16 @@ import { useQueryClient } from "@tanstack/react-query";
2
2
  import { createApiPath } from "../../create-query";
3
3
  import { useCreateMutation } from "../../create-mutation";
4
4
  import {
5
- CreateWishListInput,
6
- WishList,
7
- } from "../../../datasources/e4/graphqlRequestSdk";
5
+ Wishlist,
6
+ WishlistCreateInput,
7
+ } from "@/api-manager/schemas/user.schema";
8
8
 
9
9
  const apiPath = createApiPath("user", "createWishlist");
10
10
 
11
11
  const useCreateWishlist = () => {
12
12
  const queryClient = useQueryClient();
13
13
 
14
- return useCreateMutation<CreateWishListInput, WishList>(apiPath, {
14
+ return useCreateMutation<WishlistCreateInput, Wishlist>(apiPath, {
15
15
  onSuccess: () => {
16
16
  queryClient.invalidateQueries({ queryKey: ["wishlists"] });
17
17
  },
@@ -1,17 +1,18 @@
1
1
  import { useQueryClient } from "@tanstack/react-query";
2
2
  import { createApiPath } from "../../create-query";
3
3
  import { useCreateMutation } from "../../create-mutation";
4
+ import { WishlistDetailInput } from "@/api-manager/schemas/user.schema";
5
+ import { getWishlistsQueryKey } from "../queries/get-wishlists";
4
6
 
5
7
  const apiPath = createApiPath("user", "deleteWishlist");
6
8
 
7
9
  const useDeleteWishlist = () => {
8
10
  const queryClient = useQueryClient();
9
11
 
10
- return useCreateMutation<string, string>(apiPath, {
12
+ return useCreateMutation<WishlistDetailInput, void>(apiPath, {
11
13
  onSuccess: () => {
12
- queryClient.invalidateQueries({ queryKey: ["wishlists"] });
14
+ queryClient.invalidateQueries({ queryKey: [getWishlistsQueryKey] });
13
15
  },
14
16
  });
15
17
  };
16
-
17
18
  export default useDeleteWishlist;
@@ -0,0 +1,21 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import { WishlistLinesInput } from "@/api-manager/schemas/user.schema";
3
+ import { createApiPath } from "../../create-query";
4
+ import { useCreateMutation } from "../../create-mutation";
5
+ import { getWishlistDetailsQueryKey } from "../queries/get-wishlist-details";
6
+
7
+ const apiPath = createApiPath("user", "removeProductsFromWishlist");
8
+
9
+ const useRemoveFromWishlist = () => {
10
+ const queryClient = useQueryClient();
11
+
12
+ return useCreateMutation<WishlistLinesInput, void>(apiPath, {
13
+ onSuccess: (_data, _variables) => {
14
+ queryClient.invalidateQueries({
15
+ queryKey: [getWishlistDetailsQueryKey, { Id: _variables.Id }],
16
+ });
17
+ },
18
+ });
19
+ };
20
+
21
+ export default useRemoveFromWishlist;
@@ -0,0 +1,23 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import {
3
+ Wishlist,
4
+ WishlistLinesInput,
5
+ } from "@/api-manager/schemas/user.schema";
6
+ import { useCreateMutation } from "../../create-mutation";
7
+ import { createApiPath } from "../../create-query";
8
+
9
+ const apiPath = createApiPath("user", "updateWishlist");
10
+
11
+ const useUpdateWishlist = () => {
12
+ const queryClient = useQueryClient();
13
+
14
+ return useCreateMutation<WishlistLinesInput, Wishlist>(apiPath, {
15
+ onSuccess: (_data, _variables) => {
16
+ queryClient.invalidateQueries({
17
+ queryKey: ["wishlistDetails", _variables.Id],
18
+ });
19
+ },
20
+ });
21
+ };
22
+
23
+ export default useUpdateWishlist;
@@ -1,10 +1,17 @@
1
+ import {
2
+ ExtendedWishlist,
3
+ WishlistDetailInput,
4
+ } from "@/api-manager/schemas/user.schema";
1
5
  import { createApiPath, createQuery } from "../../create-query";
2
- import { WishList } from "../../../datasources/e4/graphqlRequestSdk";
3
6
 
7
+ export const getWishlistDetailsQueryKey = "wish-list-details";
4
8
  const apiPath = createApiPath("user", "getWishlistDetails");
5
9
 
6
- const getWishListDetails = createQuery<string, WishList>(apiPath, {
7
- queryKey: "wish-list-details",
8
- });
10
+ const getWishListDetails = createQuery<WishlistDetailInput, ExtendedWishlist>(
11
+ apiPath,
12
+ {
13
+ queryKey: getWishlistDetailsQueryKey,
14
+ },
15
+ );
9
16
 
10
17
  export default getWishListDetails;
@@ -1,10 +1,11 @@
1
- import { WishList } from "../../../datasources/e4/graphqlRequestSdk";
1
+ import { Wishlist } from "@/api-manager/schemas/user.schema";
2
2
  import { createApiPath, createQuery } from "../../create-query";
3
3
 
4
+ export const getWishlistsQueryKey = "wishlists";
4
5
  const apiPath = createApiPath("user", "getWishlists");
5
6
 
6
- const getWishlists = createQuery<null, WishList[]>(apiPath, {
7
- queryKey: "wish-lists",
7
+ const getWishlists = createQuery<null, Wishlist[]>(apiPath, {
8
+ queryKey: getWishlistsQueryKey,
8
9
  });
9
10
 
10
11
  export default getWishlists;