Files
thermcool/components/kalkulator/KalkulatorClient.tsx
T

741 lines
39 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useState, useMemo } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { ArrowRight, ArrowLeft, Check, Thermometer, Home, Zap, ShoppingCart, Phone, RotateCcw } from 'lucide-react';
import { Product } from '@/content/products';
import { companyDetails } from '@/content/company';
interface Props {
products: Product[];
}
// Oblicz wymaganą moc chłodniczą w kW
function calculatePower(m2: number, floor: string, sun: string, building: string): number {
let power = m2 * 0.1; // baza: 1 kW na 10 m²
// Korekta typu budynku i piętra
if (building === 'apartment') {
if (floor === 'top') power *= 1.2; // ostatnie piętro - więcej ciepła z dachu
if (floor === 'ground') power *= 0.95;
} else if (building === 'house') {
if (floor === 'top') power *= 1.1; // poddasze - dodatkowe nagrzewanie
}
// Korekta nasłonecznienia
if (sun === 'south') power *= 1.15; // południe - duże nasłonecznienie
if (sun === 'west') power *= 1.1;
if (sun === 'north') power *= 0.9;
return Math.round(power * 10) / 10;
}
// Szacunkowy koszt montażu
function estimateInstall(pipes: string, rooms: number): { min: number; max: number } {
const base = rooms === 1 ? 1400 : rooms === 2 ? 2400 : rooms === 3 ? 3200 : 3800;
const pipeExtra = pipes === 'short' ? 0 : pipes === 'medium' ? 300 : pipes === 'long' ? 700 : 1200;
return { min: base + pipeExtra, max: base + pipeExtra + 600 };
}
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 = systemType === 'auto' ? (rooms === 1 ? 'scienne' : 'multisplit') : systemType;
const results = useMemo(() => {
if (!showResults || deviceType === 'pompa') return [];
const maxPrice = budget * 0.75;
const powerMin = requiredPower * 0.6;
const powerMax = requiredPower * 1.8;
const filtered = products
.filter(p => {
if (p.category !== category) 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;
})
.sort((a, b) => {
// Sortuj po tym jak blisko jest moc do wymaganej
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);
});
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">
{/* Podsumowanie */}
<div className="bg-white rounded-2xl border border-border p-6 mb-8">
<h1 className="text-2xl font-extrabold text-primary font-heading mb-4">
Dopasowane klimatyzatory
</h1>
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
{[
{ label: 'Wymagana moc', value: `${requiredPower} kW` },
{ label: 'Powierzchnia', value: `${m2} m²` },
{ 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">
<p className="text-xs text-text-muted mb-1">{s.label}</p>
<p className="text-base font-bold text-primary font-heading">{s.value}</p>
</div>
))}
</div>
</div>
{results.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5">
{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="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>
</div>
</div>
);
})}
</div>
) : (
<div className="bg-white rounded-2xl border border-border p-12 text-center">
<p className="text-text-muted mb-4">
Nie znaleziono produktów dla podanych kryteriów. Spróbuj zwiększyć budżet lub zadzwoń do nas — dobierzemy ofertę indywidualnie.
</p>
<a href={`tel:${companyDetails.phoneRaw}`}>
<button className="flex items-center gap-2 px-6 py-3 bg-accent text-white rounded-xl font-bold mx-auto hover:bg-accent/90 transition-colors">
<Phone className="size-4" /> {companyDetails.phone}
</button>
</a>
</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
</button>
<Link href="/sklep">
<button 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">
Przeglądaj cały sklep <ArrowRight className="size-4" />
</button>
</Link>
</div>
</div>
</main>
);
}
return (
<main className="bg-slate-50 min-h-screen py-12">
<div className="max-w-2xl mx-auto px-4 sm:px-6">
{/* Header */}
<div className="text-center mb-8">
<h1 className="text-3xl font-extrabold text-primary font-heading mb-2">
Dobierz urządzenie
</h1>
<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 */}
<div className="flex items-center gap-2 mb-8">
{STEPS.map((s, i) => (
<div key={s} className="flex-1 flex items-center gap-2">
<div className={`size-7 rounded-full flex items-center justify-center text-xs font-bold shrink-0 transition-all ${
i < step ? 'bg-green-500 text-white' : i === step ? 'bg-accent text-white' : 'bg-slate-200 text-text-muted'
}`}>
{i < step ? <Check className="size-3.5" /> : i + 1}
</div>
<span className={`text-xs font-medium hidden sm:block ${i === step ? 'text-accent' : 'text-text-muted'}`}>{s}</span>
{i < STEPS.length - 1 && <div className={`flex-1 h-0.5 ${i < step ? 'bg-green-500' : 'bg-slate-200'}`} />}
</div>
))}
</div>
{/* Karty kroków */}
<div className="bg-white rounded-2xl border border-border p-6 md:p-8">
{/* 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 w celu ustalenia terminu bezpłatnej i niezobowiązującej wizji lokalnej</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>
<p className="text-xs text-text-muted text-center mt-2">
Wizja lokalna jest bezpłatna i niezobowiązująca. Oddzwaniamy w ciągu 24 godzin.
</p>
</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">
<Home className="size-5 text-blue-600" />
</div>
<div>
<h2 className="text-lg font-bold text-primary font-heading">Pomieszczenie</h2>
<p className="text-xs text-text-muted">Metraż i warunki</p>
</div>
</div>
<div className="flex flex-col gap-1.5">
<div className="flex items-center justify-between">
<span className="text-xs text-text-muted">Powierzchnia</span>
<span className="text-xs font-bold text-primary bg-accent/10 px-2 py-0.5 rounded-md">{m2} m²</span>
</div>
<div className="relative h-5 flex items-center">
<div className="absolute w-full h-1.5 bg-slate-200 rounded-full" />
<div
className="absolute h-1.5 bg-accent rounded-full"
style={{ width: `${((m2 - 10) / 90) * 100}%` }}
/>
<input
type="range" min={10} max={100} step={5} value={m2}
onChange={e => setM2(Number(e.target.value))}
className="absolute w-full h-1.5 opacity-0 cursor-pointer z-10"
/>
<div
className="absolute size-4 bg-white border-2 border-accent rounded-full shadow-md pointer-events-none"
style={{ left: `calc(${((m2 - 10) / 90) * 100}% - 8px)` }}
/>
</div>
<div className="flex justify-between text-xs text-text-muted">
<span>10 m²</span>
<span>100 m²</span>
</div>
<div className="mt-3 p-3 bg-blue-50 rounded-xl text-sm text-blue-700 font-medium">
Wymagana moc: ok. <strong>{requiredPower} kW</strong>
<span className="text-xs font-normal ml-2">(dla {m2} m²)</span>
</div>
</div>
<div>
<label className="text-sm font-semibold text-primary mb-3 block">Typ budynku</label>
<div className="grid grid-cols-2 gap-2">
{[
{ value: 'apartment', label: '🏢 Mieszkanie w bloku', sub: 'Kamienica, wieżowiec, blok' },
{ value: 'house', label: '🏠 Dom jednorodzinny', sub: 'Wolnostojący, szeregowiec, bliźniak' },
].map(o => (
<button key={o.value} onClick={() => setBuilding(o.value)}
className={`p-4 rounded-xl border-2 text-left transition-all ${building === o.value ? 'border-accent bg-accent/5' : 'border-border hover:border-accent'}`}>
<p className="text-sm font-bold text-primary">{o.label}</p>
<p className="text-xs text-text-muted">{o.sub}</p>
</button>
))}
</div>
</div>
{building === 'house' && (
<div>
<label className="text-sm font-semibold text-primary mb-3 block">Typ przestrzeni</label>
<div className="grid grid-cols-2 gap-2">
{[
{ value: 'ground', label: '🏠 Parter' },
{ value: 'top', label: '🏠 Piętro / poddasze' },
].map(o => (
<button key={o.value} onClick={() => setFloor(o.value)}
className={`py-2.5 px-3 rounded-xl text-sm font-semibold border-2 transition-all ${floor === o.value ? 'border-accent bg-accent text-white' : 'border-border bg-white text-primary hover:border-accent'}`}>
{o.label}
</button>
))}
</div>
</div>
)}
{building === 'apartment' && (
<div>
<label className="text-sm font-semibold text-primary mb-3 block">Piętro</label>
<div className="flex flex-wrap gap-2">
{[
{ value: 'ground', label: 'Parter' },
{ value: 'low', label: '1-3 piętro' },
{ value: 'middle', label: '4-8 piętro' },
{ value: 'high', label: '9+ piętro' },
{ value: 'top', label: 'Ostatnie' },
].map(o => (
<button key={o.value} onClick={() => setFloor(o.value)}
className={`py-2 px-4 rounded-xl text-sm font-semibold border-2 transition-all ${floor === 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">Ekspozycja okien</label>
<div className="grid grid-cols-2 gap-2">
{[
{ value: 'north', label: '🧭 Północ (chłodna)' },
{ value: 'east', label: '🧭 Wschód' },
{ value: 'west', label: '🧭 Zachód' },
{ value: 'south', label: '🧭 Południe (mocne słońce)' },
].map(o => (
<button key={o.value} onClick={() => setSun(o.value)}
className={`py-2.5 px-3 rounded-xl text-sm font-semibold border-2 transition-all ${sun === o.value ? 'border-accent bg-accent text-white' : 'border-border bg-white text-primary hover:border-accent'}`}>
{o.label}
</button>
))}
</div>
</div>
</div>
)}
{/* 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">Konfiguracja</h2>
<p className="text-xs text-text-muted">Ilość pomieszczeń i typ instalacji</p>
</div>
</div>
<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">
{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 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">
<Zap className="size-5 text-orange-600" />
</div>
<div>
<h2 className="text-lg font-bold text-primary font-heading">Długość instalacji</h2>
<p className="text-xs text-text-muted">Rury i kable między jednostkami</p>
</div>
</div>
<div className="flex flex-col gap-3">
{[
{ value: 'short', label: 'Do 3 metrów', sub: 'Jednostka zewnętrzna tuż obok (balkon, taras)' },
{ value: 'medium', label: '3–6 metrów', sub: 'Typowa instalacja w bloku lub domu' },
{ value: 'long', label: '6–10 metrów', sub: 'Dłuższa trasa, np. przez kilka pomieszczeń' },
{ value: 'verylong', label: 'Powyżej 10 metrów', sub: 'Bardzo długa trasa, wymaga dodatkowych materiałów' },
].map(o => (
<button key={o.value} onClick={() => setPipes(o.value)}
className={`p-4 rounded-xl border-2 text-left transition-all ${pipes === o.value ? 'border-accent bg-accent/5' : 'border-border hover:border-accent'}`}>
<p className="text-sm font-bold text-primary">{o.label}</p>
<p className="text-xs text-text-muted">{o.sub}</p>
</button>
))}
</div>
<div className="p-3 bg-orange-50 rounded-xl text-xs text-orange-700">
Szacowany koszt montażu dla Twojej konfiguracji:
<strong className="ml-1">{installCost.min.toLocaleString('pl-PL')}–{installCost.max.toLocaleString('pl-PL')} zł</strong>
</div>
<div className="mt-3 p-4 bg-blue-50 border border-blue-200 rounded-xl">
<p className="text-sm font-semibold text-blue-900 mb-1">📐 Chcesz dokładną wycenę?</p>
<p className="text-xs text-blue-800 leading-relaxed">
Skontaktuj się z nami — wycena jest <strong>bezpłatna i niezobowiązująca</strong>.
Aby przyspieszyć wycenę, wyślij nam zdjęcia:
</p>
<ul className="mt-2 flex flex-col gap-1">
{[
'Miejsca gdzie ma wisieć jednostka wewnętrzna',
'Ściany przez które przejdzie instalacja',
'Miejsca gdzie stanie jednostka zewnętrzna',
'Skrzynki elektrycznej (bezpieczniki)',
].map((item, i) => (
<li key={i} className="flex items-start gap-2 text-xs text-blue-800">
<span className="text-blue-500 shrink-0">→</span>
{item}
</li>
))}
</ul>
<a href="/kontakt" className="mt-3 inline-flex items-center gap-1.5 text-xs font-bold text-white bg-accent px-3 py-1.5 rounded-lg hover:bg-accent/90 transition-colors">
Wyślij zdjęcia i zapytaj o wycenę →
</a>
</div>
</div>
)}
{/* 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">
<ShoppingCart className="size-5 text-green-600" />
</div>
<div>
<h2 className="text-lg font-bold text-primary font-heading">Całkowity budżet</h2>
<p className="text-xs text-text-muted">Urządzenie + montaż łącznie</p>
</div>
</div>
<div className="flex flex-col gap-1.5">
<div className="flex items-center justify-between">
<span className="text-xs text-text-muted">Budżet</span>
<span className="text-xs font-bold text-primary bg-accent/10 px-2 py-0.5 rounded-md">{budget.toLocaleString('pl-PL')} zł</span>
</div>
<div className="relative h-5 flex items-center">
<div className="absolute w-full h-1.5 bg-slate-200 rounded-full" />
<div
className="absolute h-1.5 bg-accent rounded-full"
style={{ width: `${((budget - 3000) / 22000) * 100}%` }}
/>
<input
type="range" min={3000} max={25000} step={500} value={budget}
onChange={e => setBudget(Number(e.target.value))}
className="absolute w-full h-1.5 opacity-0 cursor-pointer z-10"
/>
<div
className="absolute size-4 bg-white border-2 border-accent rounded-full shadow-md pointer-events-none"
style={{ left: `calc(${((budget - 3000) / 22000) * 100}% - 8px)` }}
/>
</div>
<div className="flex justify-between text-xs text-text-muted">
<span>3 000 zł</span>
<span>25 000 zł</span>
</div>
</div>
<div className="grid grid-cols-2 gap-3">
<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. {(budget * 0.75).toLocaleString('pl-PL')} zł
</p>
</div>
<div className="bg-orange-50 rounded-xl p-3">
<p className="text-xs text-orange-700 mb-1">Szac. koszt montażu</p>
<p className="text-base font-bold text-orange-700 font-heading">
{installCost.min.toLocaleString('pl-PL')}–{installCost.max.toLocaleString('pl-PL')} zł
</p>
</div>
</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>{(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>
)}
{/* Nawigacja */}
<div className="flex justify-between mt-8 pt-6 border-t border-border">
{step > 0 ? (
<button onClick={() => setStep(s => s - 1)}
className="flex items-center gap-2 px-4 py-2.5 border border-border rounded-xl text-sm font-semibold text-primary hover:border-accent transition-colors">
<ArrowLeft className="size-4" /> Wstecz
</button>
) : <div />}
{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">
Pokaż dopasowane produkty <ArrowRight className="size-4" />
</button>
)}
</div>
</div>
</div>
</main>
);
}