@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
@@ -8,18 +8,50 @@ import CategoryDropdown from "./components/category-dropdown";
8
8
  // CUSTOM ICON COMPONENT
9
9
  import Search from "@/components/_components/icons/search";
10
10
  import { useTranslations } from "next-intl";
11
- import React, { useState } from "react";
11
+ import React, { FormEvent, useState } from "react";
12
12
  import getCategories from "@/services/categories/queries/get-categories";
13
13
  import searchProducts from "@/services/product/queries/search-products";
14
14
  import { INPUT_SX } from "./styles/index";
15
15
  import _ from "lodash";
16
+ import ProductViewDialog, {
17
+ ProductInfo,
18
+ } from "../products-view/product-view-dialog";
19
+ import { IconButton } from "@mui/material";
20
+ import { usePathname, useRouter } from "next/navigation";
21
+ import { PageSlug } from "@/lib/page-slugs";
22
+ import { PageKey } from "@/lib/product-list-types";
23
+ import AddToWishlistDialog from "../wishlist/add-to-wishlist-dialog";
24
+ import RemoveFromWishlistDialog from "../wishlist/remove-from-wishlist-dialog";
25
+ import getCart from "@/api-manager/services/cart/queries/get-cart";
26
+
27
+ export enum DialogType {
28
+ AddToWishlist = "addToWishlist",
29
+ RemoveFromWishlist = "removeFromWishlist",
30
+ QuickView = "quickView",
31
+ }
32
+
33
+ type DialogState = {
34
+ type: DialogType | null;
35
+ productId: number | null;
36
+ productInfo?: ProductInfo; // for quick view
37
+ };
38
+
39
+ type Props = {
40
+ cartId?: string;
41
+ };
16
42
 
