diff --git a/src/app/(main)/products/[slug]/page.tsx b/src/app/(main)/products/[slug]/page.tsx index 8d6c8798a..0101245b9 100644 --- a/src/app/(main)/products/[slug]/page.tsx +++ b/src/app/(main)/products/[slug]/page.tsx @@ -145,7 +145,9 @@ export default async function Page(props: { params: { slug: string }; searchPara : ""}

- {variants && } + {variants && ( + + )} {description && (
diff --git a/src/graphql/ProductDetails.graphql b/src/graphql/ProductDetails.graphql index 269bfd7e8..376470fb7 100644 --- a/src/graphql/ProductDetails.graphql +++ b/src/graphql/ProductDetails.graphql @@ -15,17 +15,7 @@ query ProductDetails($slug: String!) { name } variants { - id - name - quantityAvailable - pricing { - price { - gross { - currency - amount - } - } - } + ...VariantDetails } } } diff --git a/src/graphql/VariantDetailsFragment.graphql b/src/graphql/VariantDetailsFragment.graphql new file mode 100644 index 000000000..0ee45fd01 --- /dev/null +++ b/src/graphql/VariantDetailsFragment.graphql @@ -0,0 +1,13 @@ +fragment VariantDetails on ProductVariant { + id + name + quantityAvailable + pricing { + price { + gross { + currency + amount + } + } + } +} diff --git a/src/ui/components/VariantSelector.tsx b/src/ui/components/VariantSelector.tsx index 68c0196ab..2c380788d 100644 --- a/src/ui/components/VariantSelector.tsx +++ b/src/ui/components/VariantSelector.tsx @@ -1,45 +1,20 @@ -"use client"; - import { clsx } from "clsx"; -import { usePathname, useRouter, useSearchParams } from "next/navigation"; -import { useCallback, useEffect } from "react"; - -export const createPathname = (pathname: string, params: URLSearchParams) => { - const paramsString = params.toString(); - const queryString = `${paramsString.length ? "?" : ""}${paramsString}`; - - return `${pathname}${queryString}`; -}; - -export function VariantSelector(props: { - variants: { id: string; name: string; quantityAvailable?: number | null }[]; +import Link from "next/link"; +import { redirect } from "next/navigation"; +import { type ProductListItemFragment, type VariantDetailsFragment } from "@/gql/graphql"; + +export function VariantSelector({ + variants, + product, + selectedVariant, +}: { + variants: readonly VariantDetailsFragment[]; + product: ProductListItemFragment; + selectedVariant?: VariantDetailsFragment; }) { - const { variants } = props; - - const router = useRouter(); - const pathname = usePathname(); - const searchParams = useSearchParams(); - - const selectVariant = useCallback( - (variantID: string, replace = false) => { - const params = new URLSearchParams(searchParams); - params.set("variant", variantID); - - const variantPathname = createPathname(pathname, params); - if (replace) { - router.replace(variantPathname, { scroll: false }); - } else { - router.push(variantPathname, { scroll: false }); - } - }, - [pathname, router, searchParams], - ); - - useEffect(() => { - if (variants.length === 1 && variants[0].quantityAvailable) { - selectVariant(variants[0].id, true); - } - }, [selectVariant, variants]); + if (!selectedVariant && variants.length === 1 && variants[0]?.quantityAvailable) { + redirect(getHrefForVariant(product, variants[0])); + } return (
@@ -47,30 +22,35 @@ export function VariantSelector(props: {
{variants.length > 1 && variants.map((variant) => { + const isDisabled = !variant.quantityAvailable; + const isCurrentVariant = selectedVariant?.id === variant.id; return ( - + ); })}
); } + +function getHrefForVariant(product: ProductListItemFragment, variant: VariantDetailsFragment): string { + const pathname = `/products/${encodeURIComponent(product.slug)}`; + const query = new URLSearchParams({ variant: variant.id }); + return `${pathname}?${query.toString()}`; +}