fix(catalog): auto-advance variant selectors instead of forcing an extra "Kataloga Git" click
After the user picks the last meaningful dimension, the next step is determined
— there is no decision left to make. Yet the Ford and PSA selectors stopped at
that point and waited for a "Kataloga Git" / "Proceed" button click. For Ford
specifically this was the worst case: LEGACY_FORD's upstream returns no engines
or gearboxes, so picking a year/catCode IS the whole flow — the user had to
click twice for one decision.
Auto-fire onSelect when the last available dimension is filled in:
- **Ford**: when year picked and (!hasEngines && !hasGearboxes); when engine
picked and !hasGearboxes; when gearbox picked. Also: when config returns
empty (no variants at all), fire onSelect("_nor_", "_nor_", "_nor_") via a
one-shot useEffect so the selector skips itself rather than dead-ending on
a "no config" notice with no actionable button.
- **PSA**: when gearbox is picked. Body→engine→gearbox is always 3 steps,
picking gearbox is unambiguous intent. "Show All" buttons already auto-
advanced — this just removes the asymmetry on the explicit-pick path.
Drop the now-dead Proceed button + handleProceed handler in both. P5
restriction selector already auto-advances on `isFinal` and stays untouched.
i18n keys catalog.fordVariant.proceed / catalog.psaVariant.proceed are kept
in case we ever re-introduce a confirmation button.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { api } from "@/lib/api-client";
|
||||
import { useTranslation } from "@/lib/i18n";
|
||||
import { Button, Card, CardContent, CardHeader, CardTitle } from "@sase/ui";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@sase/ui";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
interface VariantItem {
|
||||
code: string;
|
||||
@@ -42,33 +42,42 @@ export function FordVariantSelector({ vehicleId, onSelect }: FordVariantSelector
|
||||
const hasEngines = engines.length > 0;
|
||||
const hasGearboxes = gearboxes.length > 0;
|
||||
|
||||
// Auto-advance: if a selection makes all required dimensions filled in, fire
|
||||
// onSelect immediately instead of asking the user to click an extra button.
|
||||
// For LEGACY_FORD this is almost always after the very first pick because the
|
||||
// upstream returns no engines/gearboxes — one click should go to categories.
|
||||
const handleYearSelect = (code: string) => {
|
||||
setSelectedYear(code);
|
||||
setSelectedEngine(null);
|
||||
setSelectedGearbox(null);
|
||||
if (!hasEngines && !hasGearboxes) {
|
||||
onSelect(code, "_nor_", "_nor_");
|
||||
}
|
||||
};
|
||||
|
||||
const handleEngineSelect = (code: string) => {
|
||||
setSelectedEngine(code);
|
||||
setSelectedGearbox(null);
|
||||
if (!hasGearboxes) {
|
||||
onSelect(selectedYear ?? "_nor_", code, "_nor_");
|
||||
}
|
||||
};
|
||||
|
||||
const handleGearboxSelect = (code: string) => {
|
||||
setSelectedGearbox(code);
|
||||
onSelect(selectedYear ?? "_nor_", selectedEngine ?? "_nor_", code);
|
||||
};
|
||||
|
||||
// No variants at all (config came back empty) — skip the selector outright
|
||||
// instead of forcing the user to click a button that does nothing meaningful.
|
||||
const hasAny = hasYears || hasEngines || hasGearboxes;
|
||||
const canProceed =
|
||||
!hasAny || // No variants available — can always proceed
|
||||
((!hasYears || !!selectedYear) &&
|
||||
(!hasEngines || !!selectedEngine) &&
|
||||
(!hasGearboxes || !!selectedGearbox));
|
||||
|
||||
const handleProceed = () => {
|
||||
if (!canProceed) return;
|
||||
// When no variants, use "_nor_" so hasVariant=true and variant selector is skipped
|
||||
onSelect(selectedYear ?? "_nor_", selectedEngine ?? "_nor_", selectedGearbox ?? "_nor_");
|
||||
};
|
||||
const autoSkipFired = useRef(false);
|
||||
useEffect(() => {
|
||||
if (!isLoading && config && !hasAny && !autoSkipFired.current) {
|
||||
autoSkipFired.current = true;
|
||||
onSelect("_nor_", "_nor_", "_nor_");
|
||||
}
|
||||
}, [isLoading, config, hasAny, onSelect]);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
@@ -152,17 +161,11 @@ export function FordVariantSelector({ vehicleId, onSelect }: FordVariantSelector
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* No config available — allow skipping */}
|
||||
{!hasYears && !hasEngines && !hasGearboxes && (
|
||||
{/* No config available — autoSkip useEffect above will fire
|
||||
onSelect("_nor_",…) shortly; show a brief notice meanwhile. */}
|
||||
{!hasAny && (
|
||||
<p className="text-sm text-muted-foreground">{t("catalog.fordVariant.noConfig")}</p>
|
||||
)}
|
||||
|
||||
{/* Proceed button — only enabled when all required dimensions are selected */}
|
||||
<div className="flex gap-2">
|
||||
<Button onClick={handleProceed} disabled={!canProceed} className="w-full sm:w-auto">
|
||||
{t("catalog.fordVariant.proceed")}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</CardContent>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { api } from "@/lib/api-client";
|
||||
import { useTranslation } from "@/lib/i18n";
|
||||
import { Button, Card, CardContent, CardHeader, CardTitle } from "@sase/ui";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@sase/ui";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
@@ -66,6 +66,9 @@ export function PsaVariantSelector({ vehicleId, onSelect }: PsaVariantSelectorPr
|
||||
setSelectedGearbox(null);
|
||||
};
|
||||
|
||||
// Auto-advance on the final dimension — gearbox is always the last step in
|
||||
// PSA's body→engine→gearbox flow, so picking one is unambiguous intent to
|
||||
// proceed. No reason to make the user click an extra button.
|
||||
const handleGearboxSelect = (code: string | "_all_") => {
|
||||
if (code === "_all_") {
|
||||
if (!selectedBody || !selectedEngine) return;
|
||||
@@ -73,16 +76,11 @@ export function PsaVariantSelector({ vehicleId, onSelect }: PsaVariantSelectorPr
|
||||
return;
|
||||
}
|
||||
setSelectedGearbox(code);
|
||||
};
|
||||
|
||||
const handleProceed = () => {
|
||||
if (selectedBody && selectedEngine && selectedGearbox) {
|
||||
onSelect(selectedBody, selectedEngine, selectedGearbox);
|
||||
if (selectedBody && selectedEngine) {
|
||||
onSelect(selectedBody, selectedEngine, code);
|
||||
}
|
||||
};
|
||||
|
||||
const canProceed = selectedBody && selectedEngine && selectedGearbox;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
@@ -198,13 +196,6 @@ export function PsaVariantSelector({ vehicleId, onSelect }: PsaVariantSelectorPr
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Proceed button */}
|
||||
{canProceed && (
|
||||
<Button onClick={handleProceed} className="w-full sm:w-auto">
|
||||
{t("catalog.psaVariant.proceed")}
|
||||
</Button>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user