basic seach small json data set models and parts
This commit is contained in:
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/bin/zsh
|
||||
|
||||
echo "📘 Creating Models Browser Page..."
|
||||
|
||||
PAGE="src/app/models"
|
||||
COMP="src/app/components"
|
||||
LIB="src/lib/ui"
|
||||
|
||||
mkdir -p "$PAGE"
|
||||
|
||||
#############################################
|
||||
# Create models/page.js
|
||||
#############################################
|
||||
|
||||
cat > "$PAGE/page.js" << 'EOF'
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import ModelCard from "../components/ModelCard";
|
||||
|
||||
export default function ModelsPage() {
|
||||
const [models, setModels] = useState([]);
|
||||
const [filtered, setFiltered] = useState([]);
|
||||
const [brand, setBrand] = useState("all");
|
||||
const [scale, setScale] = useState("all");
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
const res = await fetch("/api/models", { cache: "no-store" });
|
||||
const data = await res.json();
|
||||
setModels(data);
|
||||
setFiltered(data);
|
||||
}
|
||||
load();
|
||||
}, []);
|
||||
|
||||
function filter() {
|
||||
let result = [...models];
|
||||
|
||||
if (brand !== "all") {
|
||||
result = result.filter(m => m.brand === brand);
|
||||
}
|
||||
if (scale !== "all") {
|
||||
result = result.filter(m => m.scale === scale);
|
||||
}
|
||||
|
||||
setFiltered(result);
|
||||
}
|
||||
|
||||
const brands = [...new Set(models.map(m => m.brand))];
|
||||
const scales = [...new Set(models.map(m => m.scale))];
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<h1 className="text-4xl font-bold">All Models</h1>
|
||||
|
||||
{/* Filters */}
|
||||
<div className="flex gap-4 items-end">
|
||||
<div>
|
||||
<label className="block mb-1 font-semibold">Brand</label>
|
||||
<select
|
||||
className="border p-2 rounded"
|
||||
value={brand}
|
||||
onChange={e => setBrand(e.target.value)}
|
||||
>
|
||||
<option value="all">All</option>
|
||||
{brands.map(b => <option key={b} value={b}>{b}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block mb-1 font-semibold">Scale</label>
|
||||
<select
|
||||
className="border p-2 rounded"
|
||||
value={scale}
|
||||
onChange={e => setScale(e.target.value)}
|
||||
>
|
||||
<option value="all">All</option>
|
||||
{scales.map(s => <option key={s} value={s}>{s}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={filter}
|
||||
className="px-4 py-2 bg-primary text-white rounded"
|
||||
>
|
||||
Apply Filters
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Model Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{filtered.map(model => (
|
||||
<a key={model.id} href={`/model/${model.id}`} className="block">
|
||||
<ModelCard model={model} />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "🎉 Models Browser Page created!"
|
||||
Reference in New Issue
Block a user