feat(web): vehicle detail — empty-categories state, equipment show-more, mobile header
- Render a composed "no categories found" panel when the category tree resolves to an empty array, so vehicles without a catalog stop showing a silent void under "Yedek Parça Kategorileri". - Collapse the equipment list to the first 8 codes by default with a "Tümünü göster (N)" toggle instead of a sub-scrollarea — friendlier on mobile, no card-in-card scroll. - Loosen the header flex layout: the title block gets `min-w-0 flex-1` with break-words and a truncated VIN line so long brand+model strings no longer crush the layout on narrow screens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -193,21 +193,20 @@ function VehicleDetailPage() {
|
||||
onClick={handleBack}
|
||||
title="Geri dön"
|
||||
aria-label="Geri dön"
|
||||
className="shrink-0"
|
||||
data-faro-user-action-name="vehicle-back"
|
||||
>
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
</Button>
|
||||
<div className="flex items-center gap-3">
|
||||
{vehicle?.brandName && (
|
||||
<CarBrandLogo brandName={vehicle.brandName} size={32} className="shrink-0" />
|
||||
)}
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold">
|
||||
{vehicle?.brandName} {cleanModelName(vehicle?.model)}{" "}
|
||||
{vehicle?.year && `(${vehicle.year})`}
|
||||
</h2>
|
||||
<p className="font-mono text-sm text-muted-foreground">{vehicle?.vin}</p>
|
||||
</div>
|
||||
{vehicle?.brandName && (
|
||||
<CarBrandLogo brandName={vehicle.brandName} size={32} className="shrink-0" />
|
||||
)}
|
||||
<div className="min-w-0 flex-1">
|
||||
<h2 className="break-words text-2xl font-bold leading-tight">
|
||||
{vehicle?.brandName} {cleanModelName(vehicle?.model)}{" "}
|
||||
{vehicle?.year && `(${vehicle.year})`}
|
||||
</h2>
|
||||
<p className="truncate font-mono text-sm text-muted-foreground">{vehicle?.vin}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -253,12 +252,22 @@ function VehicleDetailPage() {
|
||||
<Skeleton key={__k} className="h-8 w-full" />
|
||||
))}
|
||||
</div>
|
||||
) : !categoryTree || categoryTree.length === 0 ? (
|
||||
<div className="rounded-lg border border-dashed border-border bg-muted/30 px-6 py-10 text-center">
|
||||
<p className="text-sm font-medium text-foreground">
|
||||
Bu araç için kategori bulunamadı
|
||||
</p>
|
||||
<p className="mx-auto mt-1 max-w-md text-xs text-muted-foreground">
|
||||
Araç decode edildi ama parça kataloğu henüz hazırlanmamış olabilir. Destek
|
||||
ekibimize bildirirseniz katalog hızlandırılır.
|
||||
</p>
|
||||
</div>
|
||||
) : viewMode === "grid" ? (
|
||||
<CategoryGrid categories={categoryTree || []} vehicleId={id} hideFilter />
|
||||
<CategoryGrid categories={categoryTree} vehicleId={id} hideFilter />
|
||||
) : viewMode === "tree" ? (
|
||||
<CategoryTree categories={categoryTree || []} vehicleId={id} />
|
||||
<CategoryTree categories={categoryTree} vehicleId={id} />
|
||||
) : (
|
||||
<CategoryColumns categories={categoryTree || []} vehicleId={id} />
|
||||
<CategoryColumns categories={categoryTree} vehicleId={id} />
|
||||
))}
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -525,17 +534,22 @@ function getEquipment(vehicle: any): Equipment[] {
|
||||
}
|
||||
|
||||
/** Full decoded equipment / PR-code list, shown inside the expanded card. */
|
||||
const EQUIPMENT_PREVIEW = 8;
|
||||
function VehicleEquipment({ vehicle }: { vehicle: any }) {
|
||||
const items = getEquipment(vehicle);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
if (items.length === 0) return null;
|
||||
|
||||
const hasMore = items.length > EQUIPMENT_PREVIEW;
|
||||
const visible = expanded || !hasMore ? items : items.slice(0, EQUIPMENT_PREVIEW);
|
||||
|
||||
return (
|
||||
<div className="mt-6 border-t border-border pt-4">
|
||||
<p className="mb-3 text-xs font-semibold text-muted-foreground">
|
||||
Donanım kodları ({items.length})
|
||||
</p>
|
||||
<ul className="grid max-h-80 grid-cols-1 gap-x-6 gap-y-2 overflow-y-auto pr-1 sm:grid-cols-2">
|
||||
{items.map((it, i) => (
|
||||
<ul className="grid grid-cols-1 gap-x-6 gap-y-2 sm:grid-cols-2">
|
||||
{visible.map((it, i) => (
|
||||
<li key={`${it.code}-${i}`} className="flex items-baseline gap-2">
|
||||
{it.code && (
|
||||
<span className="shrink-0 rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] leading-tight text-muted-foreground">
|
||||
@@ -546,6 +560,17 @@ function VehicleEquipment({ vehicle }: { vehicle: any }) {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{hasMore && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setExpanded((v) => !v)}
|
||||
className="mt-3 h-8 px-2 text-xs text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
{expanded ? "Daha az göster" : `Tümünü göster (${items.length})`}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user