// contacts-page.jsx — Довідник зовнішніх контактів // Зведення з наявних модулів (не дублює дані): Замовники, Підрядники, Ліди. // Контакти команди живуть у Команда → Профілі (єдине місце), тут їх немає. // Розбір рядка контакту "Ім'я · +380… · email" у частини function parseContactStr(str) { const parts = String(str || "").split("·").map(s => s.trim()).filter(Boolean); let name = "", phone = "", email = "", extra = ""; parts.forEach(p => { if (/@/.test(p)) email = p; else if (/\+?\d[\d\s().-]{6,}/.test(p)) phone = p; else if (!name) name = p; else extra = p; }); return { name, phone, email, extra }; } function initialsOf(name) { return String(name || "?").trim().split(/\s+/).map(w => w[0]).slice(0, 2).join("").toUpperCase(); } const CONTACT_TYPES = { client: { label: "Замовник", chip: "client" }, supplier: { label: "Підрядник", chip: "supplier" }, lead: { label: "Лід", chip: "lead" }, }; // Зведення всіх контактів window.allContacts = function () { const out = []; (window.DATA.CLIENTS || []).forEach(c => { const k = c.contact || {}; out.push({ id: "cl-" + c.id, type: "client", name: k.name || c.name, org: c.name, role: k.role || "", phone: k.phone || "", email: k.email || "", edrpou: c.edrpou || "", note: c.note || "" }); }); (window.DATA.SUPPLIERS || []).forEach(s => { const k = parseContactStr(s.contact); const cat = (window.SUPPLIER_CATEGORIES || {})[s.category]; out.push({ id: "su-" + s.id, type: "supplier", name: k.name || s.name, org: s.name, role: cat ? cat.label : "", phone: k.phone, email: k.email, edrpou: s.edrpou || "", note: s.note || "" }); }); (window.DATA.LEADS || []).forEach(l => { const k = parseContactStr(l.contact); const t = (window.LEAD_TYPE || {})[l.type]; out.push({ id: "ld-" + l.id, type: "lead", name: k.name || l.client, org: l.client, role: [l.name, t].filter(Boolean).join(" · "), phone: k.phone, email: k.email, edrpou: "", note: k.extra || "" }); }); // Команда навмисно не зводиться сюди — контакти співробітників лише у Команда → Профілі. return out; }; function ContactsPage({ role }) { const all = window.allContacts(); const [q, setQ] = React.useState(""); const [type, setType] = React.useState("all"); const counts = all.reduce((a, c) => { a[c.type] = (a[c.type] || 0) + 1; return a; }, {}); const ql = q.trim().toLowerCase(); let shown = all; if (type !== "all") shown = shown.filter(c => c.type === type); if (ql) shown = shown.filter(c => [c.name, c.org, c.role, c.phone, c.email, c.edrpou].filter(Boolean).join(" ").toLowerCase().includes(ql) ); shown = [...shown].sort((a, b) => a.name.localeCompare(b.name, "uk")); const pills = [ { id: "all", label: "Усі", n: all.length }, { id: "client", label: "Замовники", n: counts.client || 0 }, { id: "supplier", label: "Підрядники", n: counts.supplier || 0 }, { id: "lead", label: "Ліди", n: counts.lead || 0 }, ]; return (

Контакти

{all.length} контактів зведено з Замовників, Підрядників і Лідів
Довідник зовнішніх контактів. Дані тягнуться з відповідних модулів — щоб змінити контакт, редагуйте його у джерелі (Продажі → Замовники / Підрядники / Ліди). Контакти співробітників — у розділі Команда → Профілі.
{pills.map(p => ( ))}
setQ(e.target.value)} />
{shown.map(c => { const t = CONTACT_TYPES[c.type]; return ( ); })}
Контакт Тип Роль / організація Телефон Email ЄДРПОУ
{initialsOf(c.name)}
{c.name}
{c.note &&
{c.note}
}
{t.label}
{c.org}
{c.role &&
{c.role}
}
{c.phone ? {c.phone} : } {c.email ? {c.email} : } {c.edrpou || "—"}
{shown.length === 0 &&
Нічого не знайдено за запитом «{q}».
}
); } window.ContactsPage = ContactsPage;