separate out PurchaseInput & input components (prep for interaction)

This commit is contained in:
andr-ew 2023-06-22 17:18:16 -05:00
parent b4b6221389
commit 824070a54b
3 changed files with 70 additions and 60 deletions

View File

@ -2,6 +2,8 @@ import xss from 'xss';
import { getProducts, getProduct } from 'lib/shopify';
import PurchaseInput from '/components/product/purchase-input.js';
export async function generateStaticParams() {
const products = await getProducts({
sortKey: 'UPDATED_AT',
@ -12,36 +14,10 @@ export async function generateStaticParams() {
return products.map(product => ({ product: product.handle }));
}
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 ? (
@ -52,40 +28,7 @@ export default async function ProductPage({ params: { handle } }) {
__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>
))}
</>
</>
)}
<PurchaseInput product={product} />
</>
) : (
<p>Product not found</p>

24
components/input.js Normal file
View File

@ -0,0 +1,24 @@
export function Option({ children, ...props }) {
return <option {...props}>{children}</option>;
}
export function Select({ id, label, children, ...props }) {
return (
<div>
<select name={label} id={id} {...props}>
{children}
</select>
{/* TODO: parentheses around label w/ css */}
<label for={id}>{label}</label>
</div>
);
}
export function NumberInput({ id, label, ...props }) {
return (
<div>
<input {...props} type='number' id={id} name={label} />
<label for={id}>{label}</label>
</div>
);
}

View File

@ -0,0 +1,43 @@
'use client';
import { Option, Select, NumberInput } from '/components/input.js';
export default function PurchaseInput({ product }) {
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?.availableForSale &&
isForSale && (
<>
<NumberInput min='1' value='1' id='quantity' label='Qty' />
<>
{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>
))}
</>
</>
)
);
}