// ============================================================================ // Простая администраторская панель // — Добавление товаров и правка цен. Изменения хранятся в браузере // (localStorage) и сразу попадают в конструктор, пакеты, КП и заявки. // — Доступ по коду (по умолчанию ниже). Код можно сменить в ADMIN_PASS. // ============================================================================ const ADMIN_PASS = "razum2025"; // ← код доступа в админ-панель // Доступ к админке только по секретной ссылке /changes (замаскировано — не /admin). // Работает как https://razumdom38.ru/changes (на боевом домене), так и через // #changes / ?changes в превью и на статике. function rdAdminAllowed() { try { const path = location.pathname.replace(/\/+$/, "").toLowerCase(); const hash = (location.hash || "").toLowerCase(); const search = (location.search || "").toLowerCase(); return path.endsWith("/changes") || path.endsWith("/changes.html") || hash.includes("changes") || search.includes("changes"); } catch (e) { return false; } } const AdminPanel = () => { const RD = window.RD; const allowed = rdAdminAllowed(); const [open, setOpen] = React.useState(allowed); // по ссылке /changes — открыта сразу const [unlocked, setUnlocked] = React.useState(() => { try { return sessionStorage.getItem("rd_admin_ok") === "1"; } catch (e) { return false; } }); const [pass, setPass] = React.useState(""); const [passErr, setPassErr] = React.useState(false); const [, force] = React.useReducer((x) => x + 1, 0); // живой список при правках React.useEffect(() => RD.onCatalogChange(force), []); const tryUnlock = (e) => { e.preventDefault(); if (pass.trim() === ADMIN_PASS) { setUnlocked(true); setPassErr(false); try { sessionStorage.setItem("rd_admin_ok", "1"); } catch (e2) {} } else { setPassErr(true); } }; const groups = RD.groupOrder(); const sensors = RD.SENSORS; // ——— форма добавления ——— const [f, setF] = React.useState({ name: "", desc: "", group: groups[0] || "", newGroup: "", price: "", icon: "bulb" }); const upd = (k, v) => setF((s) => ({ ...s, [k]: v })); const addNow = () => { const grp = f.group === "__new__" ? f.newGroup.trim() : f.group; if (!f.name.trim() || !grp || !(Number(f.price) > 0)) return; RD.addProduct({ name: f.name, desc: f.desc, group: grp, price: f.price, icon: f.icon }); setF({ name: "", desc: "", group: grp, newGroup: "", price: "", icon: "bulb" }); }; // Для обычных посетителей админка полностью скрыта (нет даже кнопки). // Доступ — только по секретной ссылке /changes. if (!allowed) return null; return ( <> {/* Триггер */} {!open ? null : (