@shopify/create-hydrogen 0.2.1 → 0.18.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 (96) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/bin/run.cmd +3 -0
  3. package/bin/run.js +5 -0
  4. package/dist/commands/init.js +76397 -0
  5. package/dist/commands/init.js.map +1 -0
  6. package/dist/index.js +21 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +61 -14
  9. package/templates/template-hydrogen/.devcontainer/devcontainer.json +18 -0
  10. package/templates/template-hydrogen/.eslintrc.js +3 -0
  11. package/templates/template-hydrogen/.gitignore +7 -0
  12. package/templates/template-hydrogen/.stackblitzrc +4 -0
  13. package/{template-hydrogen → templates/template-hydrogen}/.stylelintrc.js +1 -1
  14. package/templates/template-hydrogen/.vscode/extensions.json +8 -0
  15. package/templates/template-hydrogen/Dockerfile +15 -0
  16. package/{template-hydrogen → templates/template-hydrogen}/README.md +11 -2
  17. package/{template-hydrogen → templates/template-hydrogen}/_gitignore +0 -0
  18. package/templates/template-hydrogen/index.html +20 -0
  19. package/{template-hydrogen → templates/template-hydrogen}/package.json +20 -16
  20. package/{template-hydrogen → templates/template-hydrogen}/postcss.config.js +0 -0
  21. package/{template-hydrogen/src → templates/template-hydrogen/public}/favicon.svg +0 -0
  22. package/{template-hydrogen → templates/template-hydrogen}/server.js +4 -2
  23. package/{template-hydrogen → templates/template-hydrogen}/shopify.config.js +1 -2
  24. package/templates/template-hydrogen/src/App.client.jsx +8 -0
  25. package/templates/template-hydrogen/src/App.server.jsx +27 -0
  26. package/templates/template-hydrogen/src/components/Button.client.jsx +65 -0
  27. package/templates/template-hydrogen/src/components/Cart.client.jsx +265 -0
  28. package/templates/template-hydrogen/src/components/CartIcon.jsx +33 -0
  29. package/templates/template-hydrogen/src/components/CartIconWithItems.client.jsx +28 -0
  30. package/templates/template-hydrogen/src/components/CartProvider.client.jsx +35 -0
  31. package/templates/template-hydrogen/src/components/CartToggle.client.jsx +30 -0
  32. package/{template-hydrogen → templates/template-hydrogen}/src/components/CartUIProvider.client.jsx +3 -0
  33. package/templates/template-hydrogen/src/components/CountrySelector.client.jsx +116 -0
  34. package/templates/template-hydrogen/src/components/DefaultSeo.server.jsx +35 -0
  35. package/templates/template-hydrogen/src/components/FeaturedCollection.jsx +26 -0
  36. package/templates/template-hydrogen/src/components/Footer.server.jsx +103 -0
  37. package/templates/template-hydrogen/src/components/Gallery.client.jsx +65 -0
  38. package/templates/template-hydrogen/src/components/Header.client.jsx +62 -0
  39. package/templates/template-hydrogen/src/components/Layout.server.jsx +87 -0
  40. package/templates/template-hydrogen/src/components/LoadMoreProducts.client.jsx +56 -0
  41. package/templates/template-hydrogen/src/components/LoadingFallback.jsx +26 -0
  42. package/templates/template-hydrogen/src/components/MobileCountrySelector.client.jsx +64 -0
  43. package/templates/template-hydrogen/src/components/MobileNavigation.client.jsx +98 -0
  44. package/templates/template-hydrogen/src/components/MoneyCompareAtPrice.client.jsx +14 -0
  45. package/templates/template-hydrogen/src/components/MoneyPrice.client.jsx +15 -0
  46. package/templates/template-hydrogen/src/components/Navigation.client.jsx +23 -0
  47. package/templates/template-hydrogen/src/components/NotFound.server.jsx +93 -0
  48. package/templates/template-hydrogen/src/components/OpenIcon.jsx +33 -0
  49. package/templates/template-hydrogen/src/components/ProductCard.jsx +50 -0
  50. package/templates/template-hydrogen/src/components/ProductDetails.client.jsx +242 -0
  51. package/{template-hydrogen → templates/template-hydrogen}/src/components/ProductOptions.client.jsx +7 -4
  52. package/templates/template-hydrogen/src/components/Welcome.server.jsx +188 -0
  53. package/templates/template-hydrogen/src/entry-client.jsx +7 -0
  54. package/templates/template-hydrogen/src/entry-server.jsx +6 -0
  55. package/{template-hydrogen → templates/template-hydrogen}/src/index.css +31 -0
  56. package/templates/template-hydrogen/src/pages/collections/[handle].server.jsx +105 -0
  57. package/templates/template-hydrogen/src/pages/index.server.jsx +237 -0
  58. package/{template-hydrogen → templates/template-hydrogen}/src/pages/pages/[handle].server.jsx +14 -5
  59. package/templates/template-hydrogen/src/pages/products/[handle].server.jsx +69 -0
  60. package/templates/template-hydrogen/src/pages/redirect.server.jsx +4 -0
  61. package/templates/template-hydrogen/src/pages/robots.txt.server.js +10 -0
  62. package/{template-hydrogen → templates/template-hydrogen}/src/pages/sitemap.xml.server.jsx +2 -2
  63. package/templates/template-hydrogen/tailwind.config.js +26 -0
  64. package/{template-hydrogen → templates/template-hydrogen}/vite.config.js +1 -0
  65. package/{template-hydrogen → templates/template-hydrogen}/worker.js +1 -0
  66. package/README.md +0 -3
  67. package/index.js +0 -205
  68. package/scripts/tmp-copy-template-from-dev.js +0 -21
  69. package/scripts/utils.js +0 -29
  70. package/template-hydrogen/.eslintrc.js +0 -41
  71. package/template-hydrogen/.vscode/extensions.json +0 -3
  72. package/template-hydrogen/Dockerfile +0 -15
  73. package/template-hydrogen/index.html +0 -14
  74. package/template-hydrogen/src/App.server.jsx +0 -42
  75. package/template-hydrogen/src/components/Cart.client.jsx +0 -296
  76. package/template-hydrogen/src/components/CartProvider.client.jsx +0 -40
  77. package/template-hydrogen/src/components/DefaultSeo.server.jsx +0 -22
  78. package/template-hydrogen/src/components/Footer.jsx +0 -12
  79. package/template-hydrogen/src/components/Gallery.client.jsx +0 -36
  80. package/template-hydrogen/src/components/Header.client.jsx +0 -103
  81. package/template-hydrogen/src/components/HightlightedProduct.client.jsx +0 -54
  82. package/template-hydrogen/src/components/Layout.client.jsx +0 -41
  83. package/template-hydrogen/src/components/MediaPlaceholder.jsx +0 -21
  84. package/template-hydrogen/src/components/NotFound.server.jsx +0 -104
  85. package/template-hydrogen/src/components/ProductCard.client.jsx +0 -39
  86. package/template-hydrogen/src/components/ProductDetails.client.jsx +0 -184
  87. package/template-hydrogen/src/components/Seo.client.jsx +0 -75
  88. package/template-hydrogen/src/entry-client.jsx +0 -12
  89. package/template-hydrogen/src/entry-server.jsx +0 -7
  90. package/template-hydrogen/src/pages/Index.server.jsx +0 -199
  91. package/template-hydrogen/src/pages/blogs/[handle]/[articleHandle].server.jsx +0 -49
  92. package/template-hydrogen/src/pages/blogs/[handle].server.jsx +0 -76
  93. package/template-hydrogen/src/pages/collections/[handle].server.jsx +0 -69
  94. package/template-hydrogen/src/pages/products/[handle].server.jsx +0 -62
  95. package/template-hydrogen/src/pages/search.server.jsx +0 -107
  96. package/template-hydrogen/tailwind.config.js +0 -9
