/* global React */
// Shared chrome (header + footer) and layout helpers for inner pages.
// Nav links route to the homepage anchors; "Вики" stays within the section.
const { Button, Input, Textarea } = window.DoslovnoByDesignSystem_88f6e6;
const DBIcon = window.DBIcon;
const DB_MAXW = "var(--container-max)";
/* --------------------------------------------------- flags (brand-neutral) */
const FLAGS = {
PL:` `,
DE:` `,
LT:` `,
CZ:` `,
IT:` `,
ES:` `,
FR:` `,
NL:` `,
US:` `,
CA:` `,
GB:` `,
AE:` `,
CN:` `,
IR:` `,
TM:` `,
};
const CODE3 = { PL:"POL", DE:"DEU", LT:"LTU", CZ:"CZE", US:"USA", CA:"CAN", IT:"ITA", ES:"ESP", FR:"FRA", NL:"NLD", GB:"GBR", AE:"ARE", CN:"CHN", IR:"IRN", TM:"TKM" };
// Префикс для ссылок: пустая строка из корня сайта, "../" из articles/
var LINK_PREFIX = (window.location.pathname.indexOf("/articles/") !== -1) ? "../" : "";
/* Country card with the flag-as-background treatment (settled variant):
flag fills the right at 30% opacity behind a white→translucent fade;
on hover the flag reaches full brightness and the fade clears. */
function FlagCard({ code, name, count, href }) {
href = href || (LINK_PREFIX + "articles.html");
const [hover, setHover] = React.useState(false);
return (
setHover(true)} onMouseLeave={() => setHover(false)}
style={{ position: "relative", overflow: "hidden", display: "flex", alignItems: "center", gap: 13,
border: `1px solid ${hover ? "var(--color-border-strong)" : "var(--color-border)"}`,
borderRadius: "var(--radius-lg)", padding: "15px 16px", background: "var(--color-canvas)",
transition: "border-color 140ms ease" }}>
{CODE3[code] || code}
{name}
{count} статей
);
}
function DBSection({ children, bg = "var(--surface-page)", id, style = {}, pad = "80px 24px" }) {
return (
);
}
function DBEyebrow({ children, onDark = false }) {
return (
{children}
);
}
const HEADER_LANGS = [["RU", "Русский"], ["BY", "Беларуская"], ["EN", "English"], ["PL", "Polski"]];
function LangSwitcher() {
const [cur, setCur] = React.useState("RU");
return (
setCur(e.target.value)}
style={{ appearance: "none", WebkitAppearance: "none", MozAppearance: "none", border: "none", outline: "none", background: "transparent", font: "inherit", fontFamily: "var(--font-body)", fontSize: 14, fontWeight: 700, color: "var(--color-navy-deep)", cursor: "pointer", padding: 0 }}>
{HEADER_LANGS.map(([code, name]) => ({name} ))}
▾
);
}
function DBHeader({ active }) {
var p = LINK_PREFIX;
const links = [
["Услуги", p + "index.html#services"],
["Доставка", p + "index.html#delivery"],
["Цены", p + "price.html", "prices"],
["Вики", p + "wiki.html", "wiki"],
["Контакты", p + "index.html#lead"],
];
const [hover, setHover] = React.useState(null);
return (
doslovno.by
{links.map(([label, href, key]) => {
const on = key === active;
return (
setHover(label)} onMouseLeave={() => setHover(null)}
style={{
position: "relative", textDecoration: "none", fontSize: 15, fontWeight: 600,
padding: "8px 12px", borderRadius: "var(--radius-pill)",
color: on || hover === label ? "var(--color-navy-deep)" : "var(--color-body)",
transition: "color 120ms ease",
}}>
{label}
{on && }
);
})}
);
}
function DBFooter() {
var p = LINK_PREFIX;
const col = (title, links) => (
{title}
{links.map(([label, href]) => (
{label}
))}
);
return (
);
}
/* ---- lead modal для страниц статей (Article, Articles) ---- */
const ARTICLE_LEAD_ENDPOINT = "";
async function submitArticleLead(payload) {
const lead = {
id: Date.now().toString(36) + Math.random().toString(36).slice(2, 7),
ts: new Date().toISOString(),
page: typeof location !== "undefined" ? location.pathname : "",
...payload,
};
try {
const k = "doslovno_leads";
const all = JSON.parse(localStorage.getItem(k) || "[]");
all.push(lead);
localStorage.setItem(k, JSON.stringify(all));
} catch (e) {}
if (ARTICLE_LEAD_ENDPOINT) {
await fetch(ARTICLE_LEAD_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(lead) });
}
console.log("[lead]", lead);
return lead;
}
function isPhoneOk(raw) { return (raw || "").replace(/\D/g, "").length >= 9; }
function ReqLabel({ text }) {
return {text} * ;
}
function AgreementCheck(props) {
return (
Согласен на обработку персональных данных
);
}
function ArticleLeadModal() {
const [open, setOpen] = React.useState(false);
const [name, setName] = React.useState("");
const [phone, setPhone] = React.useState("");
const [message, setMessage] = React.useState("");
const [consent, setConsent] = React.useState(false);
const [status, setStatus] = React.useState("idle");
const [touched, setTouched] = React.useState(false);
React.useEffect(() => {
const onOpen = (e) => {
setOpen(true);
setMessage((e.detail && e.detail.message) || "");
setName(""); setPhone(""); setConsent(false); setStatus("idle"); setTouched(false);
};
const onClose = () => setOpen(false);
window.addEventListener("doslovno:article-lead-open", onOpen);
window.addEventListener("doslovno:article-lead-close", onClose);
return () => {
window.removeEventListener("doslovno:article-lead-open", onOpen);
window.removeEventListener("doslovno:article-lead-close", onClose);
};
}, []);
React.useEffect(() => {
document.body.style.overflow = open ? "hidden" : "";
return () => { document.body.style.overflow = ""; };
}, [open]);
React.useEffect(() => {
const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
window.addEventListener("keydown", onKey);
return () => window.removeEventListener("keydown", onKey);
}, []);
const nameOk = name.trim().length > 0;
const phoneOk = isPhoneOk(phone);
const handleSubmit = async () => {
setTouched(true);
if (!nameOk || !phoneOk || !consent) return;
setStatus("sending");
try {
await submitArticleLead({ kind: "article_lead", name: name.trim(), phone: "+375" + phone.replace(/\D/g, "").slice(-9), message: message.trim() });
setStatus("sent");
} catch (e) { setStatus("error"); }
};
if (!open) return null;
return (
setOpen(false)} style={{ position: "fixed", inset: 0, zIndex: 100, background: "rgba(20,20,58,0.55)", backdropFilter: "blur(4px)", display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "6vh 16px 16px", overflowY: "auto" }}>
e.stopPropagation()} style={{ width: "100%", maxWidth: 460, position: "relative" }}>
setOpen(false)} aria-label="Закрыть" style={{ position: "absolute", top: -42, right: 0, background: "transparent", border: "none", cursor: "pointer", color: "#fff", display: "inline-flex", alignItems: "center", gap: 6, fontFamily: "var(--font-body)", fontSize: 15, fontWeight: 600 }}>
Закрыть
{status === "sent" ? (
Заявка принята
Перезвоним в течение 30 минут.
) : (
)}
);
}
function openArticleLead(message) {
window.dispatchEvent(new CustomEvent("doslovno:article-lead-open", { detail: { message: message || "" } }));
}
// Монтируем модал в отдельный корень — работает на любой странице, загружающей Shared.jsx
(function () {
const el = document.createElement("div");
document.body.appendChild(el);
ReactDOM.createRoot(el).render(React.createElement(ArticleLeadModal));
}());
Object.assign(window, { DBSection, DBEyebrow, DBHeader, DBFooter, DB_MAXW, FlagCard, FLAGS, CODE3, openArticleLead });