// Interactive home configurator const { useState: useStateCfg, useMemo: useMemoCfg } = React; function HomeConfigurator({ addToCart, setPage }) { const MODULE = 625; // mm const [widthMods, setWidthMods] = useStateCfg(14); // 14 × 625 = 8750mm const [depthMods, setDepthMods] = useStateCfg(10); // 10 × 625 = 6250mm const [roof, setRoof] = useStateCfg("sedlova"); const [windows, setWindows] = useStateCfg(6); const [doors, setDoors] = useStateCfg(2); const [added, setAdded] = useStateCfg(false); const widthMm = widthMods * MODULE; const depthMm = depthMods * MODULE; const area = (widthMm * depthMm) / 1_000_000; // m² const perimeter = 2 * (widthMm + depthMm) / 1000; // m const ribsCount = 2 * (widthMods + 1) + 2 * (depthMods + 1) - 4; // corners counted once const roofMul = { plocha:1.0, sedlova:1.08, pultova:1.05, valbova:1.12 }; const basePrice = Math.round(area * 3500 * roofMul[roof]); const openingsPrice = windows * 3800 + doors * 5400; const total = basePrice + openingsPrice; const ribs = ribsCount; const uProfile = Math.ceil(perimeter / 6); // 6m profils const screws = ribs * 14; const handleAdd = () => { const custom = { id: `cfg-${Date.now()}`, cat: "stavebnice", color: "a", name: `Stavebnice ${(widthMm/1000).toFixed(2)} × ${(depthMm/1000).toFixed(2)} m`, desc: `Konfigurace z webu — ${roof}, ${windows}× okno, ${doors}× dveře`, price: total, unit: "kpl", sku: `CFG-${widthMods}x${depthMods}`, tag: "KONFIG", }; addToCart(custom); setAdded(true); setTimeout(()=>setAdded(false), 1800); }; // Render floorplan const maxMm = Math.max(widthMm, depthMm); const scale = 380 / maxMm; const pw = widthMm * scale; const pd = depthMm * scale; const cx = 220, cy = 160; const x0 = cx - pw/2, y0 = cy - pd/2; // Distribute windows/doors on perimeter const openings = []; const bays = widthMods; for (let i = 0; i < windows; i++) { const side = i % 2 === 0 ? "top" : "bottom"; const slot = 2 + (Math.floor(i/2) * 3); if (slot < bays - 1) { if (side === "top") openings.push({ x: x0 + slot * MODULE * scale, y: y0 - 3, w: MODULE * scale * 1.5, h: 6, kind:"w" }); else openings.push({ x: x0 + slot * MODULE * scale, y: y0 + pd - 3, w: MODULE * scale * 1.5, h: 6, kind:"w" }); } } for (let i = 0; i < doors; i++) { const slot = 1 + i * (bays - 3); const yPos = i === 0 ? y0 + pd - 3 : y0 - 3; openings.push({ x: x0 + slot * MODULE * scale, y: yPos, w: MODULE * scale, h: 6, kind:"d" }); } return (
Spočítejte si konstrukci

Spočítejte první návrh nosné konstrukce za pár kliků.

Upravte rozměry, typ střechy, okna a dveře. Konfigurátor průběžně počítá výkaz prvků a orientační cenu. Výstup je orientační — finální řešení poté ověřuje projektant nebo statik.

{/* Left: canvas */}
2D půdorys · rastr 625 mm
{/* grid raster overlay inside house */} {/* fill */} {/* ribs */} {Array.from({length: widthMods+1}).map((_,i) => ( ))} {Array.from({length: depthMods+1}).map((_,i) => ( ))} {/* outer walls */} {/* openings */} {openings.map((o,i)=>( ))} {/* dim top */} {(widthMm/1000).toFixed(2).replace('.',',')} m · {widthMods} × 625 {/* dim right */} {(depthMm/1000).toFixed(2).replace('.',',')} m {/* roof overlay */} {roof !== "plocha" && ( <> )}
Okno Dveře Raster 625
{/* Right: controls */}
{(widthMm/1000).toFixed(2).replace('.',',')} m ({widthMods} × 625)
setWidthMods(+e.target.value)}/>
{(depthMm/1000).toFixed(2).replace('.',',')} m ({depthMods} × 625)
setDepthMods(+e.target.value)}/>
 
{[["plocha","Plochá"],["sedlova","Sedlová"],["pultova","Pultová"],["valbova","Valbová"]].map(([id,l])=>( ))}
{windows}×
{windows}
{doors}×
{doors}
Výkaz prvků · orientační
Zastavěná plocha{area.toFixed(1).replace('.',',')} m²
Obvod{perimeter.toFixed(1).replace('.',',')} m
Nosná žebra{ribs} ks
U profily (6 m){uProfile*2} ks
Kotvící prvkycca {screws} ks
{/* Buildability score */} {(() => { const openingCount = windows + doors; const openingsPerWall = Math.ceil(openingCount / 4); const checks = [ { ok: widthMods >= 8 && depthMods >= 6, label: "Modulové rozměry v rozsahu systému", warn: "Velmi malý dům — zvažte studio či přístavbu" }, { ok: openingsPerWall <= 3, label: "Otvorů na stěnu v normě", warn: "Vysoký počet otvorů na jedné stěně — kontrola statikem" }, { ok: roof !== "valbova" || area <= 100, label: "Střecha vhodná pro plochu", warn: "Valbová střecha pro velký dům — vyžaduje úpravu" }, { ok: doors >= 1, label: "Minimálně jedny dveře", warn: "Návrh musí mít alespoň jedny vstupní dveře" }, { ok: true, label: "Rastr 625 mm zachován", warn: "" }, ]; const okCount = checks.filter(c=>c.ok).length; const score = Math.round((okCount / checks.length) * 100); const status = score === 100 ? "Připraveno k odeslání" : score >= 80 ? "Téměř hotovo" : "Vyžaduje úpravy"; return (
Kontrola návrhu
{score} % · {status}
{checks.map((c,i)=>(
{c.ok?"✓":"!"} {c.ok ? c.label : (c.warn || c.label)}
))}
); })()}
Orientační cena konstrukce
{total.toLocaleString("cs-CZ")} Kč
bez DPH · {(total*1.21).toLocaleString("cs-CZ",{maximumFractionDigits:0})} Kč s DPH · finální cenu potvrdíme podle projektu
Máte vlastní půdorys? Pošlete nám ho a ověříme, jak sedí do systému.
); } window.HomeConfigurator = HomeConfigurator;