-
Notifications
You must be signed in to change notification settings - Fork 248
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add and render ImageText section in skeleton homepage
- Loading branch information
1 parent
98bcfc7
commit ba8fc2e
Showing
4 changed files
with
132 additions
and
212 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
# These variables are only available locally in MiniOxygen | ||
|
||
# SESSION_SECRET="foobar" | ||
# PUBLIC_STORE_DOMAIN="mock.shop" | ||
SESSION_SECRET="foobar" | ||
PUBLIC_STORE_DOMAIN="mock.shop" | ||
PUBLIC_STOREFRONT_API_TOKEN="3b580e70970c4528da70c98e097c2fa0" | ||
PUBLIC_STORE_DOMAIN="hydrogen-preview.myshopify.com" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,145 +1,33 @@ | ||
import type {V2_MetaFunction} from '@shopify/remix-oxygen'; | ||
import {defer, type LoaderArgs} from '@shopify/remix-oxygen'; | ||
import {Await, useLoaderData, Link} from '@remix-run/react'; | ||
import {Suspense} from 'react'; | ||
import {Image, Money} from '@shopify/hydrogen'; | ||
import type { | ||
FeaturedCollectionFragment, | ||
RecommendedProductsQuery, | ||
} from 'storefrontapi.generated'; | ||
import {json, type LoaderArgs} from '@shopify/remix-oxygen'; | ||
import {useLoaderData} from '@remix-run/react'; | ||
import {ImageText} from '../sections/ImageText'; | ||
|
||
export const meta: V2_MetaFunction = () => { | ||
return [{title: 'Hydrogen | Home'}]; | ||
}; | ||
|
||
export async function loader({context}: LoaderArgs) { | ||
const {storefront} = context; | ||
const {collections} = await storefront.query(FEATURED_COLLECTION_QUERY); | ||
const featuredCollection = collections.nodes[0]; | ||
const recommendedProducts = storefront.query(RECOMMENDED_PRODUCTS_QUERY); | ||
|
||
return defer({featuredCollection, recommendedProducts}); | ||
// For now we query for an individual section. In the future we'll want to | ||
// query for all sections on the page via a route metaobject query that holds | ||
// an array of sections for a given route | ||
const {section} = await context.storefront.query<{ | ||
// TODO: this type should be auto code-generated from the CLI based | ||
section: Parameters<typeof ImageText>[0]; | ||
}>(ImageText.section.query, { | ||
variables: { | ||
handle: 'section-image-text-default', | ||
}, | ||
}); | ||
|
||
return json({ | ||
imageText: section, | ||
}); | ||
} | ||
|
||
export default function Homepage() { | ||
const data = useLoaderData<typeof loader>(); | ||
return ( | ||
<div className="home"> | ||
<FeaturedCollection collection={data.featuredCollection} /> | ||
<RecommendedProducts products={data.recommendedProducts} /> | ||
</div> | ||
); | ||
} | ||
|
||
function FeaturedCollection({ | ||
collection, | ||
}: { | ||
collection: FeaturedCollectionFragment; | ||
}) { | ||
const image = collection.image; | ||
const {imageText} = useLoaderData<typeof loader>(); | ||
return ( | ||
<Link | ||
className="featured-collection" | ||
to={`/collections/${collection.handle}`} | ||
> | ||
{image && ( | ||
<div className="featured-collection-image"> | ||
<Image data={image} sizes="100vw" /> | ||
</div> | ||
)} | ||
<h1>{collection.title}</h1> | ||
</Link> | ||
<div className="home">{imageText && <ImageText {...imageText} />}</div> | ||
); | ||
} | ||
|
||
function RecommendedProducts({ | ||
products, | ||
}: { | ||
products: Promise<RecommendedProductsQuery>; | ||
}) { | ||
return ( | ||
<div className="recommended-products"> | ||
<h2>Recommended Products</h2> | ||
<Suspense fallback={<div>Loading...</div>}> | ||
<Await resolve={products}> | ||
{({products}) => ( | ||
<div className="recommended-products-grid"> | ||
{products.nodes.map((product) => ( | ||
<Link | ||
key={product.id} | ||
className="recommended-product" | ||
to={`/products/${product.handle}`} | ||
> | ||
<Image | ||
data={product.images.nodes[0]} | ||
aspectRatio="1/1" | ||
sizes="(min-width: 45em) 20vw, 50vw" | ||
/> | ||
<h4>{product.title}</h4> | ||
<small> | ||
<Money data={product.priceRange.minVariantPrice} /> | ||
</small> | ||
</Link> | ||
))} | ||
</div> | ||
)} | ||
</Await> | ||
</Suspense> | ||
<br /> | ||
</div> | ||
); | ||
} | ||
|
||
const FEATURED_COLLECTION_QUERY = `#graphql | ||
fragment FeaturedCollection on Collection { | ||
id | ||
title | ||
image { | ||
id | ||
url | ||
altText | ||
width | ||
height | ||
} | ||
handle | ||
} | ||
query FeaturedCollection($country: CountryCode, $language: LanguageCode) | ||
@inContext(country: $country, language: $language) { | ||
collections(first: 1, sortKey: UPDATED_AT, reverse: true) { | ||
nodes { | ||
...FeaturedCollection | ||
} | ||
} | ||
} | ||
` as const; | ||
|
||
const RECOMMENDED_PRODUCTS_QUERY = `#graphql | ||
fragment RecommendedProduct on Product { | ||
id | ||
title | ||
handle | ||
priceRange { | ||
minVariantPrice { | ||
amount | ||
currencyCode | ||
} | ||
} | ||
images(first: 1) { | ||
nodes { | ||
id | ||
url | ||
altText | ||
width | ||
height | ||
} | ||
} | ||
} | ||
query RecommendedProducts ($country: CountryCode, $language: LanguageCode) | ||
@inContext(country: $country, language: $language) { | ||
products(first: 4, sortKey: UPDATED_AT, reverse: true) { | ||
nodes { | ||
...RecommendedProduct | ||
} | ||
} | ||
} | ||
` as const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import {defineSection, Image} from '@shopify/hydrogen'; | ||
import type {MediaImage} from '@shopify/hydrogen/storefront-api-types'; | ||
|
||
// TODO: these types should be auto code-generated from the CLI based | ||
// on the passed schema and the generated query. | ||
type SectionImageText = { | ||
name: 'Image Text'; | ||
type: 'section_image_text'; | ||
heading: { | ||
value: string; | ||
}; | ||
image: { | ||
reference?: MediaImage; | ||
}; | ||
}; | ||
|
||
export function ImageText({heading, image}: SectionImageText) { | ||
return ( | ||
<section className="section_image_text"> | ||
<h1>{heading.value}</h1> | ||
{image.reference?.image ? ( | ||
<Image sizes="100vw" data={image.reference.image} /> | ||
) : null} | ||
</section> | ||
); | ||
} | ||
|
||
ImageText.section = defineSection({ | ||
name: 'Image Text', | ||
type: 'image_text', | ||
fields: [ | ||
{ | ||
name: 'Text', | ||
key: 'heading', | ||
type: 'single_line_text_field', | ||
default: 'Image Text Heading', | ||
required: true, | ||
}, | ||
{ | ||
name: 'Image', | ||
key: 'image', | ||
type: 'file_reference', | ||
required: true, | ||
default: { | ||
altText: null, | ||
url: 'https://placehold.co/1920x1080.jpg', | ||
width: 1920, | ||
height: 1080, | ||
}, | ||
}, | ||
], | ||
}); | ||
|
||
/* | ||
* The generated query for this section looks like: | ||
* -------------------------------------------------------------------------------------- | ||
query SectionImageText($handle: String!) { | ||
section: metaobject(handle: {handle: $handle, type: "section_image_text"}) { | ||
id | ||
handle | ||
type | ||
heading: field(key: "heading") { | ||
value | ||
} | ||
image: field(key: "image") { | ||
reference { | ||
...MediaImageFragment | ||
} | ||
} | ||
} | ||
} | ||
fragment MediaImageFragment on MediaImage { | ||
__typename | ||
image { | ||
altText | ||
url | ||
width | ||
height | ||
} | ||
} | ||
*/ | ||
|
||
/* | ||
* The query response would look like | ||
-------------------------------------------------------------------------------------- | ||
* | ||
{ | ||
"id": "gid://shopify/Metaobject/602701880", | ||
"handle": "section-image-text-default", | ||
"type": "section_image_text", | ||
"heading": { | ||
"value": "Image Text Heading" | ||
}, | ||
"image": { | ||
"reference": { | ||
"__typename": "MediaImage", | ||
"image": { | ||
"altText": null, | ||
"url": "https://cdn.shopify.com/s/files/1/0551/4566/0472/files/Main-the-Inferno_23782978-cfe9-42ca-b5ef-9f04284b1872.jpg?v=1684520797", | ||
"width": 3908, | ||
"height": 3908 | ||
} | ||
} | ||
} | ||
} | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters