product: begin content

This commit is contained in:
andr-ew 2023-06-21 20:51:00 -05:00
parent f0187e9f7a
commit b4b6221389
5 changed files with 3398 additions and 1445 deletions

View File

@ -1,11 +1,6 @@
export default function ProductLayout({ children }) {
export default function PageLayout({ children }) {
return (
<>
{/* <header> */}
{/* <nav> */}
{/* <a>back</a> */}
{/* </nav> */}
{/* </header> */}
<main>{children}</main>
</>
);

View File

@ -1,4 +1,6 @@
import { getProducts } from 'lib/shopify';
import xss from 'xss';
import { getProducts, getProduct } from 'lib/shopify';
export async function generateStaticParams() {
const products = await getProducts({
@ -7,11 +9,87 @@ export async function generateStaticParams() {
query: '',
});
console.log({ products });
return products.map(product => ({ product: product.handle }));
}
export default async function ProductPage({ params: { handle } }) {
return <h1>{handle}</h1>;
export async function Option({ value, children, selected }) {
return <option {...{ value, selected }}>{children}</option>;
}
export async function Select({ id, label, children }) {
return (
<div>
<select name={label} id={id}>
{children}
</select>
{/* TODO: parentheses around label w/ css */}
<label for={id}>{label}</label>
</div>
);
}
//TODO: NumberInput
export default async function ProductPage({ params: { handle } }) {
const product = await getProduct(handle);
const hasOptions = product?.options?.[0]?.values.length > 1 ?? false;
//TODO: turn these checks into shared functions
// const onSale =
// (compareAtPriceRange?.minVariantPrice?.amount ?? 0) >
// (priceRange?.minVariantPrice?.amount ?? 0) ||
// (compareAtPriceRange?.maxVariantPrice?.amount ?? 0) >
// (priceRange?.maxVariantPrice?.amount ?? 0);
const isForSale = (product?.priceRange?.maxVariantPrice?.amount ?? 0) > 0;
return (
<>
{product?.handle ? (
<>
<h1>{product?.title}</h1>
<div
dangerouslySetInnerHTML={{
__html: xss(product.descriptionHtml),
}}
/>
{product?.availableForSale && isForSale && (
<>
<div>
<input
type='number'
id='quantity'
name='quantity'
min='1'
/>
<label for='quantity'>Qty</label>
</div>
<>
{hasOptions &&
product?.options?.map(option => (
<Select
key={option?.id}
id={option?.name}
label={option?.name}
>
{option?.values?.map((value, i) => (
<Option
key={value}
value={value}
selected={i == 0}
>
{value}
</Option>
))}
</Select>
))}
</>
</>
)}
</>
) : (
<p>Product not found</p>
)}
</>
);
}

View File

@ -27,6 +27,7 @@ export const PriceRanges = ({
compareAtPriceRange,
availableForSale,
}) => {
//TODO: turn these checks into shared functions
const onSale =
(compareAtPriceRange?.minVariantPrice?.amount ?? 0) >
(priceRange?.minVariantPrice?.amount ?? 0) ||

4642
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,55 @@
{
"private": true,
"engines": {
"node": ">=16",
"pnpm": ">=7"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint-staged": "lint-staged",
"prettier": "prettier --write --ignore-unknown .",
"prettier:check": "prettier --check --ignore-unknown .",
"test": "pnpm lint && pnpm prettier:check",
"test:e2e": "playwright test"
},
"git": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*": "prettier --write --ignore-unknown"
},
"dependencies": {
"@headlessui/react": "^1.7.15",
"@vercel/og": "^0.5.6",
"clsx": "^1.2.1",
"framer-motion": "^10.12.16",
"is-empty-iterable": "^3.0.0",
"next": "13.4.6",
"react": "18.2.0",
"react-cookie": "^4.1.1",
"react-dom": "18.2.0"
},
"devDependencies": {
"@playwright/test": "^1.34.3",
"@tailwindcss/typography": "^0.5.9",
"@types/node": "20.2.5",
"@types/react": "18.2.8",
"@types/react-dom": "18.2.4",
"@vercel/git-hooks": "^1.0.0",
"autoprefixer": "^10.4.14",
"eslint": "^8.42.0",
"eslint-config-next": "^13.4.4",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-unicorn": "^47.0.0",
"lint-staged": "^13.2.2",
"postcss": "^8.4.24",
"prettier": "^2.8.8",
"prettier-plugin-tailwindcss": "^0.3.0",
"tailwindcss": "^3.3.2",
"typescript": "5.1.3"
}
"private": true,
"engines": {
"node": ">=16",
"pnpm": ">=7"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint-staged": "lint-staged",
"prettier": "prettier --write --ignore-unknown .",
"prettier:check": "prettier --check --ignore-unknown .",
"test": "pnpm lint && pnpm prettier:check",
"test:e2e": "playwright test"
},
"git": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*": "prettier --write --ignore-unknown"
},
"dependencies": {
"@headlessui/react": "^1.7.15",
"@vercel/og": "^0.5.6",
"clsx": "^1.2.1",
"framer-motion": "^10.12.16",
"is-empty-iterable": "^3.0.0",
"next": "13.4.6",
"react": "18.2.0",
"react-cookie": "^4.1.1",
"react-dom": "18.2.0",
"xss": "^1.0.14"
},
"devDependencies": {
"@playwright/test": "^1.34.3",
"@tailwindcss/typography": "^0.5.9",
"@types/node": "20.2.5",
"@types/react": "18.2.8",
"@types/react-dom": "18.2.4",
"@vercel/git-hooks": "^1.0.0",
"autoprefixer": "^10.4.14",
"eslint": "^8.42.0",
"eslint-config-next": "^13.4.4",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-unicorn": "^47.0.0",
"lint-staged": "^13.2.2",
"postcss": "^8.4.24",
"prettier": "^2.8.8",
"prettier-plugin-tailwindcss": "^0.3.0",
"tailwindcss": "^3.3.2",
"typescript": "5.1.3"
}
}