ProductInformationSection
Section for displaying product information
Code
"use client"
import { RadioGroup } from "@headlessui/react"
import { Heart } from "@phosphor-icons/react"
import { useState } from "react"
import type { SampleProduct } from "../../helpers"
import { classNames, sampleProduct } from "../../helpers"
const ProductInformationSection = ({ product }: { product: SampleProduct }) => {
const [selectedColor, setSelectedColor] = useState(sampleProduct.colors[0])
const [selectedSize, setSelectedSize] = useState(sampleProduct.sizes[2])
const addProduct = () => null
return (
<div className="flex flex-col">
<div className="flex justify-between">
<h1 className="text-4xl font-bold text-gray-800">{product.name}</h1>
<p className="text-2xl text-gray-900">€{product.priceInclTax?.amount}</p>
</div>
<div className="mt-6">
<div className="flex items-center">
<div className="flex items-center">
<span className="text-red-600">
<Heart size={32} weight="fill" />
</span>
<span className="text-red-600">
<Heart size={32} weight="fill" />
</span>
<span className="text-red-600">
<Heart size={32} weight="fill" />
</span>
<span className="text-red-600">
<Heart size={32} />
</span>
<span className="text-red-600">
<Heart size={32} />
</span>
</div>
<p className="sr-only">{sampleProduct.reviews.average} out of 5 stars</p>
<a href={sampleProduct.reviews.href} className="ml-3 text-sm font-medium text-blue-600 hover:text-blue-500">
{sampleProduct.reviews.totalCount} reviews
</a>
</div>
<form className="mt-10">
<div>
<h3 className="text-sm font-medium text-gray-800">Color</h3>
<RadioGroup value={selectedColor} onChange={setSelectedColor} className="mt-4">
<RadioGroup.Label className="sr-only">Choose a color</RadioGroup.Label>
<div className="flex items-center space-x-4">
{sampleProduct.colors.map((color: any) => (
<RadioGroup.Option
key={color.name}
value={color}
className={({ active, checked }) =>
classNames(
color.selectedClass,
active && checked ? "ring ring-offset-1" : "",
!active && checked ? "ring-2" : "",
"relative -m-0.5 flex cursor-pointer items-center justify-center rounded-full p-0.5 focus:outline-none",
)
}
>
<RadioGroup.Label as="span" className="sr-only">
{color.name}
</RadioGroup.Label>
<span aria-hidden="true" className={classNames(color.class, "h-8 w-8 rounded-full border border-black border-opacity-10")} />
</RadioGroup.Option>
))}
</div>
</RadioGroup>
</div>
<div className="mt-10">
<div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-gray-900">Size</h3>
<a href="/" className="text-sm font-medium text-blue-600 hover:text-blue-500">
Size guide
</a>
</div>
<RadioGroup value={selectedSize} onChange={setSelectedSize} className="mt-4">
<RadioGroup.Label className="sr-only">Choose a size</RadioGroup.Label>
<div className="grid grid-cols-4 gap-4 sm:grid-cols-8 lg:grid-cols-4">
{sampleProduct.sizes.map((size: any) => (
<RadioGroup.Option
key={size.name}
value={size}
disabled={!size.inStock}
className={({ active }) =>
classNames(
size.inStock ? "cursor-pointer bg-white text-gray-900 shadow-sm" : "cursor-not-allowed bg-gray-50 text-gray-200",
active ? "ring-2 ring-blue-500" : "",
"group relative flex items-center justify-center rounded-md border py-3 px-4 text-sm font-medium uppercase hover:bg-gray-50 focus:outline-none sm:flex-1 sm:py-6",
)
}
>
{({ active, checked }) => (
<>
<RadioGroup.Label as="span">{size.name}</RadioGroup.Label>
{size.inStock ? (
<span
className={classNames(
active ? "border" : "border-2",
checked ? "border-indigo-500" : "border-transparent",
"pointer-events-none absolute -inset-px rounded-md",
)}
aria-hidden="true"
/>
) : (
<span aria-hidden="true" className="pointer-events-none absolute -inset-px rounded-md border-2 border-gray-200">
{/* rome-ignore lint/a11y/noSvgWithoutTitle: <explanation> */}
<svg
className="absolute inset-0 h-full w-full stroke-2 text-gray-200"
viewBox="0 0 100 100"
preserveAspectRatio="none"
stroke="currentColor"
>
<line x1={0} y1={100} x2={100} y2={0} vectorEffect="non-scaling-stroke" />
</svg>
</span>
)}
</>
)}
</RadioGroup.Option>
))}
</div>
</RadioGroup>
</div>
<button
className="mt-10 flex w-full items-center justify-center rounded-md border border-transparent bg-blue-600 px-8 py-3 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
onClick={() => addProduct()}
type="button"
>
Add to bag
</button>
</form>
</div>
<div className="py-8">
<div>
<div className="space-y-6">
<p className="text-base text-gray-900">{product.description}</p>
</div>
</div>
<div className="mt-10">
<h3 className="text-sm font-medium text-gray-800">Highlights</h3>
<div className="mt-4">
<ul className="list-disc space-y-2 pl-4 text-sm">
{sampleProduct.highlights.map((highlight: any) => (
<li key={highlight} className="text-gray-400">
<span className="text-gray-600">{highlight}</span>
</li>
))}
</ul>
</div>
</div>
<div className="mt-10">
<h2 className="text-sm font-medium text-gray-800">Details</h2>
<div className="mt-4 space-y-6">
<p className="text-sm text-gray-600">{sampleProduct.details}</p>
</div>
</div>
</div>
</div>
)
}
export default ProductInformationSection