Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions templates/demo-store-neue/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<title>Hydrogen Demo Store</title>
<link rel="stylesheet" href="/src/styles/index.css" />
<link rel="preconnect" href="https://cdn.shopify.com" />
<link rel="preconnect" href="https://shop.app/" />
<link rel="preconnect" href="https://hydrogen-preview.myshopify.com/" />
</head>
<body>
<div id="root"></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
import {
useCart,
CartCheckoutButton,
useCartLine,
CartLineProvider,
CartShopPayButton,
} from '@shopify/hydrogen';

/*
This example requires Tailwind CSS v2.0+

This example requires some changes to your config:

```
// tailwind.config.js
module.exports = {
// ...
plugins: [
// ...
require('@tailwindcss/forms'),
],
}
```
*/

// TODO: Replace with our own icons

import {
CheckIcon,
ClockIcon,
QuestionMarkCircleIcon,
XIcon,
} from '@heroicons/react/solid';
import {Button} from '../elements';

const products = [
{
id: 1,
name: 'Basic Tee',
href: '#',
price: '$32.00',
color: 'Sienna',
inStock: true,
size: 'Large',
imageSrc:
'https://tailwindui.com/img/ecommerce-images/shopping-cart-page-01-product-01.jpg',
imageAlt: "Front of men's Basic Tee in sienna.",
},
{
id: 2,
name: 'Basic Tee',
href: '#',
price: '$32.00',
color: 'Black',
inStock: false,
leadTime: '3–4 weeks',
size: 'Large',
imageSrc:
'https://tailwindui.com/img/ecommerce-images/shopping-cart-page-01-product-02.jpg',
imageAlt: "Front of men's Basic Tee in black.",
},
{
id: 3,
name: 'Nomad Tumbler',
href: '#',
price: '$35.00',
color: 'White',
inStock: true,
imageSrc:
'https://tailwindui.com/img/ecommerce-images/shopping-cart-page-01-product-03.jpg',
imageAlt: 'Insulated bottle with white base and black snap lid.',
},
];

export default function CartDetails() {
const {lines} = useCart();

return (
<form className="lg:grid lg:grid-cols-12 lg:gap-x-12 lg:items-start xl:gap-x-16">
<section aria-labelledby="cart-heading" className="lg:col-span-7">
<h2 id="cart-heading" className="sr-only">
Items in your shopping cart
</h2>

<ul
role="list"
className="border-t border-b border-gray-200 divide-y divide-gray-200"
>
{lines.map((line) => {
return (
<CartLineProvider key={line.id} line={line}>
<CartLineItem />
</CartLineProvider>
);
})}
</ul>
</section>

{/* Order summary */}
<section
aria-labelledby="summary-heading"
className="sticky px-4 py-6 my-16 rounded-lg top-24 bg-gray-50 sm:p-6 lg:p-8 lg:mt-0 lg:col-span-5"
>
<h2 id="summary-heading" className="text-lg font-medium text-gray-900">
Order summary
</h2>

<dl className="mt-6 space-y-4">
<div className="flex items-center justify-between">
<dt className="text-sm text-gray-600">Subtotal</dt>
<dd className="text-sm font-medium text-gray-900">$99.00</dd>
</div>
<div className="flex items-center justify-between pt-4 border-t border-gray-200">
<dt className="flex items-center text-sm text-gray-600">
<span>Shipping estimate</span>
<a
href="#"
className="flex-shrink-0 ml-2 text-gray-400 hover:text-gray-500"
>
<span className="sr-only">
Learn more about how shipping is calculated
</span>
<QuestionMarkCircleIcon
className="w-5 h-5"
aria-hidden="true"
/>
</a>
</dt>
<dd className="text-sm font-medium text-gray-900">$5.00</dd>
</div>
<div className="flex items-center justify-between pt-4 border-t border-gray-200">
<dt className="flex text-sm text-gray-600">
<span>Tax estimate</span>
<a
href="#"
className="flex-shrink-0 ml-2 text-gray-400 hover:text-gray-500"
>
<span className="sr-only">
Learn more about how tax is calculated
</span>
<QuestionMarkCircleIcon
className="w-5 h-5"
aria-hidden="true"
/>
</a>
</dt>
<dd className="text-sm font-medium text-gray-900">$8.32</dd>
</div>
<div className="flex items-center justify-between pt-4 border-t border-gray-200">
<dt className="text-base font-medium text-gray-900">Order total</dt>
<dd className="text-base font-medium text-gray-900">$112.32</dd>
</div>
</dl>

<div className="grid gap-4 mt-6">
<CartShopPayButton className="flex items-center justify-center w-full h-12 rounded bg-shopPay" />
<CartCheckoutButton className="w-full">
<Button as="span" width="full">
Continue to Checkout
</Button>
</CartCheckoutButton>
</div>
</section>
</form>
);
}

