mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 23:46:58 +00:00
refactoring out variant specific details
This commit is contained in:
parent
5cfc48cdec
commit
4e33afc9dc
@ -1,24 +1,16 @@
|
||||
import { AddToCart } from 'components/cart/add-to-cart';
|
||||
import Price from 'components/price';
|
||||
import { Product } from 'lib/shopify/types';
|
||||
import { DescriptionContent } from './description-content';
|
||||
import { SustainabilityInfo } from './sustainability-info';
|
||||
import { VariantSelector } from './variant-selector';
|
||||
import { VariantDetails } from './variant-details';
|
||||
|
||||
export function ProductDescription({ product }: { product: Product }) {
|
||||
const filterDeterminedOptions = product.options.filter(option => option.name !== 'Wrap')
|
||||
return (
|
||||
<>
|
||||
<div className="mb-6 flex flex-col border-b pb-6 dark:border-neutral-700">
|
||||
<div className="flex flex-col">
|
||||
<h1 className="mb-2 text-2xl md:text-3xl font-medium">{product.title}</h1>
|
||||
<div className="place-self-end mr-auto w-auto rounded-full bg-gray-600 p-2 text-sm text-white">
|
||||
<Price
|
||||
amount={product.priceRange.maxVariantPrice.amount}
|
||||
currencyCode={product.priceRange.maxVariantPrice.currencyCode}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<VariantSelector options={filterDeterminedOptions} variants={product.variants} />
|
||||
<VariantDetails product={product} />
|
||||
<AddToCart variants={product.variants} availableForSale={product.availableForSale} />
|
||||
|
||||
<DescriptionContent product={product} />
|
||||
|
26
components/product/variant-details.tsx
Normal file
26
components/product/variant-details.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
'use client'
|
||||
|
||||
import Price from "components/price";
|
||||
import { Product } from "lib/shopify/types";
|
||||
import { useState } from "react";
|
||||
import { VariantSelector } from "./variant-selector";
|
||||
|
||||
export function VariantDetails({ product }: { product: Product }) {
|
||||
const filterDeterminedOptions = product.options.filter(option => option.name !== 'Wrap');
|
||||
const [selectedVariant, setSelectedVariant] = useState(product.variants[0]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='flex flex-col border-b mb-6 dark:border-neutral-700'>
|
||||
<div className="place-self-end mr-auto w-auto rounded-full bg-gray-600 p-2 text-sm text-white mb-6">
|
||||
<Price
|
||||
amount={selectedVariant?.price.amount || product.variants[0]!.price.amount}
|
||||
currencyCode={product.priceRange.maxVariantPrice.currencyCode}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<VariantSelector options={filterDeterminedOptions} variants={product.variants} setSelectedVariant={setSelectedVariant} />
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import { ProductOption, ProductVariant } from 'lib/shopify/types';
|
||||
import { Money, ProductOption, ProductVariant } from 'lib/shopify/types';
|
||||
import { createUrl } from 'lib/utils';
|
||||
import Link from 'next/link';
|
||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
type ParamsMap = {
|
||||
[key: string]: string; // ie. { color: 'Red', size: 'Large', ... }
|
||||
@ -14,15 +15,18 @@ type OptimizedVariant = {
|
||||
id: string;
|
||||
availableForSale: boolean;
|
||||
params: URLSearchParams;
|
||||
[key: string]: string | boolean | URLSearchParams; // ie. { color: 'Red', size: 'Large', ... }
|
||||
price: Money;
|
||||
[key: string]: string | boolean | URLSearchParams | Money; // ie. { color: 'Red', size: 'Large', ... }
|
||||
};
|
||||
|
||||
export function VariantSelector({
|
||||
options,
|
||||
variants
|
||||
variants,
|
||||
setSelectedVariant,
|
||||
}: {
|
||||
options: ProductOption[];
|
||||
variants: ProductVariant[];
|
||||
setSelectedVariant: (newVariant: ProductVariant) => void,
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const currentParams = useSearchParams();
|
||||
@ -46,7 +50,8 @@ export function VariantSelector({
|
||||
const optimized: OptimizedVariant = {
|
||||
id: variant.id,
|
||||
availableForSale: variant.availableForSale,
|
||||
params: new URLSearchParams()
|
||||
params: new URLSearchParams(),
|
||||
price: variant.price,
|
||||
};
|
||||
|
||||
variant.selectedOptions.forEach((selectedOption) => {
|
||||
@ -79,6 +84,10 @@ export function VariantSelector({
|
||||
const currentUrl = createUrl(pathname, currentParams);
|
||||
const selectedVariantUrl = createUrl(pathname, selectedVariantParams);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedVariant(selectedVariant);
|
||||
}, [selectedVariantUrl]);
|
||||
|
||||
if (currentUrl !== selectedVariantUrl) {
|
||||
router.replace(selectedVariantUrl);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user