// Main app + nav + small marquee/why strip
const Nav = () => (
);
// Marquee of "why" badges
const WhyStrip = () => {
const items = [
{ icon: "house", text: "Закладываем на этапе ремонта" },
{ icon: "gear", text: "Интеграция после ремонта" },
{ icon: "cloud-off", text: "Автономно без интернета" },
{ icon: "leaf", text: "Поддержка Zigbee" },
{ icon: "mic", text: "Голосовое управление" },
{ icon: "key", text: "Квартира или частный дом" },
{ icon: "phone", text: "Управление со смартфона" },
];
const row = [...items, ...items];
return (
{row.map((it, i) => (
{it.text}
·
))}
);
};
// ----- Tweaks (host) -----
const DEFAULTS = /*EDITMODE-BEGIN*/{
"hero": "promise",
"showWhyStrip": true,
"accent": "#E89A1C"
}/*EDITMODE-END*/;
function App() {
const [t, setT, setTweak] = useTweaks(DEFAULTS);
// Ре-рендер всего дерева при правках каталога в админ-панели
const [, forceCatalog] = React.useReducer((x) => x + 1, 0);
React.useEffect(() => window.RD.onCatalogChange(forceCatalog), []);
// Shared builder/quote state ---------------------------------------------
const [picked, setPicked] = React.useState(() => ({ ...window.RD.PACKAGES[0].compose })); // Базовый ~12 000 ₽
const [presetName, setPresetName] = React.useState(window.RD.PACKAGES[0].name);
const [kpNumber] = React.useState(() => window.RD.kpNumber());
const [consult, setConsult] = React.useState(false); // «Бесплатная консультация» как интерес заявки
const requestConsult = () => {
setConsult(true);
window.RD.scrollTo("contact");
};
// Готовый пакет → пересчитать состав в конструкторе
const selectPackage = (p) => {
setConsult(false);
setPicked({ ...p.compose });
setPresetName(p.name);
window.RD.scrollTo("builder");
};
// Готовый пакет → оставить заявку (прикрепляем пакет и ведём в контакты)
const requestPackage = (p) => {
setConsult(false);
setPicked({ ...p.compose });
setPresetName(p.name);
window.RD.scrollTo("contact");
};
// Apply accent live
React.useEffect(() => {
document.documentElement.style.setProperty("--accent", t.accent);
// shift accent-2 to darker variant
const c = t.accent;
document.documentElement.style.setProperty("--accent-2", shade(c, -0.15));
}, [t.accent]);
return (
<>
{t.showWhyStrip && }
setTweak("hero", v)}
/>
setTweak("showWhyStrip", v)}
/>
setTweak("accent", v)}
/>
>
);
}
// Darken/lighten helper
function shade(hex, amt) {
let c = hex.replace("#", "");
if (c.length === 3) c = c.split("").map(x => x + x).join("");
const r = parseInt(c.slice(0, 2), 16);
const g = parseInt(c.slice(2, 4), 16);
const b = parseInt(c.slice(4, 6), 16);
const f = (v) => Math.max(0, Math.min(255, Math.round(v + 255 * amt)));
return "#" + [f(r), f(g), f(b)].map(v => v.toString(16).padStart(2, "0")).join("");
}
ReactDOM.createRoot(document.getElementById("root")).render();