function CartLineItem() {
const {id, price, productTitle, quantity} = useCartLine();

const product = {
id: 1,
name: 'Basic Tee',
href: '#',
price: '$32.00',
color: 'Sienna',
inStock: true,
size: 'Large',
imageSrc:
'https://tailwindui.com/img/ecommerce-images/shopping-cart-page-01-product-01.jpg',
imageAlt: "Front of men's Basic Tee in sienna.",
};
return (
<li key={product.id} className="flex py-6 sm:py-10">
<div className="flex-shrink-0">
<img
src={product.imageSrc}
alt={product.imageAlt}
className="object-cover object-center w-24 h-24 rounded-md sm:w-48 sm:h-48"
/>
</div>

<div className="flex flex-col justify-between flex-1 ml-4 sm:ml-6">
<div className="relative pr-9 sm:grid sm:grid-cols-2 sm:gap-x-6 sm:pr-0">
<div>
<div className="flex justify-between">
<h3 className="text-sm">
<a
href={product.href}
className="font-medium text-gray-700 hover:text-gray-800"
>
{product.name}
</a>
</h3>
</div>
<div className="flex mt-1 text-sm">
<p className="text-gray-500">{product.color}</p>
{product.size ? (
<p className="pl-4 ml-4 text-gray-500 border-l border-gray-200">
{product.size}
</p>
) : null}
</div>
<p className="mt-1 text-sm font-medium text-gray-900">
{product.price}
</p>
</div>

<div className="mt-4 sm:mt-0 sm:pr-9">
<label htmlFor={`quantity-${id}`} className="sr-only">
Quantity, {product.name}
</label>
<select
id={`quantity-${id}`}
name={`quantity-${id}`}
className="max-w-full rounded-md border border-gray-300 py-1.5 text-base leading-5 font-medium text-gray-700 text-left shadow-sm focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
>
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
<option value={5}>5</option>
<option value={6}>6</option>
<option value={7}>7</option>
<option value={8}>8</option>
</select>

<div className="absolute top-0 right-0">
<button
type="button"
className="inline-flex p-2 -m-2 text-gray-400 hover:text-gray-500"
>
<span className="sr-only">Remove</span>
<XIcon className="w-5 h-5" aria-hidden="true" />
</button>
</div>
</div>
</div>

<p className="flex mt-4 space-x-2 text-sm text-gray-700">
{product.inStock ? (
<CheckIcon
className="flex-shrink-0 w-5 h-5 text-green-500"
aria-hidden="true"
/>
) : (
<ClockIcon
className="flex-shrink-0 w-5 h-5 text-gray-300"
aria-hidden="true"
/>
)}

<span>
{product.inStock ? 'In stock' : `Ships in ${product.leadTime}`}
</span>
</p>
</div>
</li>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {Disclosure} from '@headlessui/react';
export default function Footer({menus = mockData}) {
const styles = {
footer:
'grid items-start w-full grid-flow-row grid-cols-1 gap-6 py-8 border-b md:gap-8 lg:gap-12 md:grid-cols-2 lg:grid-cols-4 bg-primary dark:bg-contrast dark:text-primary text-contrast',
'grid items-start w-full grid-flow-row grid-cols-1 gap-6 py-8 px-4 md:px-8 lg:px-12 border-b md:gap-8 lg:gap-12 md:grid-cols-2 lg:grid-cols-4 bg-primary dark:bg-contrast dark:text-primary text-contrast',
section: 'grid gap-4',
nav: 'grid gap-2 pb-6',
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Link, useUrl} from '@shopify/hydrogen';
import {Link, useUrl, useCart} from '@shopify/hydrogen';
import {useMedia} from 'react-use';

import {
Expand Down Expand Up @@ -27,6 +27,8 @@ export default function Header({title}) {
}

function MobileHeader({title, home}) {
const {totalQuantity} = useCart();

const styles = {
button: 'relative flex items-center justify-center w-8 h-8',
container: `${
Expand Down Expand Up @@ -75,14 +77,16 @@ function MobileHeader({title, home}) {
</button>
<Link to={'/cart'} className={styles.button}>
<IconBag />
<CartBadge dark={home} quantity={1} />
<CartBadge dark={home} quantity={totalQuantity} />
</Link>
</div>
</header>
);
}

function DesktopHeader({title, home}) {
const {totalQuantity} = useCart();

const styles = {
button: 'relative flex items-center justify-center w-8 h-8',
container: `${
Expand Down Expand Up @@ -131,7 +135,7 @@ function DesktopHeader({title, home}) {
</button>
<Link to={'/cart'} className={styles.button}>
<IconBag />
<CartBadge dark={home} quantity={1} />
<CartBadge dark={home} quantity={totalQuantity} />
</Link>
</div>
</header>
Expand Down
Loading