Skip to content

Commit

Permalink
@benjaminsehl/pdp demo store neue (#1414)
Browse files Browse the repository at this point in the history
* Product Swimlane now works with product recommendations

* Updates Header for mobile

* Mobile layout for header, footer, and key layout components

* Adds expanding menus to footer

* Adds mobile layout for search

* Basic product page layout

* Adds URL param control to PDP
  • Loading branch information
benjaminsehl authored Jun 2, 2022
1 parent 0c456db commit 3440639
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
import {useProduct} from '@shopify/hydrogen';
import {useEffect} from 'react';
import {useProduct, useUrl, useNavigate} from '@shopify/hydrogen';
import {Heading, Text} from '~/components/elements';

export default function ProductForm() {
const {pathname, search} = useUrl();
const navigate = useNavigate();

let params = new URLSearchParams(search);

const {options, setSelectedOption, selectedOptions} = useProduct();

useEffect(() => {
options.map(({name, values}) => {
const currentValue = params.get(name.toLowerCase());
if (currentValue) {
const matchedValue = values.filter(
(value) => value.toLowerCase() === currentValue,
);
setSelectedOption(name, matchedValue[0]);
}
});
}, []);

function handleChange(name, value) {
setSelectedOption(name, value);
params.set(
encodeURIComponent(name.toLowerCase()),
encodeURIComponent(value.toLowerCase()),
);
navigate(
`${pathname}?${params.toString()}`,
{replace: true},
{reloadDocument: false},
);
}

return (
<form>
{
Expand All @@ -27,7 +59,7 @@ export default function ProductForm() {
name={`option[${name}]`}
value={value}
checked={checked}
onChange={() => setSelectedOption(name, value)}
onChange={() => handleChange(name, value)}
/>
<div
className={`p-2 border cursor-pointer rounded text-sm md:text-md ${
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
import {useProduct, MediaFile} from '@shopify/hydrogen/client';
import {Tab} from '@headlessui/react';
import {Fragment, useState} from 'react';

/**
* A client component that defines a media gallery for hosting images, 3D models, and videos of products
*/
export default function Gallery() {
const {descriptionHtml, media} = useProduct();
const [selectedIndex, setSelectedIndex] = useState();
export default function Gallery({className}) {
const {media} = useProduct();

if (!media.length) {
return null;
}

const featuredMedia = media[1];
const mediaFiles = media.slice(1);

let featuredExtraProps = {
interactionPromptThreshold: '50',
ar: true,
loading: 'eager',
disableZoom: true,
};

return (
<div className="bg-white bg-productPhotos rounded-xl shadow-productPhotos overflow-clip py-10 w-full md:w-[33.5rem] relative grid items-center justify-start">
{mediaFiles.map((med) => {
<div
className={`grid grid-flow-col md:grid-flow-row gap-4 px-4 pb-4 overflow-x-scroll snap-x snap-center w-full md:grid-cols-2 ${className}`}
>
{media.map((med, i) => {
let extraProps = {};

if (med.mediaContentType === 'MODEL_3D') {
Expand All @@ -43,16 +32,19 @@ export default function Gallery() {
};

return (
<div className="relative" key={med.id || med.image.id}>
<div
className={`${
i % 3 === 0 ? 'md:col-span-2' : 'md:col-span-1'
} aspect-square md:w-full w-[80vw]`}
key={med.id || med.image.id}
>
<MediaFile
tabIndex="0"
className={`object-scale-down w-full h-full ${
className={` w-full h-full ${
med.mediaContentType !== 'MODEL_3D' && 'mix-blend-multiply'
} aspect-square`}
data={data}
options={{
height: '485',
width: '485',
crop: 'center',
}}
{...extraProps}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import clsx from 'clsx';
import {Heading} from '~/components/elements';
import {missingClass} from '~/lib/utils';

export default function Section({
as = 'section',
Expand All @@ -26,7 +27,7 @@ export default function Section({

const styles = clsx(
'w-full grid gap-4 md:gap-8',
paddings[padding],
missingClass(className, 'p[xy]?-') && paddings[padding],
dividers[divider],
className,
);
Expand Down
22 changes: 15 additions & 7 deletions templates/demo-store-neue/src/routes/products/[handle].server.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,21 @@ export default function Product() {
return (
<ProductProvider data={product}>
<Layout>
<ProductGallery />
<section>
<Heading as="h1">{product.title}</Heading>
{product.vendor && <Text>{product.vendor}</Text>}
<ProductForm />
<div></div>
</section>
<Section className="pb-6 md:p-8 lg:p-12">
<div className="grid items-start gap-6 lg:gap-20 md:grid-cols-2 lg:grid-cols-3">
<ProductGallery className="w-full lg:col-span-2" />
<section className="sticky py-4 px-4 md:px-0 top-[6rem] lg:top-[8rem] xl:top-[10rem]">
<Heading as="h1">{product.title}</Heading>
{product.vendor && (
<Text className={'opacity-50 font-medium'}>
{product.vendor}
</Text>
)}
<ProductForm />
<div></div>
</section>
</div>
</Section>
<ProductSwimlane title="Related Products" data={product.id} />
</Layout>
</ProductProvider>
Expand Down

0 comments on commit 3440639

Please sign in to comment.