@@ -1,75 +0,0 @@
1
- import {useShop, Helmet} from '@shopify/hydrogen/client';
2
-
3
- export default function Seo({shopName, product}) {
4
- const {locale} = useShop();
5
- const lang = locale.split(/[-_]/)[0];
6
-
7
- if (product) {
8
- const variant = product.variants.edges[0].node;
9
- const price = variant.priceV2;
10
- const image = product.images.edges[0]?.node;
11
- const title = product.seo?.title ?? product.title;
12
- const description = product.seo?.description ?? product.description;
13
-
14
- /* TODO: Find a way to get the full URL */
15
- const url = typeof window === 'undefined' ? '' : window.location.href;
16
-
17
- return (
18
- <Helmet>
19
- <title>{title}</title>
20
- <meta name="description" content={description} />
21
- {url && <meta property="og:url" content={url} />}
22
- <meta property="og:title" content={title} />
23
- <meta property="og:type" content="product" />
24
- <meta property="og:description" content={description} />
25
- <meta property="og:price:amount" content={price.amount} />
26
- <meta property="og:price:currency" content={price.currencyCode} />
27
-
28
- {image && <meta property="og:image" content={image.originalSrc} />}
29
- {image && (
30
- <meta property="og:image:secure_url" content={image.originalSrc} />
31
- )}
32
-
33
- <meta name="twitter:card" content="summary_large_image" />
34
- <meta name="twitter:title" content={title} />
35
- <meta name="twitter:description" content={description} />
36
-
37
- <script type="application/ld+json">{`
38
- {
39
- "@context": "https://schema.org/",
40
- "@type": "Product",
41
- "name": "${product.title}",
42
- "image": [
43
- ${image ? `"${image.originalSrc}"` : ''}
44
- ],
45
- "description": "${description}",
46
- "brand": {
47
- "@type": "Brand",
48
- "name": "${product.vendor}"
49
- },
50
- "offers": {
51
- "@type": "Offer",
52
- "url": "${url}",
53
- "priceCurrency": "${price.currencyCode}",
54
- "price": "${price.amount}",
55
- "availability": "https://schema.org/${
56
- variant.availableForSale ? 'InStock' : 'OutOfStock'
57
- }"
58
- }
59
- }
60
- `}</script>
61
- </Helmet>
62
- );
63
- }
64
-
65
- /**
66
- * Return a global SEO helper if no other props were passed.
67
- * Useful for placing in the "main" <App> container.
68
- */
69
- return (
70
- <Helmet defaultTitle={shopName} titleTemplate={`%s - ${shopName}`}>
71
- <html lang={lang} />
72
- <meta property="og:site_name" content={shopName} />
73
- </Helmet>
74
- );
75
- }
@@ -1,12 +0,0 @@
1
- import renderHydrogen from '@shopify/hydrogen/entry-client';
2
- import {ShopifyProvider} from '@shopify/hydrogen/client';
3
-
4
- import shopifyConfig from '../shopify.config';
5
-
6
- function ClientApp({children}) {
7
- return (
8
- <ShopifyProvider shopifyConfig={shopifyConfig}>{children}</ShopifyProvider>
9
- );
10
- }
11
-
12
- export default renderHydrogen(ClientApp);
@@ -1,7 +0,0 @@
1
- import renderHydrogen from '@shopify/hydrogen/entry-server';
2
-
3
- import App from './App.server';
4
-
5
- export default renderHydrogen(App, () => {
6
- // Custom hook
7
- });
@@ -1,199 +0,0 @@
1
- import {
2
- useShopQuery,
3
- flattenConnection,
4
- ProductProviderFragment,
5
- } from '@shopify/hydrogen';
6
- import gql from 'graphql-tag';
7
-
8
- import HighlightedProduct from '../components/HightlightedProduct.client';
9
- import Layout from '../components/Layout.client';
10
- import ProductCard from '../components/ProductCard.client';
11
- import MediaPlaceholder from '../components/MediaPlaceholder';
12
-
13
- export default function Index() {
14
- const {data} = useShopQuery({
15
- query: QUERY,
16
- variables: {
17
- numProducts: 3,
18
- numProductMetafields: 0,
19
- numProductVariants: 250,
20
- numProductMedia: 1,
21
- numProductVariantMetafields: 10,
22
- numProductVariantSellingPlanAllocations: 10,
23
- numProductSellingPlanGroups: 10,
24
- numProductSellingPlans: 10,
25
- },
26
- });
27
-
28
- const products = data ? flattenConnection(data.products) : [];
29
-
30
- return (
31
- <Layout>
32
- <div className="z-0 gradient w-screen h-screen top-0 left-0 right-0 fixed" />
33
- <div className="z-5 relative space-y-16">
34
- <section className="md:px-4 pt-10 pb-4">
35
- <HydrogenGettingStarted />
36
- </section>
37
-
38
- <section className="space-y-6 md:space-y-0 md:grid grid-cols-3 gap-10">
39
- <div>
40
- <CommerceReadyComponents />
41
- </div>
42
- <div className="col-span-2 md:flex shadow-xl p-4 md:p-6 rounded-md bg-white">
43
- {products[0] ? (
44
- <HighlightedProduct product={products[0]} />
45
- ) : (
46
- <MediaPlaceholder text="Your product here" />
47
- )}
48
- </div>
49
- </section>
50
-
51
- <section className="space-y-6 md:space-y-0 md:grid grid-cols-3 gap-10 flex flex-col-reverse">
52
- {products.length > 2 && (
53
- <div className="col-span-2 md:flex shadow-xl p-4 md:p-6 rounded-md space-y-6 md:space-y-0 md:space-x-6 bg-white">
54
- {[products[1], products[2]].map((product) => {
55
- return (
56
- <div key={product.id}>
57
- <ProductCard product={product} />
58
- </div>
59
- );
60
- })}
61
- </div>
62
- )}
63
- <div>
64
- <StyleWithTailwind />
65
- </div>
66
- </section>
67
- </div>
68
- </Layout>
69
- );
70
- }
71
-
72
- function HydrogenGettingStarted() {
73
- const links = [
74
- {
75
- text: 'Browse Hydrogen documentation',
76
- url: 'https://shopify.dev/beta/hydrogen/',
77
- },
78
- {
79
- text: 'Open the GraphiQL editor',
80
- url: '/graphiql',
81
- },
82
- {
83
- text: 'Explore starter templates',
84
- url: '/',
85
- },
86
- ];
87
-
88
- return (
89
- <>
90
- <h2 className="text-4xl md:text-7xl font-extrabold text-center">
91
- Hello, Hydrogen
92
- </h2>
93
-
94
- <p className="text-xl text-center mt-4 mb-8">
95
- Welcome to your custom storefront. Let‘s get building.
96
- </p>
97
-
98
- <ul className="md:flex justify-center gap-5 space-y-4 md:space-y-0">
99
- {links.map((link) => (
100
- <li key={link.url}>
101
- <a
102
- href={link.url}
103
- className="rounded-full bg-white px-4 py-2 bg-opacity-80 flex items-center gap-2"
104
- >
105
- {link.text}
106
- <svg
107
- width="7"
108
- height="13"
109
- viewBox="0 0 7 13"
110
- fill="none"
111
- xmlns="http://www.w3.org/2000/svg"
112
- >
113
- <path
114
- d="M1 1.5L6 6.5L1 11.5"
115
- stroke="currentColor"
116
- strokeWidth="2"
117
- strokeLinecap="round"
118
- strokeLinejoin="round"
119
- />
120
- </svg>
121
- </a>
122
- </li>
123
- ))}
124
- </ul>
125
- </>
126
- );
127
- }
128
-
129
- function CommerceReadyComponents() {
130
- return (
131
- <>
132
- <h2 className="font-bold text-3xl">Commerce-ready components</h2>
133
- <p className="text-xl leading-8 mt-2 mb-4">
134
- Hydrogen includes the most common components for commerce, powered by
135
- your Shopify custom storefront. They&apos;re accessible, performant, and
136
- ready for implementation.
137
- </p>
138
- <a
139
- className="text-blue-500 text-xl flex items-center gap-1"
140
- href="https://shopify.dev/beta/hydrogen/"
141
- >
142
- Browse components
143
- <svg
144
- xmlns="http://www.w3.org/2000/svg"
145
- className="h-5 w-5"
146
- viewBox="0 0 20 20"
147
- fill="currentColor"
148
- >
149
- <path
150
- fillRule="evenodd"
151
- d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z"
152
- clipRule="evenodd"
153
- />
154
- </svg>
155
- </a>
156
- </>
157
- );
158
- }
159
-
160
- function StyleWithTailwind() {
161
- return (
162
- <>
163
- <h2 className="font-bold text-3xl">
164
- Style with Tailwind or roll your own
165
- </h2>
166
- <p className="text-xl leading-8 mt-2 mb-4">
167
- Hydrogen starter templates are styled using the flexible{' '}
168
- <a className="text-blue-500" href="https://www.tailwindcss.com">
169
- Tailwind CSS
170
- </a>{' '}
171
- framework. Start building with Tailwind&apos;s library or choose your
172
- own styling - it&apos;s up to you.
173
- </p>
174
- </>
175
- );
176
- }
177
-
178
- const QUERY = gql`
179
- query indexContent(
180
- $numProducts: Int!
181
- $numProductMetafields: Int!
182
- $numProductVariants: Int!
183
- $numProductMedia: Int!
184
- $numProductVariantMetafields: Int!
185
- $numProductVariantSellingPlanAllocations: Int!
186
- $numProductSellingPlanGroups: Int!
187
- $numProductSellingPlans: Int!
188
- ) {
189
- products(first: $numProducts) {
190
- edges {
191
- node {
192
- ...ProductProviderFragment
193
- }
194
- }
195
- }
196
- }
197
-
198
- ${ProductProviderFragment}
199
- `;
@@ -1,49 +0,0 @@
1
- import {RawHtml, useShopQuery} from '@shopify/hydrogen';
2
- import {useParams} from 'react-router-dom';
3
- import gql from 'graphql-tag';
4
-
5
- import Layout from '../../../components/Layout.client';
6
-
7
- export default function Article() {
8
- const {handle, articleHandle} = useParams();
9
- const {data} = useShopQuery({
10
- query: QUERY,
11
- variables: {handle, articleHandle},
12
- });
13
-
14
- const article = data.blogByHandle.articleByHandle;
15
-
16
- return (
17
- <Layout>
18
- <section className="my-8 px-4 pt-10 pb-4 text-white">
19
- <h1 className="text-7xl mb-4 font-semibold tracking-tight">
20
- {article.title}
21
- </h1>
22
- </section>
23
-
24
- <section className="my-8 bg-white rounded-3xl p-10 sticky shadow-2xl">
25
- <p className="font-medium mt-1">
26
- Published {new Date(article.publishedAt).toLocaleDateString()} by{' '}
27
- {article.author.name}
28
- </p>
29
-
30
- <RawHtml string={article.contentHtml} className="prose mt-8" />
31
- </section>
32
- </Layout>
33
- );
34
- }
35
-
36
- const QUERY = gql`
37
- query ArticleDetails($handle: String!, $articleHandle: String!) {
38
- blogByHandle(handle: $handle) {
39
- articleByHandle(handle: $articleHandle) {
40
- title
41
- contentHtml
42
- publishedAt
43
- author: authorV2 {
44
- name
45
- }
46
- }
47
- }
48
- }
49
- `;
@@ -1,76 +0,0 @@
1
- import {useParams} from 'react-router-dom';
2
- import {useShopQuery, RawHtml, Link} from '@shopify/hydrogen';
3
- import gql from 'graphql-tag';
4
-
5
- import Layout from '../../components/Layout.client';
6
-
7
- export default function Blog() {
8
- const {handle} = useParams();
9
- const {data} = useShopQuery({query: QUERY, variables: {handle}});
10
-
11
- const blog = data.blogByHandle;
12
-
13
- return (
14
- <Layout>
15
- <div className="relative">
16
- <section className="my-8 px-4 pt-10 pb-4 text-white">
17
- <h1 className="text-7xl mb-4 font-semibold tracking-tight">
18
- {blog.title}
19
- </h1>
20
- </section>
21
-
22
- <section className="my-8 px-4 pb-4">
23
- <ul className="space-y-12 mt-8">
24
- {blog.articles.edges.map((edge) => {
25
- const article = edge.node;
26
- return (
27
- <li
28
- key={article.id}
29
- className="p-5 rounded-3xl overflow-hidden shadow-2xl bg-white bg-opacity-70"
30
- >
31
- <h2 className="text-xl font-medium">
32
- <Link to={`/blogs/${handle}/${article.handle}`}>
33
- {article.title}
34
- </Link>
35
- </h2>
36
- <p className="font-medium mt-1">
37
- Published on{' '}
38
- {new Date(article.publishedAt).toLocaleDateString()} by{' '}
39
- {article.author.name}
40
- </p>
41
-
42
- <RawHtml
43
- string={article.contentHtml}
44
- className="mt-2 prose"
45
- />
46
- </li>
47
- );
48
- })}
49
- </ul>
50
- </section>
51
- </div>
52
- </Layout>
53
- );
54
- }
55
-
56
- const QUERY = gql`
57
- query BlogDetails($handle: String!) {
58
- blogByHandle(handle: $handle) {
59
- title
60
- articles(first: 10) {
61
- edges {
62
- node {
63
- id
64
- title
65
- handle
66
- publishedAt
67
- contentHtml
68
- author {
69
- name
70
- }
71
- }
72
- }
73
- }
74
- }
75
- }
76
- `;
@@ -1,69 +0,0 @@
1
- import {MediaFileFragment, useShopQuery} from '@shopify/hydrogen';
2
- import {useParams} from 'react-router-dom';
3
- import gql from 'graphql-tag';
4
-
5
- import Layout from '../../components/Layout.client';
6
- import ProductCard from '../../components/ProductCard.client';
7
-
8
- export default function Collection() {
9
- const {handle} = useParams();
10
- const {data} = useShopQuery({query: QUERY, variables: {handle}});
11
-
12
- const collection = data.collectionByHandle;
13
-
14
- return (
15
- <Layout>
16
- <h1 className="text-2xl font-bold">{collection.title}</h1>
17
-
18
- <ul className="grid lg:grid-cols-3 gap-6 mt-4">
19
- {collection.products.edges.map((edge) => (
20
- <li key={edge.node.id}>
21
- <ProductCard product={edge.node} />
22
- </li>
23
- ))}
24
- </ul>
25
- </Layout>
26
- );
27
- }
28
-
29
- const QUERY = gql`
30
- fragment CollectionProductDetails on Product {
31
- id
32
- title
33
- handle
34
- priceRange {
35
- maxVariantPrice {
36
- amount
37
- currencyCode
38
- }
39
- minVariantPrice {
40
- amount
41
- currencyCode
42
- }
43
- }
44
- media(first: 1) {
45
- edges {
46
- node {
47
- ...MediaFileFragment
48
- }
49
- }
50
- }
51
- }
52
-
53
- query CollectionDetails($handle: String!) {
54
- collectionByHandle(handle: $handle) {
55
- id
56
- title
57
-
58
- products(first: 10) {
59
- edges {
60
- node {
61
- ...CollectionProductDetails
62
- }
63
- }
64
- }
65
- }
66
- }
67
-
68
- ${MediaFileFragment}
69
- `;
@@ -1,62 +0,0 @@
1
- import {useShopQuery, ProductProviderFragment} from '@shopify/hydrogen';
2
- import {useParams} from 'react-router-dom';
3
- import gql from 'graphql-tag';
4
-
5
- import ProductDetails from '../../components/ProductDetails.client';
6
- import NotFound from '../../components/NotFound.server';
7
-
8
- export default function Product() {
9
- const {handle} = useParams();
10
-
11
- const {data} = useShopQuery({
12
- query: QUERY,
13
- variables: {
14
- handle,
15
- numProductMetafields: 10,
16
- numProductVariants: 250,
17
- numProductMedia: 6,
18
- numProductVariantMetafields: 10,
19
- numProductVariantSellingPlanAllocations: 10,
20
- numProductSellingPlanGroups: 10,
21
- numProductSellingPlans: 10,
22
- },
23
- });
24
-
25
- if (!data.product) {
26
- return <NotFound />;
27
- }
28
-
29
- return <ProductDetails data={data} />;
30
- }
31
-
32
- const QUERY = gql`
33
- query product(
34
- $handle: String!
35
- $numProductMetafields: Int!
36
- $numProductVariants: Int!
37
- $numProductMedia: Int!
38
- $numProductVariantMetafields: Int!
39
- $numProductVariantSellingPlanAllocations: Int!
40
- $numProductSellingPlanGroups: Int!
41
- $numProductSellingPlans: Int!
42
- ) {
43
- product: product(handle: $handle) {
44
- id
45
- vendor
46
- seo {
47
- title
48
- description
49
- }
50
- images(first: 1) {
51
- edges {
52
- node {
53
- originalSrc
54
- }
55
- }
56
- }
57
- ...ProductProviderFragment
58
- }
59
- }
60
-
61
- ${ProductProviderFragment}
62
- `;
@@ -1,107 +0,0 @@
1
- import {useEffect, useMemo, useState} from 'react';
2
- import {useHistory, useLocation} from 'react-router-dom';
3
- import {useShopQuery, MediaFileFragment} from '@shopify/hydrogen';
4
- import gql from 'graphql-tag';
5
-
6
- import Layout from '../components/Layout.client';
7
- import ProductCard from '../components/ProductCard.client';
8
-
9
- /**
10
- * TODO: Refactor to a true server component.
11
- */
12
- export default function Search() {
13
- const {search} = useLocation();
14
- const originalQuery = useMemo(
15
- () => new URLSearchParams(search).get('query'),
16
- [search],
17
- );
18
- const history = useHistory();
19
- const [query, setQuery] = useState(originalQuery);
20
- const [newQuery, setNewQuery] = useState(query);
21
-
22
- useEffect(() => {
23
- if (originalQuery) {
24
- setQuery(originalQuery);
25
- }
26
- }, [originalQuery]);
27
-
28
- return (
29
- <Layout>
30
- <h1 className="text-2xl font-bold">Search</h1>
31
- <form
32
- onSubmit={(event) => {
33
- event.preventDefault();
34
- setQuery(newQuery);
35
- history.push(`/search?query=${newQuery}`);
36
- }}
37
- className="mt-4 space-x-2"
38
- >
39
- <label htmlFor="search">Search Products:</label>
40
- <input
41
- autocomplete="off"
42
- name="search"
43
- id="search"
44
- type="search"
45
- value={newQuery}
46
- onChange={(event) => setNewQuery(event.target.value)}
47
- className="p-1"
48
- />
49
- <button type="submit" className="bg-black text-white font-bold p-1">
50
- Search
51
- </button>
52
- </form>
53
- {query && <SearchResults query={query} />}
54
- </Layout>
55
- );
56
- }
57
-
58
- function SearchResults({query}) {
59
- const {data, fetching} = useShopQuery({query: QUERY, variables: {query}});
60
-
61
- if (fetching) return <p>Loading...</p>;
62
-
63
- return (
64
- <>
65
- <h2 className="text-xl font-medium mt-8">Search results for: {query}</h2>
66
-
67
- {data.products.edges.length ? (
68
- <ul className="grid lg:grid-cols-3 gap-6 mt-4">
69
- {data.products.edges.map((edge) => (
70
- <li key={edge.node.id}>
71
- <ProductCard product={edge.node} />
72
- </li>
73
- ))}
74
- </ul>
75
- ) : (
76
- <p>No results found.</p>
77
- )}
78
- </>
79
- );
80
- }
81
-
82
- const QUERY = gql`
83
- fragment SearchProductDetails on Product {
84
- id
85
- title
86
- handle
87
- media(first: 1) {
88
- edges {
89
- node {
90
- ...MediaFileFragment
91
- }
92
- }
93
- }
94
- }
95
-
96
- query ProductSearch($query: String!) {
97
- products(query: $query, first: 10) {
98
- edges {
99
- node {
100
- ...SearchProductDetails
101
- }
102
- }
103
- }
104
- }
105
-
106
- ${MediaFileFragment}
107
- `;
@@ -1,9 +0,0 @@
1
- module.exports = {
2
- purge: ['./index.html', './src/**/*.{js,jsx,ts,tsx}'],
3
- mode: 'jit',
4
- darkMode: false, // or 'media' or 'class'
5
- variants: {
6
- extend: {},
7
- },
8
- plugins: [require('@tailwindcss/typography')],
9
- };