feat: Zaktualizuj sekcję hero, nawigację, kalkulator i formularz zgłoszenia awarii

This commit is contained in:
MichalC
2026-06-28 15:03:36 +02:00
parent 002a325dfb
commit 59808f1243
22 changed files with 1465 additions and 345 deletions
+313 -90
View File
@@ -38,33 +38,49 @@ function estimateInstall(pipes: string, rooms: number): { min: number; max: numb
return { min: base + pipeExtra, max: base + pipeExtra + 600 };
}
const STEPS = ['Pomieszczenie', 'Konfiguracja', 'Instalacja', 'Budżet'] as const;
const STEPS = ['Typ', 'Pomieszczenie', 'Konfiguracja', 'Instalacja', 'Budżet'] as const;
export function KalkulatorClient({ products }: Props) {
const [deviceType, setDeviceType] = useState<'klimatyzacja' | 'pompa'>('klimatyzacja');
const [pumpFormSent, setPumpFormSent] = useState(false);
const [pumpForm, setPumpForm] = useState({ name: '', phone: '', city: '', message: '' });
const [step, setStep] = useState(0);
const [building, setBuilding] = useState('apartment');
const [m2, setM2] = useState(25);
const [floor, setFloor] = useState('middle'); // ground | middle | top
const [sun, setSun] = useState('south'); // north | east | south | west
const [systemType, setSystemType] = useState<'auto' | 'scienne' | 'multisplit'>('auto');
const [rooms, setRooms] = useState(1);
const [pipes, setPipes] = useState('medium'); // short(<3m) | medium(3-6m) | long(6-10m) | verylong(>10m)
const [budget, setBudget] = useState(8000);
const [showResults, setShowResults] = useState(false);
const [preferredBrand, setPreferredBrand] = useState('');
const requiredPower = useMemo(() => calculatePower(m2, floor, sun, building), [m2, floor, sun, building]);
const installCost = useMemo(() => estimateInstall(pipes, rooms), [pipes, rooms]);
const category = rooms === 1 ? 'scienne' : 'multisplit';
const category = systemType === 'auto' ? (rooms === 1 ? 'scienne' : 'multisplit') : systemType;
const results = useMemo(() => {
if (!showResults) return [];
const powerMin = requiredPower * 0.8;
const powerMax = requiredPower * 1.4;
const maxPrice = budget - installCost.min;
if (!showResults || deviceType === 'pompa') return [];
const maxPrice = budget * 0.75;
const powerMin = requiredPower * 0.6;
const powerMax = requiredPower * 1.8;
return products
const filtered = products
.filter(p => {
if (p.category !== category) return false;
if (p.price === null || p.price > maxPrice) return false;
if (preferredBrand && p.brand !== preferredBrand) return false;
if (category === 'multisplit') {
if (p.price !== null && p.price > maxPrice) return false;
} else {
if (p.price === null || p.price > maxPrice) return false;
}
const moc = parseFloat(String(p.specs?.['Moc chłodnicza'] || '0').replace(',', '.').split('–')[0]);
return moc >= powerMin && moc <= powerMax;
})
@@ -73,14 +89,58 @@ export function KalkulatorClient({ products }: Props) {
const mocA = parseFloat(String(a.specs?.['Moc chłodnicza'] || '0').replace(',', '.').split('–')[0]);
const mocB = parseFloat(String(b.specs?.['Moc chłodnicza'] || '0').replace(',', '.').split('–')[0]);
return Math.abs(mocA - requiredPower) - Math.abs(mocB - requiredPower);
})
.slice(0, 6);
}, [showResults, products, requiredPower, category, budget, installCost.min]);
});
return filtered.length > 0
? filtered.slice(0, 6)
: products
.filter(p => p.category === category && p.price !== null)
.sort((a, b) => (a.price || 0) - (b.price || 0))
.slice(0, 6);
}, [showResults, deviceType, products, requiredPower, category, budget, preferredBrand]);
const handleFinish = () => setShowResults(true);
const handleReset = () => { setShowResults(false); setStep(0); };
const handleNext = () => {
setStep(s => s + 1);
};
const handlePumpSubmit = async () => {
if (!pumpForm.name || !pumpForm.phone || !pumpForm.city) return;
// Na razie pokazujemy success — podepniemy Resend później
setPumpFormSent(true);
};
if (showResults) {
if (deviceType === 'pompa') {
return (
<main className="bg-slate-50 min-h-screen py-12">
<div className="max-w-3xl mx-auto px-4 text-center">
<div className="bg-white rounded-2xl border border-border p-12">
<h1 className="text-3xl font-extrabold text-primary font-heading mb-4">
Wycena pompy ciepła
</h1>
<p className="text-text-muted mb-8 text-lg">
Każda instalacja pompy ciepła wymaga indywidualnego doboru urządzenia do specyfiki budynku (izolacja, instalacja grzewcza).
Skontaktuj się z nami, a przygotujemy dla Ciebie <strong>bezpłatną, spersonalizowaną ofertę</strong>.
</p>
<a href={`tel:${companyDetails.phoneRaw}`}>
<button className="flex items-center gap-2 px-8 py-4 bg-accent text-white rounded-xl font-bold mx-auto hover:bg-accent/90 transition-colors text-lg">
<Phone className="size-5" /> {companyDetails.phone}
</button>
</a>
<div className="mt-8">
<button onClick={handleReset} className="flex items-center gap-2 px-5 py-3 border border-border rounded-xl text-sm font-semibold text-primary hover:border-accent transition-colors mx-auto">
<RotateCcw className="size-4" /> Zacznij od nowa
</button>
</div>
</div>
</div>
</main>
);
}
return (
<main className="bg-slate-50 min-h-screen py-12">
<div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
@@ -93,7 +153,7 @@ export function KalkulatorClient({ products }: Props) {
{[
{ label: 'Wymagana moc', value: `${requiredPower} kW` },
{ label: 'Powierzchnia', value: `${m2} m²` },
{ label: 'Typ instalacji', value: rooms === 1 ? 'Split (1 pokój)' : `Multisplit (${rooms} pokoje)` },
{ label: 'Typ instalacji', value: category === 'scienne' ? 'Split (1 pokój)' : `Multisplit (${rooms} pokoje)` },
{ label: 'Szac. montaż', value: `${installCost.min.toLocaleString('pl-PL')}–${installCost.max.toLocaleString('pl-PL')} zł` },
].map((s, i) => (
<div key={i} className="bg-slate-50 rounded-xl p-3">
@@ -106,55 +166,69 @@ export function KalkulatorClient({ products }: Props) {
{results.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5">
{results.map(product => (
<div key={product.slug} className="bg-white rounded-2xl border border-border overflow-hidden hover:border-accent hover:shadow-md transition-all">
<div className="relative aspect-[4/3] bg-slate-50">
<Image
src={product.image}
alt={product.name}
fill
className="object-contain p-6"
unoptimized={product.image.startsWith('http')}
/>
{product.specs?.['Klasa energetyczna'] && (
<span className="absolute top-2 left-2 px-2 py-0.5 bg-green-500 text-white text-xs font-bold rounded">
{product.specs['Klasa energetyczna'].split('/')[0]}
</span>
)}
</div>
<div className="p-4">
<p className="text-xs text-accent font-bold uppercase mb-1">{product.brand}</p>
<h3 className="text-sm font-bold text-primary font-heading leading-snug mb-3 line-clamp-2">
{product.name}
</h3>
<div className="flex flex-wrap gap-1.5 mb-3">
{product.specs?.['Moc chłodnicza'] && (
<span className="px-2 py-0.5 bg-blue-50 text-blue-700 text-xs rounded border border-blue-100">
{product.specs['Moc chłodnicza']} kW
</span>
)}
{product.specs?.['Hałas wewnątrz (dB)'] && (
<span className="px-2 py-0.5 bg-slate-50 text-text-muted text-xs rounded border border-border">
{product.specs['Hałas wewnątrz (dB)']} dB
{results.map(product => {
const mocChlodnicza = parseFloat(
String(product.specs?.['Moc chłodnicza'] || '0').replace(',', '.').split('–')[0]
);
const seer = mocChlodnicza > 0 ? mocChlodnicza / (mocChlodnicza * 0.5) : 5;
const pobor = mocChlodnicza / 5; // szacowany pobór przy SEER~5
const zuzycieMiesiac = (pobor * 8 * 30).toFixed(0); // 8h/dzień 30 dni
return (
<div key={product.slug} className="bg-white rounded-2xl border border-border overflow-hidden hover:border-accent hover:shadow-md transition-all">
<div className="relative aspect-[4/3] bg-slate-50">
<Image
src={product.image}
alt={product.name}
fill
className="object-contain p-6"
unoptimized={product.image.startsWith('http')}
/>
{product.specs?.['Klasa energetyczna'] && (
<span className="absolute top-2 left-2 px-2 py-0.5 bg-green-500 text-white text-xs font-bold rounded">
{product.specs['Klasa energetyczna'].split('/')[0]}
</span>
)}
</div>
<div className="flex items-end justify-between">
<div>
<p className="text-lg font-extrabold text-primary font-heading leading-none">
{product.price?.toLocaleString('pl-PL')} zł
</p>
<p className="text-xs text-text-muted mt-0.5">+ montaż od {installCost.min.toLocaleString('pl-PL')} zł</p>
<div className="p-4 flex flex-col h-full">
<p className="text-xs text-accent font-bold uppercase mb-1">{product.brand}</p>
<h3 className="text-sm font-bold text-primary font-heading leading-snug mb-3 line-clamp-2">
{product.name}
</h3>
<div className="flex flex-wrap gap-1.5 mb-1">
{product.specs?.['Moc chłodnicza'] && (
<span className="px-2 py-0.5 bg-blue-50 text-blue-700 text-xs rounded border border-blue-100">
{product.specs['Moc chłodnicza']} kW
</span>
)}
{product.specs?.['Hałas wewnątrz (dB)'] && (
<span className="px-2 py-0.5 bg-slate-50 text-text-muted text-xs rounded border border-border">
{product.specs['Hałas wewnątrz (dB)']} dB
</span>
)}
</div>
<p className="text-xs text-text-muted mt-1 mb-4">
~{zuzycieMiesiac} kWh/miesiąc (8h/dzień)
</p>
<div className="flex items-end justify-between mt-auto">
<div>
<p className="text-lg font-extrabold text-primary font-heading leading-none">
{product.price?.toLocaleString('pl-PL')} zł
</p>
<p className="text-xs text-text-muted mt-0.5">+ montaż od {installCost.min.toLocaleString('pl-PL')} zł</p>
</div>
<Link href={`/sklep/${product.slug}`}>
<button className="flex items-center gap-1.5 px-3 py-2 bg-accent text-white rounded-xl text-xs font-bold hover:bg-accent/90 transition-colors">
Zobacz <ArrowRight className="size-3.5" />
</button>
</Link>
</div>
<Link href={`/sklep/${product.slug}`}>
<button className="flex items-center gap-1.5 px-3 py-2 bg-accent text-white rounded-xl text-xs font-bold hover:bg-accent/90 transition-colors">
Zobacz <ArrowRight className="size-3.5" />
</button>
</Link>
</div>
</div>
</div>
))}
);
})}
</div>
) : (
<div className="bg-white rounded-2xl border border-border p-12 text-center">
@@ -169,6 +243,31 @@ export function KalkulatorClient({ products }: Props) {
</div>
)}
<div className="mt-8 p-5 bg-amber-50 border border-amber-200 rounded-2xl">
<p className="text-sm font-bold text-amber-800 mb-2">⚠️ Ceny mają charakter orientacyjny</p>
<p className="text-sm text-amber-700 mb-4">
Podane ceny urządzeń są cenami brutto (23% VAT) i mogą się różnić
w zależności od aktualnej dostępności i kursu walut.
Koszt montażu jest szacunkowy — ostateczna wycena zależy od specyfiki instalacji.
</p>
<p className="text-sm text-amber-700 mb-4">
Zachęcamy do skorzystania z <strong>bezpłatnej i niezobowiązującej wyceny</strong>.
Możesz też przesłać nam zdjęcia pomieszczeń — dobierzemy optymalne rozwiązanie.
</p>
<div className="flex flex-col sm:flex-row gap-3">
<a href={`tel:${companyDetails.phoneRaw}`}>
<button className="flex items-center gap-2 px-5 py-2.5 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent/90 transition-colors">
<Phone className="size-4" /> Bezpłatna wycena
</button>
</a>
<Link href="/kontakt">
<button className="flex items-center gap-2 px-5 py-2.5 bg-amber-100 text-amber-800 rounded-xl text-sm font-bold hover:bg-amber-200 transition-colors border border-amber-300">
Prześlij zdjęcia pomieszczeń
</button>
</Link>
</div>
</div>
<div className="mt-8 flex gap-4">
<button onClick={handleReset} className="flex items-center gap-2 px-5 py-3 bg-white border border-border rounded-xl text-sm font-semibold text-primary hover:border-accent transition-colors">
<RotateCcw className="size-4" /> Zacznij od nowa
@@ -190,9 +289,9 @@ export function KalkulatorClient({ products }: Props) {
{/* Header */}
<div className="text-center mb-8">
<h1 className="text-3xl font-extrabold text-primary font-heading mb-2">
Dobierz klimatyzator
Dobierz urządzenie
</h1>
<p className="text-text-muted">Odpowiedz na 4 pytania — pokażemy Ci najlepsze opcje z naszej oferty</p>
<p className="text-text-muted">Odpowiedz na {STEPS.length} krótkich pytań — pokażemy Ci najlepsze opcje z naszej oferty</p>
</div>
{/* Pasek postępu */}
@@ -213,8 +312,90 @@ export function KalkulatorClient({ products }: Props) {
{/* Karty kroków */}
<div className="bg-white rounded-2xl border border-border p-6 md:p-8">
{/* Krok 0: Pomieszczenie */}
{/* Krok 0: Typ urządzenia */}
{step === 0 && (
<div className="flex flex-col gap-4">
<h2 className="text-lg font-bold text-primary font-heading mb-2">Co chcesz zainstalować?</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<button onClick={() => setDeviceType('klimatyzacja')}
className={`p-5 rounded-xl border-2 text-left transition-all ${deviceType === 'klimatyzacja' ? 'border-accent bg-accent/5' : 'border-border hover:border-accent'}`}>
<span className="text-3xl mb-2 block">❄️</span>
<p className="font-bold text-primary">Klimatyzacja</p>
<p className="text-xs text-text-muted mt-1">Chłodzenie latem, opcjonalne grzanie zimą</p>
</button>
<button onClick={() => setDeviceType('pompa')}
className={`p-5 rounded-xl border-2 text-left transition-all ${deviceType === 'pompa' ? 'border-accent bg-accent/5' : 'border-border hover:border-accent'}`}>
<span className="text-3xl mb-2 block">🔥</span>
<p className="font-bold text-primary">Pompa ciepła</p>
<p className="text-xs text-text-muted mt-1">Głównie ogrzewanie domu z niskim kosztem eksploatacji</p>
</button>
</div>
{deviceType === 'pompa' && !pumpFormSent && (
<div className="mt-4 p-5 bg-white border border-border rounded-2xl flex flex-col gap-4">
<p className="text-sm font-bold text-primary">Wypełnij formularz — oddzwonimy z bezpłatną wyceną</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label className="text-xs font-medium text-primary mb-1 block">Imię i nazwisko *</label>
<input
name="pump_name" required
className="w-full border border-border rounded-xl px-3 py-2.5 text-sm focus:border-accent outline-none"
placeholder="Jan Kowalski"
value={pumpForm.name}
onChange={e => setPumpForm(f => ({...f, name: e.target.value}))}
/>
</div>
<div>
<label className="text-xs font-medium text-primary mb-1 block">Telefon *</label>
<input
name="pump_phone" required type="tel"
className="w-full border border-border rounded-xl px-3 py-2.5 text-sm focus:border-accent outline-none"
placeholder="+48 600 000 000"
value={pumpForm.phone}
onChange={e => setPumpForm(f => ({...f, phone: e.target.value}))}
/>
</div>
</div>
<div>
<label className="text-xs font-medium text-primary mb-1 block">Miasto *</label>
<input
name="pump_city" required
className="w-full border border-border rounded-xl px-3 py-2.5 text-sm focus:border-accent outline-none"
placeholder="Wrocław"
value={pumpForm.city}
onChange={e => setPumpForm(f => ({...f, city: e.target.value}))}
/>
</div>
<div>
<label className="text-xs font-medium text-primary mb-1 block">Krótki opis (opcjonalnie)</label>
<textarea
name="pump_message" rows={3}
className="w-full border border-border rounded-xl px-3 py-2.5 text-sm focus:border-accent outline-none resize-none"
placeholder="Np. dom 150m², nowy budynek, chcę wymienić ogrzewanie gazowe..."
value={pumpForm.message}
onChange={e => setPumpForm(f => ({...f, message: e.target.value}))}
/>
</div>
<button
onClick={handlePumpSubmit}
disabled={!pumpForm.name || !pumpForm.phone || !pumpForm.city}
className="flex items-center justify-center gap-2 py-3 px-6 bg-accent text-white rounded-xl font-bold text-sm hover:bg-accent/90 transition-colors disabled:opacity-50"
>
Wyślij zapytanie o pompę ciepła
</button>
</div>
)}
{deviceType === 'pompa' && pumpFormSent && (
<div className="mt-4 p-5 bg-green-50 border border-green-200 rounded-2xl text-center">
<p className="text-green-700 font-bold mb-1">✅ Zapytanie wysłane!</p>
<p className="text-sm text-green-600">Skontaktujemy się z Tobą w ciągu 24 godzin z bezpłatną wyceną.</p>
</div>
)}
</div>
)}
{/* Krok 1: Pomieszczenie */}
{step === 1 && (
<div className="flex flex-col gap-6">
<div className="flex items-center gap-3 mb-2">
<div className="size-10 rounded-xl bg-blue-50 flex items-center justify-center">
@@ -316,45 +497,64 @@ export function KalkulatorClient({ products }: Props) {
</div>
)}
{/* Krok 1: Konfiguracja */}
{step === 1 && (
{/* Krok 2: Konfiguracja */}
{step === 2 && (
<div className="flex flex-col gap-6">
<div className="flex items-center gap-3 mb-2">
<div className="size-10 rounded-xl bg-purple-50 flex items-center justify-center">
<Thermometer className="size-5 text-purple-600" />
</div>
<div>
<h2 className="text-lg font-bold text-primary font-heading">Ile pomieszczeń?</h2>
<p className="text-xs text-text-muted">1 pomieszczenie = split, więcej = multisplit</p>
<h2 className="text-lg font-bold text-primary font-heading">Konfiguracja</h2>
<p className="text-xs text-text-muted">Ilość pomieszczeń i typ instalacji</p>
</div>
</div>
<div className="grid grid-cols-2 gap-3">
{[
{ value: 1, label: '1 pomieszczenie', sub: 'Klimatyzator split', icon: '🏠' },
{ value: 2, label: '2 pomieszczenia', sub: 'System multisplit 2+1', icon: '🏡' },
{ value: 3, label: '3 pomieszczenia', sub: 'System multisplit 3+1', icon: '🏘️' },
{ value: 4, label: '4-5 pomieszczeń', sub: 'System multisplit 4+1', icon: '🏗️' },
].map(o => (
<button key={o.value} onClick={() => setRooms(o.value)}
className={`p-4 rounded-xl border-2 text-left transition-all ${rooms === o.value ? 'border-accent bg-accent/5' : 'border-border hover:border-accent'}`}>
<span className="text-2xl mb-2 block">{o.icon}</span>
<p className="text-sm font-bold text-primary">{o.label}</p>
<p className="text-xs text-text-muted">{o.sub}</p>
</button>
))}
<div>
<label className="text-sm font-semibold text-primary mb-3 block">Wybierz typ systemu</label>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-2">
{[
{ value: 'auto', label: 'Dobierz automatycznie' },
{ value: 'scienne', label: 'Split (1 agregat = 1 pokój)' },
{ value: 'multisplit', label: 'Multisplit (1 agregat = wiele)' },
].map(o => (
<button key={o.value} onClick={() => setSystemType(o.value as 'auto'|'scienne'|'multisplit')}
className={`py-2 px-3 rounded-xl text-sm font-semibold border-2 transition-all ${systemType === o.value ? 'border-accent bg-accent text-white' : 'border-border bg-white text-primary hover:border-accent'}`}>
{o.label}
</button>
))}
</div>
</div>
<div>
<label className="text-sm font-semibold text-primary mb-3 block">Ile pomieszczeń chcesz chłodzić?</label>
<div className="grid grid-cols-2 gap-3">
{[
{ value: 1, label: '1 pomieszczenie', sub: 'Pojedynczy pokój', icon: '🏠' },
{ value: 2, label: '2 pomieszczenia', sub: 'Dwa pokoje', icon: '🏡' },
{ value: 3, label: '3 pomieszczenia', sub: 'Trzy pokoje', icon: '🏘️' },
{ value: 4, label: '4-5 pomieszczeń', sub: 'Wiele pokoi', icon: '🏗️' },
].map(o => (
<button key={o.value} onClick={() => setRooms(o.value)}
className={`p-4 rounded-xl border-2 text-left transition-all ${rooms === o.value ? 'border-accent bg-accent/5' : 'border-border hover:border-accent'}`}>
<span className="text-2xl mb-2 block">{o.icon}</span>
<p className="text-sm font-bold text-primary">{o.label}</p>
<p className="text-xs text-text-muted">{o.sub}</p>
</button>
))}
</div>
</div>
<div className="p-3 bg-slate-50 rounded-xl text-xs text-text-muted">
{rooms === 1
? '✅ Klimatyzator split — jedna jednostka wewnętrzna + jedna zewnętrzna. Idealne do pojedynczego pomieszczenia.'
: `✅ System multisplit — jedna jednostka zewnętrzna obsługuje ${rooms} jednostki wewnętrzne. Ekonomiczne i estetyczne rozwiązanie dla całego domu.`}
{category === 'scienne'
? '✅ Wybrano: Klimatyzator split — jedna jednostka wewnętrzna i jedna zewnętrzna. Dedykowane dla jednego pokoju.'
: `✅ Wybrano: System multisplit — jedna jednostka zewnętrzna obsłuży ${rooms} jednostki wewnętrzne. Lepsza estetyka na zewnątrz budynku.`}
</div>
</div>
)}
{/* Krok 2: Instalacja */}
{step === 2 && (
{/* Krok 3: Instalacja */}
{step === 3 && (
<div className="flex flex-col gap-6">
<div className="flex items-center gap-3 mb-2">
<div className="size-10 rounded-xl bg-orange-50 flex items-center justify-center">
@@ -388,8 +588,8 @@ export function KalkulatorClient({ products }: Props) {
</div>
)}
{/* Krok 3: Budżet */}
{step === 3 && (
{/* Krok 4: Budżet */}
{step === 4 && (
<div className="flex flex-col gap-6">
<div className="flex items-center gap-3 mb-2">
<div className="size-10 rounded-xl bg-green-50 flex items-center justify-center">
@@ -420,7 +620,7 @@ export function KalkulatorClient({ products }: Props) {
<div className="bg-slate-50 rounded-xl p-3">
<p className="text-xs text-text-muted mb-1">Na urządzenie zostaje</p>
<p className="text-base font-bold text-primary font-heading">
ok. {Math.max(0, budget - installCost.min).toLocaleString('pl-PL')} zł
ok. {(budget * 0.75).toLocaleString('pl-PL')} zł
</p>
</div>
<div className="bg-orange-50 rounded-xl p-3">
@@ -432,7 +632,28 @@ export function KalkulatorClient({ products }: Props) {
</div>
<div className="p-3 bg-blue-50 rounded-xl text-xs text-blue-700">
💡 Podsumowanie: szukamy klimatyzatora <strong>{category === 'scienne' ? 'split ściennego' : 'multisplit'}</strong> o mocy ok. <strong>{requiredPower} kW</strong> w cenie do <strong>{Math.max(0, budget - installCost.min).toLocaleString('pl-PL')} zł</strong>
💡 Podsumowanie: szukamy klimatyzatora <strong>{category === 'scienne' ? 'split ściennego' : 'multisplit'}</strong> o mocy ok. <strong>{requiredPower} kW</strong> w cenie do <strong>{(budget * 0.75).toLocaleString('pl-PL')} zł</strong>
</div>
<div>
<label className="text-sm font-semibold text-primary mb-3 block">
Preferowana marka (opcjonalnie)
</label>
<div className="flex flex-wrap gap-2">
{['Bez preferencji', 'Gree', 'Rotenso', 'Daikin', 'Haier', 'LG', 'Samsung', 'Mitsubishi Electric', 'Toshiba', 'Fuji Electric'].map(b => (
<button
key={b}
onClick={() => setPreferredBrand(b === 'Bez preferencji' ? '' : b)}
className={`px-3 py-1.5 rounded-xl text-xs font-semibold border-2 transition-all ${
(b === 'Bez preferencji' && preferredBrand === '') || preferredBrand === b
? 'border-accent bg-accent text-white'
: 'border-border bg-white text-primary hover:border-accent'
}`}
>
{b}
</button>
))}
</div>
</div>
</div>
)}
@@ -446,11 +667,13 @@ export function KalkulatorClient({ products }: Props) {
</button>
) : <div />}
{step < 3 ? (
<button onClick={() => setStep(s => s + 1)}
className="flex items-center gap-2 px-6 py-2.5 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent/90 transition-colors">
Dalej <ArrowRight className="size-4" />
</button>
{step < STEPS.length - 1 ? (
!(step === 0 && deviceType === 'pompa') && (
<button onClick={handleNext}
className="flex items-center gap-2 px-6 py-2.5 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent/90 transition-colors">
Dalej <ArrowRight className="size-4" />
</button>
)
) : (
<button onClick={handleFinish}
className="flex items-center gap-2 px-6 py-2.5 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent/90 transition-colors">