Skip to content

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