@shopify/create-hydrogen 0.1.2 → 0.3.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.
- package/README.md +3 -0
- package/index.js +4 -0
- package/package.json +2 -2
- package/template-hydrogen/package.json +3 -2
- package/template-hydrogen/src/components/Cart.client.jsx +84 -76
- package/template-hydrogen/src/components/CartProvider.client.jsx +29 -3
- package/template-hydrogen/src/components/CartUIProvider.client.jsx +42 -0
- package/template-hydrogen/src/components/Gallery.client.jsx +1 -1
- package/template-hydrogen/src/components/Header.client.jsx +62 -5
- package/template-hydrogen/src/components/{HightlightedProduct.client.jsx → HighlightedProduct.client.jsx} +0 -0
- package/template-hydrogen/src/components/Layout.client.jsx +2 -22
- package/template-hydrogen/src/components/NotFound.server.jsx +2 -2
- package/template-hydrogen/src/components/ProductCard.client.jsx +3 -3
- package/template-hydrogen/src/components/ProductDetails.client.jsx +7 -10
- package/template-hydrogen/src/pages/Index.server.jsx +3 -1
- package/template-hydrogen/src/pages/collections/[handle].server.jsx +2 -2
- package/template-hydrogen/src/pages/products/[handle].server.jsx +8 -1
- package/template-hydrogen/src/pages/search.server.jsx +2 -2
package/README.md
ADDED
package/index.js
CHANGED
|
@@ -18,6 +18,10 @@ const renameFiles = {
|
|
|
18
18
|
_gitignore: '.gitignore',
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
console.warn(
|
|
22
|
+
'DEPRECATED: Please use `npm init hydrogen-app@latest` or `yarn create hydrogen-app` instead.'
|
|
23
|
+
);
|
|
24
|
+
|
|
21
25
|
async function init() {
|
|
22
26
|
let targetDir = argv._[0];
|
|
23
27
|
if (!targetDir) {
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.3.0",
|
|
8
8
|
"main": "index.js",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"bin": {
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"kolorist": "^1.4.0",
|
|
25
25
|
"minimist": "^1.2.5"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "79eec7e076abe074755bbe42bc62f7f96dcd2ff8"
|
|
28
28
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dev",
|
|
3
3
|
"description": "This is a dev environment for Hydrogen",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": true,
|
|
7
7
|
"scripts": {
|
|
@@ -31,9 +31,10 @@
|
|
|
31
31
|
"vite": "^2.6.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@shopify/hydrogen": "^0.
|
|
34
|
+
"@shopify/hydrogen": "^0.3.0",
|
|
35
35
|
"compression": "^1.7.4",
|
|
36
36
|
"express": "^4.17.1",
|
|
37
|
+
"focus-trap-react": "^8.8.1",
|
|
37
38
|
"graphql-tag": "^2.12.4",
|
|
38
39
|
"react": "18.0.0-alpha-e6be2d531",
|
|
39
40
|
"react-dom": "18.0.0-alpha-e6be2d531",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import FocusTrap from 'focus-trap-react';
|
|
1
2
|
import {
|
|
2
3
|
useCart,
|
|
3
4
|
useCartLinesTotalQuantity,
|
|
4
|
-
CartToggle,
|
|
5
5
|
CartCheckoutButton,
|
|
6
6
|
Link,
|
|
7
7
|
CartLines,
|
|
@@ -10,94 +10,75 @@ import {
|
|
|
10
10
|
CartEstimatedCost,
|
|
11
11
|
} from '@shopify/hydrogen/client';
|
|
12
12
|
|
|
13
|
+
import {useCartUI} from './CartUIProvider.client';
|
|
14
|
+
|
|
13
15
|
export default function Cart() {
|
|
16
|
+
const {isCartOpen} = useCartUI();
|
|
14
17
|
const itemCount = useCartLinesTotalQuantity();
|
|
15
18
|
const {error} = useCart();
|
|
16
19
|
|
|
17
20
|
return (
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
<FocusTrap active={isCartOpen} focusTrapOptions={{allowOutsideClick: true}}>
|
|
22
|
+
<aside
|
|
23
|
+
className={`pointer-events-none z-50 fixed right-0 top-0 bottom-0 md:p-5 flex flex-col w-full max-w-md min-w-sm transition-transform duration-500 transform-gpu ${
|
|
24
|
+
isCartOpen ? 'right-0' : 'translate-x-full'
|
|
25
|
+
}`}
|
|
26
|
+
id="cart"
|
|
27
|
+
tabIndex={-1}
|
|
28
|
+
aria-hidden={!isCartOpen}
|
|
29
|
+
aria-label="Cart"
|
|
30
|
+
>
|
|
31
|
+
<div className="overflow-hidden md:h-auto pointer-events-auto">
|
|
32
|
+
<div className="flex flex-col shadow-xl max-h-full">
|
|
33
|
+
<header className="bg-white px-4 md:px-8 md:h-20 border-b border-gray-300 border-solid rounded-t-md flex flex-shrink-0 items-center justify-between">
|
|
34
|
+
<CartHeader />
|
|
35
|
+
</header>
|
|
23
36
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
<div className="bg-white px-4 md:px-8 overflow-y-scroll md:max-h-96">
|
|
38
|
+
{itemCount > 0 ? (
|
|
39
|
+
<CartLineItems />
|
|
40
|
+
) : (
|
|
41
|
+
<p className="text-center text-gray-600 my-8">
|
|
42
|
+
Your cart is empty
|
|
43
|
+
</p>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
31
46
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
{error ? (
|
|
48
|
+
<div
|
|
49
|
+
className="border bg-red-200 border-red-400 text-red-800 mb-4 mx-8 px-4 py-3 rounded relative"
|
|
50
|
+
role="alert"
|
|
51
|
+
>
|
|
52
|
+
{error}
|
|
53
|
+
</div>
|
|
54
|
+
) : null}
|
|
40
55
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
<footer
|
|
57
|
+
className={`${
|
|
58
|
+
itemCount > 0 ? 'border-t border-solid border-gray-300' : ''
|
|
59
|
+
} bg-white p-4 md:p-8 space-y-4 flex-shrink-0 rounded-b-md`}
|
|
60
|
+
>
|
|
61
|
+
{itemCount > 0 ? <CartFooter /> : null}
|
|
62
|
+
</footer>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</aside>
|
|
66
|
+
</FocusTrap>
|
|
50
67
|
);
|
|
51
68
|
}
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
function CartHeader() {
|
|
71
|
+
const {isCartOpen, toggleCart} = useCartUI();
|
|
54
72
|
const itemCount = useCartLinesTotalQuantity();
|
|
55
73
|
|
|
56
|
-
return (
|
|
57
|
-
<div className="relative">
|
|
58
|
-
<svg
|
|
59
|
-
width="19"
|
|
60
|
-
height="24"
|
|
61
|
-
viewBox="0 0 19 24"
|
|
62
|
-
fill="none"
|
|
63
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
64
|
-
>
|
|
65
|
-
<path
|
|
66
|
-
d="M15.5894 7H3.41063C2.89451 7 2.46318 7.39279 2.415 7.90666L1.205 20.8133C1.09502 21.9865 2.01796 23 3.19627 23H15.8037C16.982 23 17.905 21.9865 17.795 20.8133L16.585 7.90666C16.5368 7.39279 16.1055 7 15.5894 7Z"
|
|
67
|
-
stroke="#1F2937"
|
|
68
|
-
strokeWidth="2"
|
|
69
|
-
strokeMiterlimit="10"
|
|
70
|
-
strokeLinecap="round"
|
|
71
|
-
/>
|
|
72
|
-
<path
|
|
73
|
-
d="M6 7V9.98952C6 12.0075 7.63589 13.6434 9.65386 13.6434V13.6434C11.6718 13.6434 13.3077 12.0075 13.3077 9.98952V7"
|
|
74
|
-
stroke="#1F2937"
|
|
75
|
-
strokeWidth="2"
|
|
76
|
-
/>
|
|
77
|
-
<path
|
|
78
|
-
d="M13 6L13 4.5C13 2.567 11.433 1 9.5 1V1C7.567 1 6 2.567 6 4.5L6 6"
|
|
79
|
-
stroke="#1F2937"
|
|
80
|
-
strokeWidth="2"
|
|
81
|
-
className={`${itemCount > 0 ? 'block' : 'hidden'}`}
|
|
82
|
-
/>
|
|
83
|
-
</svg>
|
|
84
|
-
|
|
85
|
-
<div
|
|
86
|
-
className={`bg-blue-600 text-xs rounded-full leading-none text-white absolute bottom-0 right-0 flex items-center justify-center transform translate-y-1/2 transition-all ${
|
|
87
|
-
itemCount > 0 ? 'h-4 w-4' : 'h-0 w-0 overflow-hidden'
|
|
88
|
-
}`}
|
|
89
|
-
>
|
|
90
|
-
{itemCount > 0 ? itemCount : null}
|
|
91
|
-
</div>
|
|
92
|
-
<span className="sr-only">Cart, {itemCount} items</span>
|
|
93
|
-
</div>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function CartHeader() {
|
|
98
74
|
return (
|
|
99
75
|
<>
|
|
100
|
-
<
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
aria-expanded={isCartOpen}
|
|
79
|
+
aria-controls="cart"
|
|
80
|
+
onClick={toggleCart}
|
|
81
|
+
>
|
|
101
82
|
<div>
|
|
102
83
|
<svg
|
|
103
84
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -113,9 +94,36 @@ function CartHeader() {
|
|
|
113
94
|
</svg>
|
|
114
95
|
</div>
|
|
115
96
|
<span className="sr-only">Close cart</span>
|
|
116
|
-
</
|
|
97
|
+
</button>
|
|
117
98
|
<div className="h-12 w-12 p-2 md:h-7 md:w-7 md:p-0">
|
|
118
|
-
<
|
|
99
|
+
<div className="relative">
|
|
100
|
+
<svg
|
|
101
|
+
width="19"
|
|
102
|
+
height="24"
|
|
103
|
+
viewBox="0 0 19 24"
|
|
104
|
+
fill="none"
|
|
105
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
106
|
+
>
|
|
107
|
+
<path
|
|
108
|
+
d="M15.5894 7H3.41063C2.89451 7 2.46318 7.39279 2.415 7.90666L1.205 20.8133C1.09502 21.9865 2.01796 23 3.19627 23H15.8037C16.982 23 17.905 21.9865 17.795 20.8133L16.585 7.90666C16.5368 7.39279 16.1055 7 15.5894 7Z"
|
|
109
|
+
stroke="#1F2937"
|
|
110
|
+
strokeWidth="2"
|
|
111
|
+
strokeMiterlimit="10"
|
|
112
|
+
strokeLinecap="round"
|
|
113
|
+
/>
|
|
114
|
+
<path
|
|
115
|
+
d="M6 7V9.98952C6 12.0075 7.63589 13.6434 9.65386 13.6434V13.6434C11.6718 13.6434 13.3077 12.0075 13.3077 9.98952V7"
|
|
116
|
+
stroke="#1F2937"
|
|
117
|
+
strokeWidth="2"
|
|
118
|
+
/>
|
|
119
|
+
<path
|
|
120
|
+
d="M13 6L13 4.5C13 2.567 11.433 1 9.5 1V1C7.567 1 6 2.567 6 4.5L6 6"
|
|
121
|
+
stroke="#1F2937"
|
|
122
|
+
strokeWidth="2"
|
|
123
|
+
className={`${itemCount > 0 ? 'block' : 'hidden'}`}
|
|
124
|
+
/>
|
|
125
|
+
</svg>
|
|
126
|
+
</div>
|
|
119
127
|
</div>
|
|
120
128
|
</>
|
|
121
129
|
);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import {useCallback} from 'react';
|
|
1
2
|
import {CartProvider as ShopifyCartProvider} from '@shopify/hydrogen/client';
|
|
2
3
|
|
|
4
|
+
import CartUIProvider, {useCartUI} from './CartUIProvider.client';
|
|
5
|
+
|
|
3
6
|
/**
|
|
4
7
|
* TODO: Remove this re-export once we find a long-term solution for
|
|
5
8
|
* mixed Hydrogen Client Components.
|
|
@@ -8,8 +11,31 @@ import {CartProvider as ShopifyCartProvider} from '@shopify/hydrogen/client';
|
|
|
8
11
|
|
|
9
12
|
export default function CartProvider({children, cart, numCartLines}) {
|
|
10
13
|
return (
|
|
11
|
-
<
|
|
12
|
-
{
|
|
13
|
-
|
|
14
|
+
<CartUIProvider>
|
|
15
|
+
<Provider cart={cart} numCartLines={numCartLines}>
|
|
16
|
+
{children}
|
|
17
|
+
</Provider>
|
|
18
|
+
</CartUIProvider>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function Provider({children, cart, numCartLines}) {
|
|
23
|
+
const {openCart} = useCartUI();
|
|
24
|
+
|
|
25
|
+
const open = useCallback(() => {
|
|
26
|
+
openCart();
|
|
27
|
+
}, [openCart]);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<>
|
|
31
|
+
<ShopifyCartProvider
|
|
32
|
+
cart={cart}
|
|
33
|
+
numCartLines={numCartLines}
|
|
34
|
+
onLineAdd={open}
|
|
35
|
+
onCreate={open}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
</ShopifyCartProvider>
|
|
39
|
+
</>
|
|
14
40
|
);
|
|
15
41
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useState,
|
|
3
|
+
useMemo,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
createContext,
|
|
7
|
+
} from 'react';
|
|
8
|
+
|
|
9
|
+
export const CartContext = createContext(null);
|
|
10
|
+
|
|
11
|
+
export default function CartUIProvider({children}) {
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
|
|
14
|
+
const openCart = useCallback(() => {
|
|
15
|
+
setOpen(true);
|
|
16
|
+
}, [setOpen]);
|
|
17
|
+
|
|
18
|
+
const closeCart = useCallback(() => {
|
|
19
|
+
setOpen(false);
|
|
20
|
+
}, [setOpen]);
|
|
21
|
+
|
|
22
|
+
const toggleCart = useCallback(() => {
|
|
23
|
+
setOpen(!open);
|
|
24
|
+
}, [setOpen, open]);
|
|
25
|
+
|
|
26
|
+
const contextValue = useMemo(() => {
|
|
27
|
+
return {
|
|
28
|
+
isCartOpen: open,
|
|
29
|
+
openCart,
|
|
30
|
+
closeCart,
|
|
31
|
+
toggleCart,
|
|
32
|
+
};
|
|
33
|
+
}, [open, openCart, closeCart, toggleCart]);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<CartContext.Provider value={contextValue}>{children}</CartContext.Provider>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function useCartUI() {
|
|
41
|
+
return useContext(CartContext);
|
|
42
|
+
}
|
|
@@ -19,7 +19,7 @@ function GalleryPreview() {
|
|
|
19
19
|
<ul className="grid lg:grid-cols-2 gap-10">
|
|
20
20
|
{media.map((med) => {
|
|
21
21
|
return (
|
|
22
|
-
<li key={med.id} className="relative">
|
|
22
|
+
<li key={med.id || med.image.id} className="relative">
|
|
23
23
|
<MediaFile
|
|
24
24
|
className="w-full bg-white rounded-md object-cover"
|
|
25
25
|
media={med}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {Link,
|
|
1
|
+
import {Link, useCartLinesTotalQuantity} from '@shopify/hydrogen/client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {useCartUI} from './CartUIProvider.client';
|
|
4
4
|
|
|
5
5
|
export default function Header() {
|
|
6
6
|
return (
|
|
@@ -38,9 +38,66 @@ export default function Header() {
|
|
|
38
38
|
>
|
|
39
39
|
My Shop
|
|
40
40
|
</Link>
|
|
41
|
-
<CartToggle
|
|
42
|
-
<CartIcon />
|
|
43
|
-
</CartToggle>
|
|
41
|
+
<CartToggle />
|
|
44
42
|
</header>
|
|
45
43
|
);
|
|
46
44
|
}
|
|
45
|
+
|
|
46
|
+
function CartToggle() {
|
|
47
|
+
const cartUI = useCartUI();
|
|
48
|
+
const itemCount = useCartLinesTotalQuantity();
|
|
49
|
+
|
|
50
|
+
if (cartUI == null) {
|
|
51
|
+
throw new Error('CartToggle must be a descendent of a CartUIProvider');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const {isCartOpen, toggleCart} = cartUI;
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<button
|
|
58
|
+
className="h-12 w-12 p-2 mr-2 md:mr-0 md:h-7 md:w-7 md:p-0"
|
|
59
|
+
type="button"
|
|
60
|
+
aria-expanded={isCartOpen}
|
|
61
|
+
aria-controls="cart"
|
|
62
|
+
onClick={toggleCart}
|
|
63
|
+
>
|
|
64
|
+
<div className="relative">
|
|
65
|
+
<svg
|
|
66
|
+
width="19"
|
|
67
|
+
height="24"
|
|
68
|
+
viewBox="0 0 19 24"
|
|
69
|
+
fill="none"
|
|
70
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
71
|
+
>
|
|
72
|
+
<path
|
|
73
|
+
d="M15.5894 7H3.41063C2.89451 7 2.46318 7.39279 2.415 7.90666L1.205 20.8133C1.09502 21.9865 2.01796 23 3.19627 23H15.8037C16.982 23 17.905 21.9865 17.795 20.8133L16.585 7.90666C16.5368 7.39279 16.1055 7 15.5894 7Z"
|
|
74
|
+
stroke="#1F2937"
|
|
75
|
+
strokeWidth="2"
|
|
76
|
+
strokeMiterlimit="10"
|
|
77
|
+
strokeLinecap="round"
|
|
78
|
+
/>
|
|
79
|
+
<path
|
|
80
|
+
d="M6 7V9.98952C6 12.0075 7.63589 13.6434 9.65386 13.6434V13.6434C11.6718 13.6434 13.3077 12.0075 13.3077 9.98952V7"
|
|
81
|
+
stroke="#1F2937"
|
|
82
|
+
strokeWidth="2"
|
|
83
|
+
/>
|
|
84
|
+
<path
|
|
85
|
+
d="M13 6L13 4.5C13 2.567 11.433 1 9.5 1V1C7.567 1 6 2.567 6 4.5L6 6"
|
|
86
|
+
stroke="#1F2937"
|
|
87
|
+
strokeWidth="2"
|
|
88
|
+
className={`${itemCount > 0 ? 'block' : 'hidden'}`}
|
|
89
|
+
/>
|
|
90
|
+
</svg>
|
|
91
|
+
|
|
92
|
+
<div
|
|
93
|
+
className={`bg-blue-600 text-xs rounded-full leading-none text-white absolute bottom-0 right-0 flex items-center justify-center transform translate-y-1/2 transition-all ${
|
|
94
|
+
itemCount > 0 ? 'h-4 w-4' : 'h-0 w-0 overflow-hidden'
|
|
95
|
+
}`}
|
|
96
|
+
>
|
|
97
|
+
{itemCount > 0 ? itemCount : null}
|
|
98
|
+
</div>
|
|
99
|
+
<span className="sr-only">Cart, {itemCount} items</span>
|
|
100
|
+
</div>
|
|
101
|
+
</button>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
File without changes
|
|
@@ -1,22 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CartUIProvider,
|
|
3
|
-
CartContainer,
|
|
4
|
-
useCartUI,
|
|
5
|
-
} from '@shopify/hydrogen/client';
|
|
6
|
-
|
|
7
1
|
import Header from './Header.client';
|
|
8
2
|
import Footer from './Footer';
|
|
3
|
+
import {useCartUI} from './CartUIProvider.client';
|
|
9
4
|
import Cart from './Cart.client';
|
|
10
5
|
|
|
11
6
|
export default function Layout({children}) {
|
|
12
|
-
return (
|
|
13
|
-
<CartUIProvider>
|
|
14
|
-
<InnerLayout>{children}</InnerLayout>
|
|
15
|
-
</CartUIProvider>
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function InnerLayout({children}) {
|
|
20
7
|
const {isCartOpen, closeCart} = useCartUI();
|
|
21
8
|
|
|
22
9
|
return (
|
|
@@ -39,14 +26,7 @@ function InnerLayout({children}) {
|
|
|
39
26
|
}`}
|
|
40
27
|
onClick={isCartOpen ? closeCart : null}
|
|
41
28
|
/>
|
|
42
|
-
<
|
|
43
|
-
id="cart"
|
|
44
|
-
className={`pointer-events-none z-50 fixed right-0 top-0 bottom-0 md:p-5 flex flex-col w-full max-w-md min-w-sm transition-transform duration-500 transform-gpu ${
|
|
45
|
-
isCartOpen ? 'right-0' : 'translate-x-full'
|
|
46
|
-
}`}
|
|
47
|
-
>
|
|
48
|
-
<Cart />
|
|
49
|
-
</CartContainer>
|
|
29
|
+
<Cart />
|
|
50
30
|
</div>
|
|
51
31
|
<main
|
|
52
32
|
id="mainContent"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {useShopQuery,
|
|
1
|
+
import {useShopQuery, MediaFileFragment} from '@shopify/hydrogen';
|
|
2
2
|
import {Link} from '@shopify/hydrogen/client';
|
|
3
3
|
import gql from 'graphql-tag';
|
|
4
4
|
|
|
@@ -100,5 +100,5 @@ const QUERY = gql`
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
${
|
|
103
|
+
${MediaFileFragment}
|
|
104
104
|
`;
|
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
} from '@shopify/hydrogen/client';
|
|
8
8
|
|
|
9
9
|
export default function ProductCard({product}) {
|
|
10
|
-
const firstVariant = product?.variants?.edges[0]?.node;
|
|
11
|
-
|
|
12
10
|
if (!product) return null;
|
|
13
11
|
|
|
12
|
+
const firstVariant = product.variants?.edges[0]?.node;
|
|
13
|
+
|
|
14
14
|
return (
|
|
15
15
|
<ProductProvider product={product} initialVariantId={firstVariant.id}>
|
|
16
16
|
<Link to={`/products/${product.handle}`}>
|
|
17
|
-
<SelectedVariantImage className="rounded-md bg-gray-100 h-80 w-96 mb-2" />
|
|
17
|
+
<SelectedVariantImage className="rounded-md bg-gray-100 h-80 w-96 mb-2 object-cover" />
|
|
18
18
|
<ProductTitle className="text-gray-900 font-medium" />
|
|
19
19
|
</Link>
|
|
20
20
|
<div className="flex items-center">
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import {Product} from '@shopify/hydrogen/client';
|
|
1
|
+
import {Product, flattenConnection} from '@shopify/hydrogen/client';
|
|
2
2
|
|
|
3
|
-
import Layout from './Layout.client';
|
|
4
3
|
import ProductOptions from './ProductOptions.client';
|
|
5
4
|
import Gallery from './Gallery.client';
|
|
6
5
|
import Seo from './Seo.client';
|
|
7
6
|
|
|
8
|
-
export default function ProductDetails({
|
|
7
|
+
export default function ProductDetails({product}) {
|
|
8
|
+
const initialVariant = flattenConnection(product.variants)[0];
|
|
9
9
|
return (
|
|
10
|
-
|
|
11
|
-
<Seo product={
|
|
12
|
-
<Product
|
|
13
|
-
product={data.product}
|
|
14
|
-
initialVariantId={data.product.variants.edges[0].node.id}
|
|
15
|
-
>
|
|
10
|
+
<>
|
|
11
|
+
<Seo product={product} />
|
|
12
|
+
<Product product={product} initialVariantId={initialVariant.id}>
|
|
16
13
|
<div className="py-4 md:grid md:grid-cols-2 lg:grid-cols-3 gap-12">
|
|
17
14
|
<div className="md:hidden pb-4 flex justify-between items-top">
|
|
18
15
|
<Product.Title as="h1" className="font-bold text-2xl" />
|
|
@@ -179,6 +176,6 @@ export default function ProductDetails({data}) {
|
|
|
179
176
|
</section>
|
|
180
177
|
</div>
|
|
181
178
|
</Product>
|
|
182
|
-
|
|
179
|
+
</>
|
|
183
180
|
);
|
|
184
181
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from '@shopify/hydrogen';
|
|
6
6
|
import gql from 'graphql-tag';
|
|
7
7
|
|
|
8
|
-
import HighlightedProduct from '../components/
|
|
8
|
+
import HighlightedProduct from '../components/HighlightedProduct.client';
|
|
9
9
|
import Layout from '../components/Layout.client';
|
|
10
10
|
import ProductCard from '../components/ProductCard.client';
|
|
11
11
|
import MediaPlaceholder from '../components/MediaPlaceholder';
|
|
@@ -21,6 +21,7 @@ export default function Index() {
|
|
|
21
21
|
numProductVariantMetafields: 10,
|
|
22
22
|
numProductVariantSellingPlanAllocations: 10,
|
|
23
23
|
numProductSellingPlanGroups: 10,
|
|
24
|
+
numProductSellingPlans: 10,
|
|
24
25
|
},
|
|
25
26
|
});
|
|
26
27
|
|
|
@@ -183,6 +184,7 @@ const QUERY = gql`
|
|
|
183
184
|
$numProductVariantMetafields: Int!
|
|
184
185
|
$numProductVariantSellingPlanAllocations: Int!
|
|
185
186
|
$numProductSellingPlanGroups: Int!
|
|
187
|
+
$numProductSellingPlans: Int!
|
|
186
188
|
) {
|
|
187
189
|
products(first: $numProducts) {
|
|
188
190
|
edges {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {MediaFileFragment, useShopQuery} from '@shopify/hydrogen';
|
|
2
2
|
import {useParams} from 'react-router-dom';
|
|
3
3
|
import gql from 'graphql-tag';
|
|
4
4
|
|
|
@@ -65,5 +65,5 @@ const QUERY = gql`
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
${
|
|
68
|
+
${MediaFileFragment}
|
|
69
69
|
`;
|
|
@@ -4,6 +4,7 @@ import gql from 'graphql-tag';
|
|
|
4
4
|
|
|
5
5
|
import ProductDetails from '../../components/ProductDetails.client';
|
|
6
6
|
import NotFound from '../../components/NotFound.server';
|
|
7
|
+
import Layout from '../../components/Layout.client';
|
|
7
8
|
|
|
8
9
|
export default function Product() {
|
|
9
10
|
const {handle} = useParams();
|
|
@@ -18,6 +19,7 @@ export default function Product() {
|
|
|
18
19
|
numProductVariantMetafields: 10,
|
|
19
20
|
numProductVariantSellingPlanAllocations: 10,
|
|
20
21
|
numProductSellingPlanGroups: 10,
|
|
22
|
+
numProductSellingPlans: 10,
|
|
21
23
|
},
|
|
22
24
|
});
|
|
23
25
|
|
|
@@ -25,7 +27,11 @@ export default function Product() {
|
|
|
25
27
|
return <NotFound />;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
return
|
|
30
|
+
return (
|
|
31
|
+
<Layout>
|
|
32
|
+
<ProductDetails product={data.product} />
|
|
33
|
+
</Layout>
|
|
34
|
+
);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
const QUERY = gql`
|
|
@@ -37,6 +43,7 @@ const QUERY = gql`
|
|
|
37
43
|
$numProductVariantMetafields: Int!
|
|
38
44
|
$numProductVariantSellingPlanAllocations: Int!
|
|
39
45
|
$numProductSellingPlanGroups: Int!
|
|
46
|
+
$numProductSellingPlans: Int!
|
|
40
47
|
) {
|
|
41
48
|
product: product(handle: $handle) {
|
|
42
49
|
id
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {useEffect, useMemo, useState} from 'react';
|
|
2
2
|
import {useHistory, useLocation} from 'react-router-dom';
|
|
3
|
-
import {useShopQuery,
|
|
3
|
+
import {useShopQuery, MediaFileFragment} from '@shopify/hydrogen';
|
|
4
4
|
import gql from 'graphql-tag';
|
|
5
5
|
|
|
6
6
|
import Layout from '../components/Layout.client';
|
|
@@ -103,5 +103,5 @@ const QUERY = gql`
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
${
|
|
106
|
+
${MediaFileFragment}
|
|
107
107
|
`;
|