17
43
  export default function SearchInputWithCategory() {
18
44
  const t = useTranslations();
19
-
45
+ const { data: cart } = getCart.useData();
20
46
  const [resultsOpen, setResultsOpen] = useState(false);
21
47
  const [searchText, setSearchText] = React.useState<string>("");
22
48
  const [selectedCategory, setSelectedCategory] = React.useState<number>(0);
49
+ const router = useRouter();
50
+ const pathname = usePathname();
51
+ const [dialogState, setDialogState] = useState<DialogState>({
52
+ type: null, // the type of dialog to open (add to/remove from wishlist, quick view)
53
+ productId: null,
54
+ });
23
55
 
24
56
  const { data: resultList } = searchProducts.useData({
25
57
  searchText,
@@ -48,18 +80,29 @@ export default function SearchInputWithCategory() {
48
80
 
49
81
  const debounceSearch = _.debounce(handleSearchChange, 500);
50
82
 
83
+ const handleNavigate = () => {
84
+ if (searchText.trim() === "") {
85
+ return;
86
+ }
87
+ const url = new URL(PageSlug.ProductList, window.location.origin);
88
+ url.searchParams.set(PageKey.SEARCH, searchText);
89
+
90
+ router.push(url.toString());
91
+ };
51
92
  const INPUT_PROPS = {
52
93
  startAdornment: (
53
94
  <Box
54
- mr={2}
55
- px={2}
95
+ mr={1}
96
+ px={1}
56
97
  display="grid"
57
98
  alignItems="center"
58
99
  justifyContent="center"
59
100
  borderRight="1px solid"
60
101
  borderColor="grey.400"
61
102
  >
62
- <Search sx={{ fontSize: 17, color: "grey.600" }} />
103
+ <IconButton onClick={handleNavigate}>
104
+ <Search sx={{ fontSize: 17, color: "grey.600" }} />
105
+ </IconButton>
63
106
  </Box>
64
107
  ),
65
108
  endAdornment: (
@@ -71,34 +114,94 @@ export default function SearchInputWithCategory() {
71
114
  ),
72
115
  };
73
116
 
117
+ const openDialog = (
118
+ type: DialogType,
119
+ productId: number,
120
+ productInfo?: ProductInfo,
121
+ ) => {
122
+ setDialogState({
123
+ type,
124
+ productId,
125
+ productInfo,
126
+ });
127
+ setResultsOpen(false);
128
+ };
129
+
130
+ function handleSubmit(event: FormEvent<HTMLFormElement>): void {
131
+ event.preventDefault();
132
+ handleNavigate();
133
+ setResultsOpen(false);
134
+ setSearchText("");
135
+ setSelectedCategory(0);
136
+ }
137
+
138
+ const handleCloseDialog = () => {
139
+ setDialogState({
140
+ type: null,
141
+ productId: null,
142
+ productInfo: undefined,
143
+ });
144
+ };
145
+
146
+ const handleAddRemoveSuccess = () => {
147
+ // Implement
148
+ };
149
+
74
150
  return (
75
- <Box
76
- position="relative"
77
- flex="1 1 0"
78
- maxWidth="670px"
79
- mx="auto"
80
- // {...{ ref: parentRef }}
81
- >
82
- <TextField
83
- fullWidth
84
- variant="outlined"
85
- placeholder={t("Search.searchPlaceholder")}
86
- onChange={debounceSearch}
87
- InputProps={{ ...INPUT_PROPS, sx: INPUT_SX }}
88
- onFocus={() => {
89
- setResultsOpen(true);
90
- }}
91
- onBlur={() => {
92
- // must use timeout to prevent
93
- // onClick event not firing in time
94
- // when selecting menu items
95
- setResultsOpen(false);
96
- }}
97
- />
151
+ <>
152
+ <Box position="relative" flex="1 1 0" maxWidth="670px" mx="auto">
153
+ <form onSubmit={handleSubmit}>
154
+ <TextField
155
+ fullWidth
156
+ variant="outlined"
157
+ placeholder={t("Search.searchPlaceholder")}
158
+ onChange={debounceSearch}
159
+ InputProps={{ ...INPUT_PROPS, sx: INPUT_SX }}
160
+ onFocus={() => {
161
+ setResultsOpen(true);
162
+ }}
163
+ onBlur={() => {
164
+ setTimeout(() => {
165
+ setResultsOpen(false);
166
+ }, 500);
167
+ }}
168
+ />
169
+ </form>
170
+
171
+ {resultList && resultList?.length > 0 && resultsOpen ? (
172
+ <SearchResult results={resultList} openDialog={openDialog} />
173
+ ) : null}
174
+ </Box>
175
+ {/* Dialog */}
176
+ {dialogState.type === DialogType.AddToWishlist &&
177
+ dialogState.productId && (
178
+ <AddToWishlistDialog
179
+ open={dialogState.type === DialogType.AddToWishlist}
180
+ handleClose={handleCloseDialog}
181
+ productId={dialogState.productId}
182
+ onSuccess={handleAddRemoveSuccess}
183
+ />
184
+ )}
185
+ {dialogState.type === DialogType.RemoveFromWishlist &&
186
+ dialogState.productId && (
187
+ <RemoveFromWishlistDialog
188
+ open={dialogState.type === DialogType.RemoveFromWishlist}
189
+ handleClose={handleCloseDialog}
190
+ productId={dialogState.productId}
191
+ onSuccess={handleAddRemoveSuccess}
192
+ />
193
+ )}
98
194
 
99
- {resultList && resultList?.length > 0 && resultsOpen ? (
100
- <SearchResult results={resultList} />
101
- ) : null}
102
- </Box>
195
+ {dialogState.type === DialogType.QuickView &&
196
+ dialogState.productId &&
197
+ dialogState.productInfo && (
198
+ <ProductViewDialog
199
+ openDialog={dialogState.type === DialogType.QuickView}
200
+ handleCloseDialog={handleCloseDialog}
201
+ product={dialogState.productInfo}
202
+ cartId={cart.Id}
203
+ />
204
+ )}
205
+ </>
103
206
  );
104
207
  }
@@ -19,6 +19,8 @@ export const SearchResultCard = styled(Card)({
19
19
  position: "absolute",
20
20
  paddingTop: "0.5rem",
21
21
  paddingBottom: "0.5rem",
22
+ paddingLeft: "2rem",
23
+ paddingRight: "2rem",
22
24
  });
23
25
 
24
26
  export const DropDownHandler = styled(Box)(({ theme }) => ({
@@ -8,6 +8,7 @@ interface Props extends BoxProps {
8
8
  title?: string;
9
9
  icon?: ReactNode;
10
10
  seeMoreLink?: string;
11
+ children: ReactNode;
11
12
  }
12
13
  // ==============================================================
13
14
 
@@ -0,0 +1,161 @@
1
+ import React, { Fragment } from "react";
2
+ import isFunction from "lodash/isFunction";
3
+ import { useTranslations } from "next-intl";
4
+ import { Grid, Button, Dialog, DialogContent } from "@mui/material";
5
+ import { MdFavorite } from "react-icons/md";
6
+ // Global Custom components
7
+ import DashboardHeader from "./components/dashboard-header";
8
+ import CreateWishlistButton from "./components/create-wishlist-button";
9
+ import WishlistModalItem from "./components/wishlist-modal-item";
10
+ import NoRecords from "./components/no-records";
11
+ // API
12
+ import {
13
+ CopyCartToWishlistInput,
14
+ Wishlist,
15
+ WishlistLinesInput,
16
+ } from "@evenicanpm/storefront-core/src/api-manager/schemas/user.schema";
17
+ import { Cart } from "@evenicanpm/storefront-core/src/api-manager/schemas/cart.schema";
18
+ import useAddToWishlist from "@/api-manager/services/user/mutations/add-to-wishlist";
19
+ import { useNotification } from "@evenicanpm/storefront-core/src/components/Notifications/use-notification";
20
+ import useCopyCartToWishlist from "@/api-manager/services/user/mutations/copy-cart-to-wishlist";
21
+ import { useSession } from "next-auth/react";
22
+ import getWishlists from "@/api-manager/services/user/queries/get-wishlists";
23
+
24
+ interface Props {
25
+ open: boolean;
26
+ handleClose: () => void;
27
+ productId?: number;
28
+ cart?: Cart;
29
+ onSuccess?: () => void;
30
+ }
31
+
32
+ export default function AddToWishlistDialog(props: Props) {
33
+ const { data: wishlists, isLoading } = getWishlists.useData();
34
+
35
+ const t = useTranslations("Account.Wishlists");
36
+ const { setNotification } = useNotification();
37
+
38
+ const { mutateAsync: addToWishlist } = useAddToWishlist();
39
+ const { mutateAsync: copyCartToWishlist } = useCopyCartToWishlist();
40
+
41
+ const { data: session } = useSession();
42
+ const isAuthenticated = !!session;
43
+
44
+ const handleClose = () => {
45
+ if (isFunction(props.handleClose)) {
46
+ props.handleClose();
47
+ }
48
+ };
49
+
50
+ const handleAddToWishlist = async (wishlistId: string) => {
51
+ if (props.productId) {
52
+ try {
53
+ const wishlistLinesInput: WishlistLinesInput = {
54
+ Id: wishlistId,
55
+ ProductListLines: [],
56
+ };
57
+
58
+ wishlistLinesInput.ProductListLines.push({
59
+ ProductListId: wishlistId,
60
+ ProductId: props.productId,
61
+ Quantity: 1,
62
+ UnitOfMeasure: "ea",
63
+ });
64
+ await addToWishlist(wishlistLinesInput);
65
+ setNotification({
66
+ message: t("wishlistLineAddSuccess"),
67
+ severity: "success",
68
+ });
69
+ if (isFunction(props.onSuccess)) {
70
+ props.onSuccess();
71
+ }
72
+ } catch (error) {
73
+ setNotification({
74
+ message: t("wishlistLineAddFailed"),
75
+ severity: "error",
76
+ });
77
+ }
78
+ } else if (props.cart) {
79
+ try {
80
+ const copyCartToWishlistInput: CopyCartToWishlistInput = {
81
+ Id: wishlistId,
82
+ CartID: props.cart.Id,
83
+ IsRewrite: false,
84
+ IsQuantityAggregate: true,
85
+ };
86
+
87
+ await copyCartToWishlist(copyCartToWishlistInput);
88
+ setNotification({
89
+ message: t("wishlistCartCopySuccess"),
90
+ severity: "success",
91
+ });
92
+ } catch (error) {
93
+ setNotification({
94
+ message: t("wishlistCartCopyFailed"),
95
+ severity: "error",
96
+ });
97
+ }
98
+ }
99
+ };
100
+
101
+ return (
102
+ <Dialog
103
+ open={props.open}
104
+ onClose={handleClose}
105
+ aria-labelledby="form-dialog-title"
106
+ >
107
+ <DialogContent>
108
+ <Fragment>
109
+ <DashboardHeader
110
+ title="Account.Wishlists.heading"
111
+ Icon={MdFavorite}
112
+ href=""
113
+ buttonText=""
114
+ buttons={
115
+ isAuthenticated && (
116
+ <CreateWishlistButton path="Account.Wishlists.btnCreateNewList" />
117
+ )
118
+ }
119
+ />
120
+ {isAuthenticated && !isLoading ? (
121
+ wishlists && wishlists.length > 0 ? (
122
+ wishlists?.map((wishlist: Wishlist) => (
123
+ <WishlistModalItem
124
+ key={wishlist.Id}
125
+ wishlist={wishlist}
126
+ addToWishlist={handleAddToWishlist}
127
+ />
128
+ ))
129
+ ) : (
130
+ <NoRecords message="Account.Wishlists.noWishlists" />
131
+ )
132
+ ) : (
133
+ <NoRecords message="Account.Wishlists.wishlistAddUnauthenticated" />
134
+ )}
135
+ </Fragment>
136
+ <Grid container spacing={3}>
137
+ <Grid
138
+ item
139
+ sm={12}
140
+ xs={12}
141
+ sx={{
142
+ display: "flex",
143
+ justifyContent: "flex-start",
144
+ gap: 2,
145
+ }}
146
+ >
147
+ <Button
148
+ color="primary"
149
+ variant="outlined"
150
+ size="small"
151
+ onClick={handleClose}
152
+ sx={{ height: 30.75 }}
153
+ >
154
+ {t("btnCancel")}
155
+ </Button>
156
+ </Grid>
157
+ </Grid>
158
+ </DialogContent>
159
+ </Dialog>
160
+ );
161
+ }
@@ -0,0 +1,167 @@
1
+ import React, { useEffect } from "react";
2
+ import isFunction from "lodash/isFunction";
3
+ import { useTranslations } from "next-intl";
4
+ import {
5
+ Box,
6
+ Button,
7
+ TextField,
8
+ Dialog,
9
+ DialogContent,
10
+ FormControlLabel,
11
+ Checkbox,
12
+ } from "@mui/material";
13
+ import Grid from "@mui/material/Grid2";
14
+ // Global Custom components
15
+ import { H5 } from "@evenicanpm/storefront-core/src/components/_components/Typography";
16
+ import { useNotification } from "@evenicanpm/storefront-core/src/components/Notifications/use-notification";
17
+ // Forms
18
+ import { useFormik } from "formik";
19
+ import { z } from "zod";
20
+ import { withZodSchema } from "formik-validator-zod";
21
+ // API
22
+ import useCreateWishlist from "@evenicanpm/storefront-core/src/api-manager/services/user/mutations/create-wishlist";
23
+
24
+ interface Props {
25
+ open: boolean;
26
+ handleClose: () => void;
27
+ }
28
+
29
+ export default function CreateNewList(props: Props) {
30
+ const t = useTranslations("Account.Wishlists");
31
+ const { setNotification } = useNotification();
32
+
33
+ const { mutateAsync: createWishlist } = useCreateWishlist();
34
+
35
+ const FormSchema = z.object({
36
+ Id: z.string(),
37
+ Name: z.string().nonempty(t("Validation.required", { field: t("name") })),
38
+ Comment: z.string().optional(),
39
+ IsPublic: z.boolean().optional(),
40
+ });
41
+ type FormSchemaType = z.infer<typeof FormSchema>;
42
+
43
+ const handleSubmit = async (values: FormSchemaType) => {
44
+ try {
45
+ await createWishlist({ ...values, IsPublic: !values.IsPublic });
46
+ handleClose();
47
+ setNotification({
48
+ message: t("wishlistSuccess"),
49
+ severity: "success",
50
+ });
51
+ } catch (error) {
52
+ setNotification({
53
+ message: t("wishlistFailed"),
54
+ severity: "error",
55
+ });
56
+ }
57
+ };
58
+
59
+ const formik = useFormik<FormSchemaType>({
60
+ initialValues: {
61
+ Id: "",
62
+ Name: "",
63
+ Comment: "",
64
+ IsPublic: false,
65
+ },
66
+ onSubmit: handleSubmit,
67
+ validate: withZodSchema(FormSchema),
68
+ });
69
+
70
+ // destructure to put in dependency array
71
+ // of use effect instead of whole formik
72
+ const { resetForm } = formik;
73
+
74
+ useEffect(() => {
75
+ if (props.open) {
76
+ resetForm();
77
+ }
78
+ }, [props.open, resetForm]);
79
+
80
+ const handleClose = () => {
81
+ if (isFunction(props.handleClose)) {
82
+ props.handleClose();
83
+ }
84
+ };
85
+
86
+ return (
87
+ <Dialog
88
+ open={props.open}
89
+ onClose={handleClose}
90
+ aria-labelledby="form-dialog-title"
91
+ >
92
+ <DialogContent>
93
+ <H5 mb={4}>{t("formTitle")}</H5>
94
+ <Box component="form" onSubmit={formik.handleSubmit}>
95
+ <Grid container spacing={3}>
96
+ <Grid size={{ sm: 6, xs: 12 }}>
97
+ <TextField
98
+ name="Name"
99
+ fullWidth
100
+ label={t("name")}
101
+ value={formik.values.Name}
102
+ onChange={formik.handleChange}
103
+ onBlur={formik.handleBlur}
104
+ error={formik.touched.Name && Boolean(formik.errors.Name)}
105
+ helperText={formik.touched.Name && formik.errors.Name}
106
+ required
107
+ />
108
+ </Grid>
109
+ <Grid size={{ sm: 6, xs: 12 }}>
110
+ <TextField
111
+ name="Comment"
112
+ fullWidth
113
+ label={t("comment")}
114
+ value={formik.values.Comment}
115
+ onChange={formik.handleChange}
116
+ onBlur={formik.handleBlur}
117
+ error={formik.touched.Comment && Boolean(formik.errors.Comment)}
118
+ helperText={formik.touched.Comment && formik.errors.Comment}
119
+ />
120
+ </Grid>
121
+ <Grid size={{ sm: 6, xs: 12 }}>
122
+ <FormControlLabel
123
+ control={
124
+ <Checkbox
125
+ name="IsPublic"
126
+ checked={formik.values.IsPublic}
127
+ onChange={formik.handleChange}
128
+ onBlur={formik.handleBlur}
129
+ />
130
+ }
131
+ label={t("private")}
132
+ />
133
+ </Grid>
134
+ <Grid
135
+ size={{ sm: 6, xs: 12 }}
136
+ sx={{
137
+ display: "flex",
138
+ justifyContent: "flex-end",
139
+ alignItems: "center",
140
+ gap: 2,
141
+ }}
142
+ >
143
+ <Button
144
+ color="primary"
145
+ variant="contained"
146
+ size="small"
147
+ type="submit"
148
+ sx={{ height: 30.75 }}
149
+ >
150
+ {t("btnSave")}
151
+ </Button>
152
+ <Button
153
+ color="primary"
154
+ variant="outlined"
155
+ size="small"
156
+ onClick={handleClose}
157
+ sx={{ height: 30.75 }}
158
+ >
159
+ {t("btnCancel")}
160
+ </Button>
161
+ </Grid>
162
+ </Grid>
163
+ </Box>
164
+ </DialogContent>
165
+ </Dialog>
166
+ );
167
+ }
@@ -0,0 +1,40 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { Button } from "@mui/material";
5
+ import T from "@evenicanpm/storefront-core/src/components/T";
6
+ import CreateNewListDialog from "./create-new-list";
7
+
8
+ interface Props {
9
+ path: string;
10
+ }
11
+
12
+ const CreateWishlistButton = ({ path }: Props) => {
13
+ const [openCreateListDialog, setOpenCreateListDialog] = useState(false);
14
+
15
+ const handleCloseDialog = () => {
16
+ setOpenCreateListDialog(false);
17
+ };
18
+
19
+ const handleCreateNewList = () => {
20
+ setOpenCreateListDialog(true);
21
+ };
22
+
23
+ return (
24
+ <>
25
+ <Button
26
+ onClick={handleCreateNewList}
27
+ color="primary"
28
+ sx={{ bgcolor: "primary.light", px: 4 }}
29
+ >
30
+ <T path={path} />
31
+ </Button>
32
+ <CreateNewListDialog
33
+ open={openCreateListDialog}
34
+ handleClose={handleCloseDialog}
35
+ />
36
+ </>
37
+ );
38
+ };
39
+
40
+ export default CreateWishlistButton;