function App() {
const [rolls, setRolls] = useState(40);
const [payAdvance, setPayAdvance] = useState(true);
const [includeVat, setIncludeVat] = useState(false);
const [showInquiryModal, setShowInquiryModal] = useState(false);
const [inquiryType, setInquiryType] = useState("standard"); // "standard" | "partner"
const [inquirySent, setInquirySent] = useState(false);
// Kontaktní údaje ve formuláři
const [formData, setFormData] = useState({
name: "",
company: "",
email: "",
phone: "",
address: "",
note: ""
});
const m2PerRoll = 5;
const weightPerRoll = 25;
const totalM2 = rolls * m2PerRoll;
const totalWeight = rolls * weightPerRoll;
// Cenová pásma bez DPH (Ceník 2026, max 40 rolí)
const getBasePricing = (qty) => {
if (qty >= 40) {
return { priceM2: 390, priceRoll: 1950, shippingIncluded: false, tierName: "40 rolí – Celá paleta (Bestseller)" };
}
if (qty >= 30) {
return { priceM2: 396, priceRoll: 1980, shippingIncluded: false, tierName: "30 – 39 rolí" };
}
if (qty >= 20) {
return { priceM2: 420, priceRoll: 2100, shippingIncluded: false, tierName: "20 – 29 rolí" };
}
if (qty >= 10) {
return { priceM2: 435, priceRoll: 2175, shippingIncluded: false, tierName: "10 – 19 rolí" };
}
if (qty >= 3) {
return { priceM2: 456, priceRoll: 2280, shippingIncluded: false, tierName: "3 – 9 rolí" };
}
// 1-2 role
return { priceM2: 550, priceRoll: 2750, shippingIncluded: true, tierName: "1 – 2 role (vč. dopravy v ČR)" };
};
const pricing = getBasePricing(rolls);
const baseRollPrice = pricing.priceRoll;
const baseM2Price = pricing.priceM2;
// 5% sleva za platbu předem (platí pouze pro paletový odběr 3 až 40 rolí)
const isEligibleForAdvanceDiscount = rolls >= 3 && rolls <= 40;
const advanceDiscountRate = (payAdvance && isEligibleForAdvanceDiscount) ? 0.05 : 0;
const finalRollPriceWithoutVat = baseRollPrice * (1 - advanceDiscountRate);
const finalM2PriceWithoutVat = finalRollPriceWithoutVat / m2PerRoll;
const totalWithoutVat = rolls * finalRollPriceWithoutVat;
const vatRate = 0.21;
const vatMultiplier = includeVat ? 1 + vatRate : 1;
const displayTotal = totalWithoutVat * vatMultiplier;
const displayM2Price = finalM2PriceWithoutVat * vatMultiplier;
const displayRollPrice = finalRollPriceWithoutVat * vatMultiplier;
// Vyčíslení 5% úspory
const advanceSavedTotal = (rolls * baseRollPrice * advanceDiscountRate) * vatMultiplier;
// Informace o dopravě a expedici
const getShippingInfo = (qty) => {
if (qty <= 2) {
return {
type: "Balík do 30 kg (Doprava v ceně)",
badge: "1–2 role v krabici",
desc: "Jednotlivě balené v transportních krabicích jako balík do 30 kg (cena 2 750 Kč/balení již zahrnuje dopravu v ČR). Zboží obvykle odesíláme následující den od objednání a dopravce obvykle dodává 1 až 2 dny od nakládky.",
icon: "📦",
freeIncluded: true
};
} else {
return {
type: "Europaleta (1× paleta)",
badge: "3–40 rolí na Europaletě",
desc: "Zboží jede na Europaletě (3 až max. 40 rolí). Europaleta je účtována buď výměnou, nebo připočtena k ceně dopravy. Zboží obvykle odesíláme následující den od objednání a dopravce obvykle dodává 1 až 2 dny od nakládky.",
icon: "🚛",
freeIncluded: false
};
}
};
const shipping = getShippingInfo(rolls);
const tiers = [
{ range: "1 – 2 role", m2: "5 – 10 m²", priceM2: 550, priceRoll: 2750, note: "Vč. dopravy v ČR (bez slevy 5 %)", min: 1, max: 2 },
{ range: "3 – 9 rolí", m2: "15 – 45 m²", priceM2: 456, priceRoll: 2280, note: "Europaleta (sleva 5 % předem)", min: 3, max: 9 },
{ range: "10 – 19 rolí", m2: "50 – 95 m²", priceM2: 435, priceRoll: 2175, note: "Europaleta (sleva 5 % předem)", min: 10, max: 19 },
{ range: "20 – 29 rolí", m2: "100 – 145 m²", priceM2: 420, priceRoll: 2100, note: "Europaleta (sleva 5 % předem)", min: 20, max: 29 },
{ range: "30 – 39 rolí", m2: "150 – 195 m²", priceM2: 396, priceRoll: 1980, note: "Europaleta (sleva 5 % předem)", min: 30, max: 39 },
{ range: "40 rolí (Paleta)", m2: "200 m²", priceM2: 390, priceRoll: 1950, note: "Bestseller (sleva 5 % předem)", min: 40, max: 40, bestseller: true },
];
const formatKc = (val) => {
return Math.round(val).toLocaleString("cs-CZ") + " Kč";
};
const formatKcDec = (val) => {
return (Math.round(val * 10) / 10).toLocaleString("cs-CZ", { minimumFractionDigits: 0, maximumFractionDigits: 1 }) + " Kč";
};
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSendInquiry = (e) => {
e.preventDefault();
setInquirySent(true);
};
const openInquiry = (type = "standard") => {
setInquiryType(type);
setShowInquiryModal(true);
setInquirySent(false);
};
return (
{/* Záhlaví */}
{/* Ovládací sekce */}
{/* Volba množství (1 až max 40 rolí) */}
Zvolte počet rolí (max. 40 ks = 1 paleta):
{
const val = parseInt(e.target.value) || 1;
setRolls(Math.max(1, Math.min(40, val)));
}}
style={{
width: 76,
padding: "8px 12px",
fontSize: 17,
fontWeight: 800,
textAlign: "center",
borderRadius: 8,
border: "1.5px solid #cbd5e1",
color: "#0f172a",
outline: "none",
backgroundColor: "#f8fafc"
}}
/>
ks
{/* Posuvník max 40 */}
setRolls(parseInt(e.target.value))}
style={{
width: "100%",
height: 7,
borderRadius: 4,
accentColor: "#dc2626",
cursor: "pointer",
marginBottom: 16
}}
/>
{/* Rychlý výběr */}
Rychlá volba:
{[1, 2, 5, 10, 20, 30, 40].map((qty) => {
const isSelected = rolls === qty;
return (
setRolls(qty)}
style={{
padding: "6px 12px",
fontSize: 13,
fontWeight: isSelected ? 700 : 500,
backgroundColor: isSelected ? "#0f172a" : "#f1f5f9",
color: isSelected ? "#ffffff" : "#334155",
border: isSelected ? "1px solid #0f172a" : "1px solid #e2e8f0",
borderRadius: 8,
cursor: "pointer",
transition: "all 0.15s ease"
}}
>
{qty === 40 ? "⭐ 40 (Plná paleta)" : `${qty} ${qty === 1 ? "role" : qty < 5 ? "role" : "rolí"}`}
);
})}
{/* Technické souhrny */}
Celková plocha:
{totalM2} m²
Hmotnost zboží:
{totalWeight} kg
{/* Sleva 5% a přepínač DPH */}
Nastavení platby a zobrazení cen
{/* Karta 5% slevy za zálohu (pro 3 až 40 rolí) */}
isEligibleForAdvanceDiscount && setPayAdvance(!payAdvance)}
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "14px",
borderRadius: 12,
backgroundColor: !isEligibleForAdvanceDiscount ? "#f1f5f9" : (payAdvance ? "#fef2f2" : "#ffffff"),
border: `1.5px solid ${!isEligibleForAdvanceDiscount ? "#e2e8f0" : (payAdvance ? "#f87171" : "#cbd5e1")}`,
cursor: isEligibleForAdvanceDiscount ? "pointer" : "not-allowed",
opacity: isEligibleForAdvanceDiscount ? 1 : 0.75,
marginBottom: 14,
transition: "all 0.15s ease"
}}
>
{isEligibleForAdvanceDiscount && payAdvance ? "✓" : ""}
Sleva 5 % při úhradě zálohové faktury předem
{isEligibleForAdvanceDiscount
? "Platí pro paletové množství 3 až 40 rolí před expedicí"
: "Pro 1–2 role se sleva 5 % nevztahuje (doprava je již v ceně balení)"}
{isEligibleForAdvanceDiscount && payAdvance && (
-{formatKc(advanceSavedTotal)}
)}
{/* Přepínač zobrazení DPH */}
Zobrazení cen:
setIncludeVat(false)}
style={{
padding: "6px 12px",
fontSize: 12,
fontWeight: !includeVat ? 700 : 500,
borderRadius: 6,
border: "none",
backgroundColor: !includeVat ? "#0f172a" : "transparent",
color: !includeVat ? "#ffffff" : "#64748b",
cursor: "pointer"
}}
>
bez DPH
setIncludeVat(true)}
style={{
padding: "6px 12px",
fontSize: 12,
fontWeight: includeVat ? 700 : 500,
borderRadius: 6,
border: "none",
backgroundColor: includeVat ? "#0f172a" : "transparent",
color: includeVat ? "#ffffff" : "#64748b",
cursor: "pointer"
}}
>
s DPH (21 %)
{/* Dopravní štítek */}
{shipping.icon}
Doprava: {shipping.desc}
{/* Hlavní výpočet cen */}
Cena za m²:
{formatKcDec(displayM2Price)}
/ m²
{rolls <= 2 ? (
(Včetně dopravy v ČR)
) : payAdvance ? (
(základ {baseM2Price * vatMultiplier} Kč − 5 % záloha)
) : null}
Cena za 1 roli (5 m²):
{formatKc(displayRollPrice)}
/ role
Hmotnost role: 25 kg
Celková cena {includeVat ? "s DPH" : "bez DPH"}:
{formatKc(displayTotal)}
{payAdvance && (
Ušetříte: {formatKc(advanceSavedTotal)} (5 % záloha)
)}
{includeVat && (
(bez DPH: {formatKc(totalWithoutVat)})
)}
Vybráno: {rolls} {rolls === 1 ? "role" : rolls < 5 ? "role" : "rolí"} ({totalM2} m²) • {pricing.tierName}
Doprava: {shipping.type}
{/* Vytížení palety (1 až 40 rolí) */}
Kapacita palety: {rolls} / 40 rolí
({Math.round((rolls / 40) * 100)} %)
{rolls === 40 ? (
✓ Plná paleta (Nejvýhodnější cena v kalkulátoru)
) : (
Zbývá {40 - rolls} rolí do plného zaplnění palety (40 rolí)
)}
{/* 40 políček palety */}
{Array.from({ length: 40 }).map((_, idx) => {
const isFilled = idx < rolls;
return (
);
})}
{/* Speciální banner pro více než 40 rolí (Více palet / Velkoobchod) */}
🏢 ODBĚR VÍCE NEŽ 1 PALETY (40+ ROLÍ)
Poptáváte větší množství nebo velkoobchodní odběr?
Pro projekty nad 40 rolí (více palet) vám rádi připravíme individuální partnerskou nabídku s kalkulací dopravy na míru a projektovou slevou.
openInquiry("partner")}
style={{
backgroundColor: "#dc2626",
color: "#ffffff",
padding: "14px 24px",
fontSize: 15,
fontWeight: 800,
borderRadius: 12,
border: "none",
cursor: "pointer",
boxShadow: "0 4px 14px rgba(220, 38, 38, 0.4)",
transition: "transform 0.1s ease",
display: "flex",
alignItems: "center",
gap: 8,
whiteSpace: "nowrap"
}}
>
⭐ SPECIÁLNÍ PARTNERSKÁ CENOVÁ NABÍDKA
{/* Ceníková tabulka a expediční informace */}
Přehled cenových pásem pro rok 2026 (ceny bez DPH)
{tiers.map((t, idx) => {
const isActive = rolls >= t.min && rolls <= t.max;
const discM2 = t.priceM2 * 0.95;
const discRoll = t.priceRoll * 0.95;
return (
);
})}
Pásmo odběru
Výměra (m²)
Základní cena / m²
Základní cena / 1 role
Cena se zálohou (-5 %)
Poznámka / Doprava
{isActive ? "👉 " : ""}{t.range}
{t.m2}
{t.priceM2} Kč
{formatKc(t.priceRoll)}
{formatKcDec(discM2)} / m²
({formatKc(discRoll)} / role)
{t.note}
{/* Informace o expedici a dodání */}
📦 Expedice a dodací podmínky:
Expedice: Zboží objednané jednoho dne obvykle expedujeme následující pracovní den, výjimečně den následující.
Doprava: Dopravce si vyhrazuje 1 až 2 pracovní dny na doručení. Konkrétní den či hodina doručení za příplatek.
Osobní odběr: Předem uhrazené zboží je možné vyzvednout a odvézt vlastní dopravou.
Paletové hospodářství: 3 až 40 rolí jede na Europaletě (výměnou při předání, nebo připočtena k ceně dopravy).
{/* VÝRAZNÁ SAMOSTATNÁ VÝZVA S TLAČÍTKEM "NEZÁVAZNÁ POPTÁVKA" */}
Rychlé ověření skladové dostupnosti a termínu
Máte vybráno {rolls} {rolls === 1 ? "roli" : rolls < 5 ? "role" : "rolí"} za {formatKc(displayTotal)} {includeVat ? "s DPH" : "bez DPH"}?
Kliknutím na tlačítko níže odešlete předvyplněnou poptávku. Obratem se vám ozveme s potvrzením termínu expedice a finálním vyčíslením dopravy.
openInquiry("standard")}
style={{
backgroundColor: "#dc2626",
color: "#ffffff",
padding: "18px 42px",
fontSize: 18,
fontWeight: 800,
borderRadius: 14,
border: "none",
cursor: "pointer",
boxShadow: "0 6px 20px rgba(220, 38, 38, 0.35)",
transition: "all 0.15s ease",
letterSpacing: "0.5px",
display: "inline-flex",
alignItems: "center",
gap: 12
}}
>
📩 NEZÁVAZNÁ POPTÁVKA
Nezávazná kalkulace • Rychlá odpověď do 24 hodin • Nebo volejte: +420 774 905 607
{/* Poptávkové modální okno */}
{showInquiryModal && (
setShowInquiryModal(false)}
style={{
position: "absolute",
top: 20,
right: 20,
backgroundColor: "#f1f5f9",
border: "none",
borderRadius: "50%",
width: 32,
height: 32,
fontSize: 16,
fontWeight: 700,
cursor: "pointer",
color: "#64748b"
}}
>
✕
{!inquirySent ? (
<>
{inquiryType === "partner" ? "PARTNERSKÁ VELKOOBCHODNÍ NABÍDKA" : "NEZÁVAZNÁ POPTÁVKA"}
{inquiryType === "partner" ? "Poptávka pro odběr nad 40 rolí (více palet)" : "Odeslat nezávaznou poptávku"}
{inquiryType === "partner"
? "Vyplňte údaje pro individuální projektovou cenovou nabídku. Můžete také volat přímo na +420 774 905 607."
: "Údaje z vaší kalkulace byly automaticky vloženy do poptávky."}
{/* Shrnutí kalkulace */}
{inquiryType === "partner" ? "Základní kalkulace z konfigurátoru:" : "Předvyplněná specifikace objednávky:"}
Počet rolí: {rolls} ks ({totalM2} m²)
Hmotnost: {totalWeight} kg
Typ dopravy: {shipping.type}
Cena celkem: {" "}
{formatKc(displayTotal)} {includeVat ? "s DPH" : "bez DPH"}
{payAdvance && (
✓ Zahrnuta 5% sleva při platbě předem zálohou (-{formatKc(advanceSavedTotal)})
)}
{/* Formulář */}