This commit is contained in:
2025-11-25 16:26:54 -05:00
commit 1c07310c44
114 changed files with 17175 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
"use client";
import Link from "next/link";
import type { Category, Part } from "@/types/gunbuilder";
import { PartCard } from "@/components/PartCard";
interface CategoryColumnProps {
category: Category;
parts: Part[];
selectedPartId?: string;
onSelectPart: (partId: string) => void;
}
export function CategoryColumn({
category,
parts,
selectedPartId,
onSelectPart,
}: CategoryColumnProps) {
// Show selected part if available, otherwise show first part
const displayedPart = selectedPartId
? parts.find((p) => p.id === selectedPartId) || parts[0]
: parts[0];
return (
<div className="flex flex-col h-full">
<div className="mb-3">
<h2 className="text-xs font-semibold tracking-[0.15em] text-zinc-400 uppercase">
{category.name}
</h2>
</div>
<div className="flex-1 overflow-y-auto pr-1">
{parts.length === 0 && (
<p className="text-xs text-zinc-500">No parts yet for this category.</p>
)}
{displayedPart && (
<PartCard
key={displayedPart.id}
part={displayedPart}
selected={displayedPart.id === selectedPartId}
onSelect={() => onSelectPart(displayedPart.id)}
/>
)}
</div>
{parts.length > 1 && (
<Link
href={`/gunbuilder/${category.id}`}
className="mt-2 w-full rounded-md border border-zinc-700 bg-zinc-900/50 px-3 py-2 text-xs font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors text-center"
>
View All ({parts.length})
</Link>
)}
</div>
);
}
+40
View File
@@ -0,0 +1,40 @@
"use client";
import type { Part } from "@/types/gunbuilder";
interface PartCardProps {
part: Part;
selected?: boolean;
onSelect: () => void;
}
export function PartCard({ part, selected, onSelect }: PartCardProps) {
return (
<button
type="button"
onClick={onSelect}
className={`w-full text-left border rounded-md p-3 mb-2 transition
${
selected
? "border-amber-400 bg-zinc-900"
: "border-zinc-700 hover:border-zinc-500"
}`}
>
<div className="flex justify-between items-center gap-2">
<div>
<div className="text-sm font-semibold text-zinc-50">
{part.brand} <span className="font-normal"> {part.name}</span>
</div>
{part.notes && (
<p className="mt-1 text-xs text-zinc-400 line-clamp-2">
{part.notes}
</p>
)}
</div>
<div className="text-sm font-semibold text-amber-300 whitespace-nowrap">
${part.price.toFixed(2)}
</div>
</div>
</button>
);
}