| import React, { useMemo, useState } from "react"; |
| import { Link } from "react-router-dom"; |
| import { products } from "../data/products.js"; |
|
|
| export default function Store() { |
| const [q, setQ] = useState(""); |
|
|
| const filtered = useMemo(() => { |
| const term = q.trim().toLowerCase(); |
| if (!term) return products; |
| return products.filter((p) => |
| [p.name, p.category, p.tagline].some((x) => x.toLowerCase().includes(term)) |
| ); |
| }, [q]); |
|
|
| return ( |
| <div className="space-y-6"> |
| <div className="flex flex-col gap-3 md:flex-row md:items-end md:justify-between"> |
| <div> |
| <h2 className="text-3xl font-semibold tracking-tight">Store</h2> |
| <p className="text-neutral-600">Browse products (demo data).</p> |
| </div> |
| <div className="w-full md:w-80"> |
| <label className="text-xs font-semibold uppercase tracking-wider text-neutral-500">Search</label> |
| <input |
| value={q} |
| onChange={(e) => setQ(e.target.value)} |
| placeholder="Search products..." |
| className="mt-2 w-full rounded-xl border border-neutral-300 bg-white px-4 py-2.5 text-sm outline-none focus:border-neutral-900" |
| /> |
| </div> |
| </div> |
| |
| <div className="grid gap-4 md:grid-cols-3"> |
| {filtered.map((p) => ( |
| <Link |
| key={p.slug} |
| to={`/product/${p.slug}`} |
| className="group rounded-3xl border border-neutral-200 bg-white p-5 hover:shadow-sm" |
| > |
| <div className="overflow-hidden rounded-2xl border border-neutral-200"> |
| <img |
| src={p.heroImage} |
| alt={p.name} |
| className="h-44 w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]" |
| loading="lazy" |
| /> |
| </div> |
| <div className="pt-4"> |
| <p className="text-xs font-semibold uppercase tracking-wider text-neutral-500">{p.category}</p> |
| <h3 className="pt-1 text-lg font-semibold tracking-tight">{p.name}</h3> |
| <p className="pt-1 text-sm text-neutral-600">{p.tagline}</p> |
| <p className="pt-3 text-sm font-semibold text-neutral-900">From ${p.priceFrom}</p> |
| </div> |
| </Link> |
| ))} |
| </div> |
| |
| {filtered.length === 0 ? ( |
| <div className="rounded-2xl border border-neutral-200 bg-neutral-50 p-6 text-neutral-700"> |
| No results. Try a different search term. |
| </div> |
| ) : null} |
| </div> |
| ); |
| } |
|
|