Download src/pages/Store.jsx from ronylu/iWeb: direct link, hf CLI and curl.
- Browser
- Download file 2.54 kB
-
https://huggingface.co/spaces/ronylu/iWeb/resolve/main/src/pages/Store.jsx
- Command line
-
hf download hf://spaces/ronylu/iWeb/src/pages/Store.jsx
-
curl -L -o Store.jsx https://huggingface.co/spaces/ronylu/iWeb/resolve/main/src/pages/Store.jsx
2.54 kB
| 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> | |
| ); | |
| } | |