157 lines
4.5 KiB
Bash
Executable File
157 lines
4.5 KiB
Bash
Executable File
#!/bin/zsh
|
|
|
|
echo "🎨 Applying UI polish across the app..."
|
|
|
|
BASE="src/app"
|
|
COMP="src/app/components"
|
|
|
|
mkdir -p "$COMP"
|
|
|
|
#############################################
|
|
# CategoryCard component
|
|
#############################################
|
|
|
|
cat > "$COMP/CategoryCard.js" << 'EOF'
|
|
export default function CategoryCard({ category }) {
|
|
return (
|
|
<div className="border rounded p-4 shadow hover:shadow-lg transition cursor-pointer bg-white">
|
|
<h3 className="font-bold text-lg capitalize">{category}</h3>
|
|
</div>
|
|
);
|
|
}
|
|
EOF
|
|
|
|
#############################################
|
|
# Patch ModelPage
|
|
#############################################
|
|
|
|
cat > "$BASE/model/[modelId]/page.js" << 'EOF'
|
|
import { getModel, getCompatibleParts } from "@/src/lib/ui/api";
|
|
import CategoryCard from "@/src/app/components/CategoryCard";
|
|
import PartCard from "@/src/app/components/PartCard";
|
|
|
|
export default async function ModelPage({ params }) {
|
|
const model = await getModel(params.modelId);
|
|
const parts = await getCompatibleParts(params.modelId);
|
|
|
|
if (!model) return <p className="text-red-500">Model not found</p>;
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<h1 className="text-4xl font-bold">{model.name}</h1>
|
|
<p className="opacity-75">{model.brand} • {model.scale}</p>
|
|
</div>
|
|
|
|
<h2 className="text-2xl font-bold">Categories</h2>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
{model.categories.map(cat => (
|
|
<a key={cat} href={`/category/${model.id}/${cat}`}>
|
|
<CategoryCard category={cat} />
|
|
</a>
|
|
))}
|
|
</div>
|
|
|
|
<h2 className="text-2xl font-bold">Compatible Parts</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
{Array.isArray(parts) && parts.length ? (
|
|
parts.map(item => <PartCard key={item.part.id} part={item.part} />)
|
|
) : (
|
|
<p>No compatible parts found.</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
EOF
|
|
|
|
#############################################
|
|
# Patch PartPage
|
|
#############################################
|
|
|
|
cat > "$BASE/part/[partId]/page.js" << 'EOF'
|
|
import { getPart, getCompatibleModels } from "@/src/lib/ui/api";
|
|
import ModelCard from "@/src/app/components/ModelCard";
|
|
|
|
export default async function PartDetailPage({ params }) {
|
|
const part = await getPart(params.partId);
|
|
const models = await getCompatibleModels(params.partId);
|
|
|
|
if (!part) return <p className="text-red-500">Part not found</p>;
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<h1 className="text-4xl font-bold">{part.name}</h1>
|
|
<p className="opacity-75">Part ID: {part.id}</p>
|
|
|
|
{part.universalFit && (
|
|
<span className="inline-block mt-2 px-3 py-1 bg-green-200 text-green-800 text-sm rounded">
|
|
Universal Fit
|
|
</span>
|
|
)}
|
|
|
|
{part.upgrade && (
|
|
<span className="inline-block mt-2 px-3 py-1 bg-blue-200 text-blue-800 text-sm rounded">
|
|
Upgrade Part
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
<h2 className="text-2xl font-bold">Compatible Models</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
{Array.isArray(models) && models.length ? (
|
|
models.map(item => <ModelCard key={item.model.id} model={item.model} />)
|
|
) : (
|
|
<p>No compatible models found.</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
EOF
|
|
|
|
#############################################
|
|
# Patch CategoryPage
|
|
#############################################
|
|
|
|
cat > "$BASE/category/[modelId]/[categoryName]/page.js" << 'EOF'
|
|
import { getModel, getCompatibleParts } from "@/src/lib/ui/api";
|
|
import PartCard from "@/src/app/components/PartCard";
|
|
|
|
export default async function CategoryPage({ params }) {
|
|
const model = await getModel(params.modelId);
|
|
const allParts = await getCompatibleParts(params.modelId);
|
|
|
|
if (!model) return <p className="text-red-500">Model not found</p>;
|
|
|
|
const parts = allParts.filter(
|
|
p => p.part.category === params.categoryName
|
|
);
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h1 className="text-3xl font-bold capitalize">
|
|
{params.categoryName} for {model.name}
|
|
</h1>
|
|
|
|
<a href={`/model/${model.id}`} className="text-blue-600 underline">
|
|
← Back to model
|
|
</a>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
{parts.length ? (
|
|
parts.map(p => (
|
|
<PartCard key={p.part.id} part={p.part} />
|
|
))
|
|
) : (
|
|
<p>No compatible parts in this category.</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
EOF
|
|
|
|
echo "🎉 UI polish applied!"
|