iWeb / src /pages /Product.jsx
ronylu's picture
Upload 4 files
851da48 verified
Raw
History Blame Contribute Delete
4.89 kB
import React from "react";
import { Link, useParams } from "react-router-dom";
import { getProduct } from "../data/products.js";
function SpecRow({ label, value }) {
return (
<div className="flex items-center justify-between gap-6 border-b border-neutral-200 py-3 text-sm">
<span className="text-neutral-600">{label}</span>
<span className="font-medium text-neutral-900">{value}</span>
</div>
);
}
export default function Product() {
const { slug } = useParams();
const p = getProduct(slug);
if (!p) {
return (
<div className="rounded-3xl border border-neutral-200 bg-white p-8">
<h2 className="text-2xl font-semibold">Product not found</h2>
<p className="pt-2 text-neutral-600">The product you’re looking for doesn’t exist.</p>
<Link to="/store" className="mt-6 inline-block rounded-full bg-neutral-900 px-5 py-2.5 text-sm font-semibold text-white">
Back to Store
</Link>
</div>
);
}
return (
<div className="space-y-10">
<div className="flex items-center justify-between">
<Link to="/store" className="text-sm font-semibold text-neutral-700 hover:text-neutral-900">
← Back to Store
</Link>
<p className="text-sm text-neutral-500">From ${p.priceFrom}</p>
</div>
<section className="grid gap-8 md:grid-cols-2 md:items-start">
<div className="space-y-4">
<p className="text-xs font-semibold uppercase tracking-wider text-neutral-500">{p.category}</p>
<h1 className="text-4xl font-semibold tracking-tight">{p.name}</h1>
<p className="text-lg text-neutral-600">{p.tagline}</p>
<div className="flex flex-wrap gap-3 pt-2">
<button className="rounded-full bg-neutral-900 px-5 py-2.5 text-sm font-semibold text-white hover:bg-neutral-800">
Buy (demo)
</button>
<a
className="rounded-full border border-neutral-300 bg-white px-5 py-2.5 text-sm font-semibold text-neutral-900 hover:bg-neutral-50"
href="https://www.apple.com/"
target="_blank"
rel="noreferrer"
>
Compare on official site
</a>
</div>
<div className="pt-6">
<h3 className="text-base font-semibold">Highlights</h3>
<ul className="mt-3 list-disc space-y-2 pl-5 text-sm text-neutral-700">
{p.highlights.map((h, idx) => (
<li key={idx}>{h}</li>
))}
</ul>
</div>
</div>
<div className="space-y-4">
<div className="overflow-hidden rounded-3xl border border-neutral-200">
<img src={p.heroImage} alt={p.name} className="w-full object-cover" loading="lazy" />
</div>
<div className="grid grid-cols-2 gap-3">
{p.gallery.map((src, idx) => (
<div key={idx} className="overflow-hidden rounded-2xl border border-neutral-200">
<img src={src} alt={`${p.name} ${idx + 1}`} className="h-32 w-full object-cover" loading="lazy" />
</div>
))}
</div>
</div>
</section>
<section className="grid gap-6 md:grid-cols-2">
<div className="rounded-3xl border border-neutral-200 bg-white p-6">
<h3 className="text-base font-semibold">Specifications</h3>
<div className="mt-3">
{Object.entries(p.specs).map(([k, v]) => (
<SpecRow key={k} label={k.toUpperCase()} value={v} />
))}
</div>
<p className="pt-4 text-xs text-neutral-500">
Replace these sample specs with your own data or data you’re licensed to publish.
</p>
</div>
<div className="rounded-3xl border border-neutral-200 bg-white p-6">
<h3 className="text-base font-semibold">Video</h3>
<p className="pt-2 text-sm text-neutral-600">
Embedded video (YouTube). Use official videos or content you have rights to.
</p>
<div className="mt-4 aspect-video overflow-hidden rounded-2xl border border-neutral-200">
<iframe
className="h-full w-full"
src={`https://www.youtube.com/embed/${p.youtubeId}`}
title="Product video"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
/>
</div>
</div>
</section>
<section className="rounded-3xl border border-neutral-200 bg-neutral-50 p-6 text-sm text-neutral-700">
<b>Note:</b> This is an original demo UI inspired by modern ecommerce layouts.
Do not copy Apple’s site design or use Apple’s copyrighted assets without permission.
</section>
</div>
);
}