mirror of
https://github.com/vercel/commerce.git
synced 2025-05-19 16:07:01 +00:00
wip: Add products page
This commit is contained in:
parent
bc777f57a6
commit
523db4e1d4
45
app/[locale]/products/page.tsx
Normal file
45
app/[locale]/products/page.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { ThreeItemGrid } from 'components/grid/three-items';
|
||||||
|
import Footer from 'components/layout/footer';
|
||||||
|
import { SupportedLocale } from 'components/layout/navbar/language-control';
|
||||||
|
|
||||||
|
import Navbar from 'components/layout/navbar';
|
||||||
|
import { getCart } from 'lib/shopify';
|
||||||
|
import { cookies } from 'next/headers';
|
||||||
|
import { Suspense } from 'react';
|
||||||
|
|
||||||
|
export const runtime = 'edge';
|
||||||
|
const { SITE_NAME } = process.env;
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: SITE_NAME,
|
||||||
|
description: SITE_NAME,
|
||||||
|
openGraph: {
|
||||||
|
type: 'website'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function ProductPage({
|
||||||
|
params: { locale }
|
||||||
|
}: {
|
||||||
|
params: { locale?: SupportedLocale };
|
||||||
|
}) {
|
||||||
|
const cartId = cookies().get('cartId')?.value;
|
||||||
|
let cart;
|
||||||
|
|
||||||
|
if (cartId) {
|
||||||
|
cart = await getCart(cartId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative h-screen overflow-scroll">
|
||||||
|
<Navbar cart={cart} locale={locale} />
|
||||||
|
<div className="py-24 md:py-48">
|
||||||
|
<ThreeItemGrid lang={locale} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Suspense>
|
||||||
|
<Footer cart={cart} />
|
||||||
|
</Suspense>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -22,7 +22,7 @@ function ThreeItemGridItem({ item, priority }: { item: Product; priority?: boole
|
|||||||
alt={item.title}
|
alt={item.title}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="font-multilingual max-w-sm pt-4">
|
<div className="font-multilingual max-w-sm pb-24 pt-4 md:pb-0">
|
||||||
<Label
|
<Label
|
||||||
title={item.title as string}
|
title={item.title as string}
|
||||||
amount={item.priceRange.maxVariantPrice.amount}
|
amount={item.priceRange.maxVariantPrice.amount}
|
||||||
|
@ -31,9 +31,6 @@ export function MenuModal({ scrolled }: { scrolled: boolean }) {
|
|||||||
|
|
||||||
<Transition show={isOpen} as={Fragment}>
|
<Transition show={isOpen} as={Fragment}>
|
||||||
<Dialog onClose={() => setIsOpen(false)}>
|
<Dialog onClose={() => setIsOpen(false)}>
|
||||||
{/*
|
|
||||||
Use one Transition.Child to apply one transition to the backdrop...
|
|
||||||
*/}
|
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={Fragment}
|
as={Fragment}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
@ -49,32 +46,31 @@ export function MenuModal({ scrolled }: { scrolled: boolean }) {
|
|||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={Fragment}
|
as={Fragment}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
enterFrom="opacity-0 scale-95"
|
enterFrom="opacity-0"
|
||||||
enterTo="opacity-100 scale-100"
|
enterTo="opacity-100 scale-100"
|
||||||
leave="ease-in duration-200"
|
leave="ease-in duration-200"
|
||||||
leaveFrom="opacity-100 scale-100"
|
leaveFrom="opacity-100 scale-100"
|
||||||
leaveTo="opacity-0 scale-95"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 z-30 backdrop-blur-sm">
|
<div className="fixed inset-0 z-30 bg-dark/80 backdrop-blur-sm">
|
||||||
<Dialog.Panel>
|
<Dialog.Panel>
|
||||||
|
<div className="z-40 mx-auto max-w-screen-xl px-6">
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'fixed right-5 top-6 z-40 px-2 py-1',
|
'flex flex-row justify-end space-x-6 px-2',
|
||||||
scrolled ? 'md:top-6' : 'md:top-0'
|
scrolled ? 'py-0' : 'py-0 md:py-6'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex flex-row space-x-6">
|
|
||||||
<LanguageControl lang={locale as SupportedLocale} />
|
<LanguageControl lang={locale as SupportedLocale} />
|
||||||
|
|
||||||
<button ref={closeButtonRef} onClick={close} className="">
|
<button ref={closeButtonRef} onClick={close}>
|
||||||
<CloseIcon className="h-10 w-10 stroke-current transition-opacity duration-150 hover:opacity-50" />
|
<CloseIcon className="h-10 w-10 stroke-current transition-opacity duration-150 hover:opacity-50" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="fixed inset-0 grid grid-cols-1 place-content-center bg-dark/80">
|
<div className="grid h-[calc(100vh-124px)] grid-cols-1 place-content-center">
|
||||||
<div className="flex flex-row justify-end">
|
<div className="flex flex-row justify-end">
|
||||||
<nav className="flex flex-col space-y-4 px-6 text-right">
|
<nav className="flex flex-col space-y-4 px-4 text-right">
|
||||||
<div>
|
<div>
|
||||||
<Link
|
<Link
|
||||||
href="/products"
|
href="/products"
|
||||||
@ -149,6 +145,7 @@ export function MenuModal({ scrolled }: { scrolled: boolean }) {
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</Dialog.Panel>
|
</Dialog.Panel>
|
||||||
</div>
|
</div>
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
@ -6,6 +6,7 @@ import CartModal from 'components/cart/modal';
|
|||||||
import OpenCart from 'components/cart/open-cart';
|
import OpenCart from 'components/cart/open-cart';
|
||||||
import LogoNamemark from 'components/icons/namemark';
|
import LogoNamemark from 'components/icons/namemark';
|
||||||
import { Cart } from 'lib/shopify/types';
|
import { Cart } from 'lib/shopify/types';
|
||||||
|
import Link from 'next/link';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
import { useInView } from 'react-intersection-observer';
|
import { useInView } from 'react-intersection-observer';
|
||||||
import { MenuModal } from '../menu/modal';
|
import { MenuModal } from '../menu/modal';
|
||||||
@ -19,7 +20,7 @@ export default function Navbar({ cart, locale }: { cart?: Cart; locale?: Support
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref}>
|
<div ref={ref}>
|
||||||
<div className="fixed top-0 z-20 w-full bg-dark/20 backdrop-blur-sm">
|
<div className="fixed top-0 z-20 w-full bg-dark/70 backdrop-blur-sm">
|
||||||
<Transition
|
<Transition
|
||||||
show={!!ref && !inView}
|
show={!!ref && !inView}
|
||||||
enter="transition ease duration-150 transform"
|
enter="transition ease duration-150 transform"
|
||||||
@ -31,13 +32,15 @@ export default function Navbar({ cart, locale }: { cart?: Cart; locale?: Support
|
|||||||
>
|
>
|
||||||
<div className="mx-auto flex max-w-screen-xl flex-row items-start justify-between">
|
<div className="mx-auto flex max-w-screen-xl flex-row items-start justify-between">
|
||||||
<div className="px-4 py-2">
|
<div className="px-4 py-2">
|
||||||
|
<Link href="/">
|
||||||
<LogoNamemark className={clsx('w-[260px]', 'fill-current')} />
|
<LogoNamemark className={clsx('w-[260px]', 'fill-current')} />
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<nav className="flex flex-row items-center space-x-4 px-6">
|
<nav className="flex flex-row items-center space-x-4 px-6">
|
||||||
<Suspense fallback={<OpenCart />}>
|
<Suspense fallback={<OpenCart />}>
|
||||||
<div className="flex flex-col-reverse items-center justify-center space-y-2 px-2 md:flex-row md:space-x-6">
|
<div className="flex flex-col-reverse items-center justify-center space-y-2 px-2 md:flex-row md:space-x-6">
|
||||||
<CartModal cart={cart} />
|
<CartModal cart={cart} />
|
||||||
<MenuModal scrolled={inView} />
|
<MenuModal scrolled={!inView} />
|
||||||
</div>
|
</div>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</nav>
|
</nav>
|
||||||
@ -48,21 +51,25 @@ export default function Navbar({ cart, locale }: { cart?: Cart; locale?: Support
|
|||||||
className={clsx('mx-auto flex max-w-screen-xl flex-row items-start justify-between px-6')}
|
className={clsx('mx-auto flex max-w-screen-xl flex-row items-start justify-between px-6')}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
<Link href="/">
|
||||||
<LogoNamemark
|
<LogoNamemark
|
||||||
className={clsx(
|
className={clsx(
|
||||||
inView ? 'w-[260px] md:w-[600px]' : 'w-[260px] md:w-[260px]',
|
inView ? 'w-[260px] md:w-[600px]' : 'w-[260px] md:w-[260px]',
|
||||||
'fill-current pt-4 transition-all duration-150 md:pt-12'
|
'fill-current pt-4 transition-all duration-150 md:pt-12'
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<nav className="flex flex-row space-x-4 px-2 md:pt-6">
|
<nav className="flex flex-row items-center space-x-4 px-2 md:pt-6">
|
||||||
|
<div className="hidden md:block">
|
||||||
<LanguageControl lang={locale} />
|
<LanguageControl lang={locale} />
|
||||||
<Suspense fallback={<OpenCart />}>
|
|
||||||
<div className="flex flex-col-reverse items-center justify-center space-y-2 rounded md:flex-row md:space-x-6">
|
|
||||||
<CartModal cart={cart} />
|
|
||||||
<MenuModal scrolled={inView} />
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col-reverse items-center justify-center space-y-2 rounded md:flex-row md:space-x-6 md:space-y-0">
|
||||||
|
<Suspense fallback={<OpenCart />}>
|
||||||
|
<CartModal cart={cart} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
<MenuModal scrolled={!inView} />
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user