/* Модуль «Команда» (полный) — RACI (кто за что), бригады с составом, карточки людей (опыт/инструмент/допуски). Загружается обычным script. Team.jsx (рядом) — отдельный пример на чистом JSX через Babel. */ window.RD = window.RD || { core: {}, modules: {} }; window.RD.modules.TeamFull = function TeamFull() { var store = RD.core.useStore(); var h = React.createElement; var own = store.raw.ownership || [], brigades = store.raw.brigades || []; var perms = store.perms; var drawerRef = React.useState(null); var drawer = drawerRef[0], setDrawer = drawerRef[1]; var member = null; if (drawer) brigades.forEach(function (b) { (b.members || []).forEach(function (m) { if (m.id === drawer) member = { m: m, b: b }; }); }); var tabRef = React.useState('cards'); var tab = tabRef[0], setTab = tabRef[1]; if (tab === 'raw') { var people = []; brigades.forEach(function (b) { (b.members || []).forEach(function (m) { people.push(Object.assign({ бригада: b.name, специальность: b.trade }, m)); }); }); var ds = [['ЛЮДИ', people], ['БРИГАДЫ', brigades.map(function (b) { var c = Object.assign({}, b); delete c.members; c.состав = (b.members || []).length; return c; })], ['ПОСТАВЩИКИ', store.raw.suppliers || []], ['RACI', own]]; var fmt = function (v) { if (v == null) return ''; if (Array.isArray(v) || typeof v === 'object') return JSON.stringify(v); return '' + v; }; return h('div', { className: 'rd-main-content', style: { background: 'var(--rd-surface)', overflow: 'auto' } }, h('div', { style: { height: 46, flex: 'none', borderBottom: '1px solid var(--rd-border)', display: 'flex', alignItems: 'center', padding: '0 16px', gap: 10, background: 'var(--rd-surface-2)' } }, h('div', { style: { fontSize: 13, fontWeight: 600 } }, 'Команда'), h('div', { style: { flex: 1 } }), [['cards', 'Карточки'], ['raw', 'Все столбцы из БД']].map(function (t2) { return h('button', { key: t2[0], onClick: function () { setTab(t2[0]); }, style: { padding: '5px 11px', border: '1px solid var(--rd-border)', borderRadius: 7, background: tab === t2[0] ? 'var(--rd-accent-soft)' : 'var(--rd-surface)', color: tab === t2[0] ? 'var(--rd-accent)' : 'var(--rd-text-2)', fontSize: 11, fontWeight: tab === t2[0] ? 600 : 500, cursor: 'pointer' } }, t2[1]); })), h('div', { style: { padding: 12, overflow: 'auto' } }, ds.map(function (d) { var list = d[1]; if (!list.length) return null; var keys = []; list.forEach(function (x) { Object.keys(x).forEach(function (k) { if (keys.indexOf(k) < 0) keys.push(k); }); }); var grid = '40px ' + keys.map(function (k) { return (k === 'tools' || k === 'certs' || k === 'jobs' || k === 'note') ? '200px' : '110px'; }).join(' '); return h('div', { key: d[0], style: { marginBottom: 20 } }, h('div', { style: { fontSize: 11, fontWeight: 700, color: 'var(--rd-text-muted)', margin: '0 0 6px 2px' } }, d[0] + ' · ' + list.length + ' строк · ' + keys.length + ' столбцов'), h('div', { style: { border: '1px solid var(--rd-border)', borderRadius: 8, overflow: 'auto' } }, h('div', { style: { minWidth: 50 + keys.length * 112 } }, h('div', { style: { display: 'grid', gridTemplateColumns: grid, background: 'var(--rd-surface-3)', borderBottom: '1px solid var(--rd-border)', fontSize: 10, fontWeight: 600, color: 'var(--rd-text-muted)', position: 'sticky', top: 0 } }, [h('div', { key: 'n', style: { padding: '7px 8px' } }, '№')].concat(keys.map(function (k) { var hide = (k === 'rate' && !perms.seeBrigadeRates); return h('div', { key: k, style: { padding: '7px 8px' } }, hide ? (k + ' 🔒') : k); }))), list.map(function (x, i) { return h('div', { key: i, style: { display: 'grid', gridTemplateColumns: grid, borderBottom: '1px solid var(--rd-border)', fontSize: 11, alignItems: 'center', background: i % 2 ? 'var(--rd-surface-2)' : 'var(--rd-surface)' } }, [h('div', { key: 'n', className: 'mono', style: { padding: '5px 8px', color: 'var(--rd-text-muted)', fontSize: 10 } }, i + 1)].concat(keys.map(function (k) { var hide = (k === 'rate' && !perms.seeBrigadeRates); return h('div', { key: k, className: (typeof x[k] === 'number') ? 'mono' : '', style: { padding: '5px 8px', color: 'var(--rd-text-2)', fontSize: 10.5, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, hide ? '—' : fmt(x[k])); }))); }) ))) }) ) ); } return h('div', { className: 'rd-main-content', style: { background: 'var(--rd-surface)', overflow: 'auto' } }, h('div', { style: { display: 'flex', alignItems: 'center', padding: '12px 18px 0', gap: 10 } }, h('div', { style: { flex: 1 } }), [['cards', 'Карточки'], ['raw', 'Все столбцы из БД']].map(function (t2) { return h('button', { key: t2[0], onClick: function () { setTab(t2[0]); }, style: { padding: '5px 11px', border: '1px solid var(--rd-border)', borderRadius: 7, background: tab === t2[0] ? 'var(--rd-accent-soft)' : 'var(--rd-surface)', color: tab === t2[0] ? 'var(--rd-accent)' : 'var(--rd-text-2)', fontSize: 11, fontWeight: tab === t2[0] ? 600 : 500, cursor: 'pointer' } }, t2[1]); })), h('div', { style: { padding: 18 } }, h('div', { style: { fontSize: 12, fontWeight: 600, color: 'var(--rd-text-muted)', margin: '0 0 10px 2px' } }, 'КТО ЗА ЧТО ОТВЕЧАЕТ · RACI'), h('div', { style: { border: '1px solid var(--rd-border)', borderRadius: 12, overflow: 'hidden', marginBottom: 20 } }, h('div', { style: { display: 'grid', gridTemplateColumns: 'minmax(150px,1.2fr) minmax(160px,1.3fr) 1fr 1fr 1fr', background: 'var(--rd-surface-3)', borderBottom: '1px solid var(--rd-border)', fontSize: 10.5, fontWeight: 600, color: 'var(--rd-text-muted)' } }, ['Зона', 'Ответственный (R)', 'Утверждает (A)', 'Консультант (C)', 'Информируется (I)'].map(function (t, i) { return h('div', { key: i, style: { padding: '9px 12px' } }, t); })), own.map(function (o, i) { return h('div', { key: i, style: { display: 'grid', gridTemplateColumns: 'minmax(150px,1.2fr) minmax(160px,1.3fr) 1fr 1fr 1fr', borderBottom: '1px solid var(--rd-border)', fontSize: 12, alignItems: 'center' } }, h('div', { style: { padding: '10px 12px', fontWeight: 600 } }, o.area), h('div', { style: { padding: '10px 12px', display: 'flex', alignItems: 'center', gap: 8 } }, h('span', { style: { width: 28, height: 28, borderRadius: '50%', background: o.color || 'var(--rd-accent)', color: '#fff', fontSize: 10, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center' } }, o.avatar), h('div', null, h('div', { style: { fontWeight: 500 } }, o.owner), h('div', { style: { fontSize: 10.5, color: 'var(--rd-text-muted)' } }, o.role))), h('div', { style: { padding: '10px 12px', color: 'var(--rd-text-2)' } }, o.acc), h('div', { style: { padding: '10px 12px', color: 'var(--rd-text-2)' } }, o.cons), h('div', { style: { padding: '10px 12px', color: 'var(--rd-text-muted)' } }, o.inf)); })), h('div', { style: { fontSize: 12, fontWeight: 600, color: 'var(--rd-text-muted)', margin: '0 0 10px 2px' } }, 'БРИГАДЫ · клик по человеку — карточка'), h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill,minmax(320px,1fr))', gap: 14 } }, brigades.map(function (b) { return h('div', { key: b.id, style: { border: '1px solid var(--rd-border)', borderRadius: 12, overflow: 'hidden', background: 'var(--rd-surface)', display: 'flex' } }, h('div', { style: { width: 3, alignSelf: 'stretch', background: b.color || 'var(--rd-accent)', flex: 'none' } }), h('div', { style: { flex: 1, minWidth: 0 } }, h('div', { style: { padding: '12px 14px 10px' } }, h('div', { style: { display: 'flex', alignItems: 'center', gap: 8 } }, h('span', { style: { fontSize: 13.5, fontWeight: 600 } }, b.name), h('span', { style: { flex: 1 } }), h('span', { style: { fontSize: 11, color: '#e3a008', fontWeight: 700 } }, '★ ' + (b.rating || 0).toFixed(1))), h('div', { style: { fontSize: 11, color: 'var(--rd-text-muted)', marginTop: 3 } }, b.trade + ' · ' + b.size + ' чел · бригадир ' + b.lead)), (b.members || []).map(function (m) { return h('div', { key: m.id, onClick: function () { setDrawer(m.id); }, style: { display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', borderTop: '1px solid var(--rd-border)', cursor: 'pointer' } }, h('span', { style: { width: 28, height: 28, borderRadius: '50%', background: (b.color || 'var(--rd-accent)') + '22', color: b.color || 'var(--rd-accent)', fontSize: 10, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center' } }, m.name.split(' ').map(function (x) { return x[0]; }).join('')), h('div', { style: { flex: 1, minWidth: 0 } }, h('div', { style: { fontSize: 12, fontWeight: 500 } }, m.name), h('div', { style: { fontSize: 10.5, color: 'var(--rd-text-muted)' } }, m.role + ' · опыт ' + m.exp + ' лет')), h('span', { style: { fontSize: 11, color: '#e3a008', fontWeight: 600 } }, '★ ' + (m.rating || 0).toFixed(1)), h('span', { style: { fontSize: 13, color: 'var(--rd-text-faint)' } }, '›')); }))) })) ), // drawer карточки человека member ? h('div', { onClick: function () { setDrawer(null); }, style: { position: 'fixed', inset: 0, background: 'rgba(0,0,0,.34)', zIndex: 60, display: 'flex', justifyContent: 'flex-end' } }, h('div', { onClick: function (e) { e.stopPropagation(); }, style: { width: 400, maxWidth: '92vw', height: '100%', background: 'var(--rd-surface)', boxShadow: '-12px 0 40px rgba(0,0,0,.2)', overflow: 'auto' } }, h('div', { style: { padding: 18, borderBottom: '1px solid var(--rd-border)', display: 'flex', alignItems: 'center', gap: 13 } }, h('div', { style: { width: 48, height: 48, borderRadius: '50%', background: member.b.color || 'var(--rd-accent)', color: '#fff', fontSize: 17, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 'none' } }, member.m.name.split(' ').map(function (x) { return x[0]; }).join('')), h('div', { style: { flex: 1 } }, h('div', { style: { fontSize: 16, fontWeight: 600 } }, member.m.name), h('div', { style: { fontSize: 11.5, color: 'var(--rd-text-muted)' } }, member.m.role + ' · ' + member.b.name)), h('button', { onClick: function () { setDrawer(null); }, style: { border: 'none', background: 'none', fontSize: 20, color: 'var(--rd-text-muted)', cursor: 'pointer' } }, '×')), h('div', { style: { padding: 16 } }, h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 9, marginBottom: 16 } }, [['Возраст', (member.m.age || '—') + ' лет'], ['Опыт', member.m.exp + ' лет'], ['Рейтинг', (member.m.rating || 0).toFixed(1) + ' ★'], ['Ставка', member.m.rate || '—']].map(function (s, i) { return h('div', { key: i, style: { border: '1px solid var(--rd-border)', borderRadius: 9, padding: '9px 11px', background: 'var(--rd-surface-2)' } }, h('div', { style: { fontSize: 10.5, color: 'var(--rd-text-muted)', marginBottom: 3 } }, s[0]), h('div', { className: 'mono', style: { fontSize: 14, fontWeight: 700 } }, s[1])); })), member.m.tools ? h('div', { style: { marginBottom: 14 } }, h('div', { style: { fontSize: 10, fontWeight: 600, color: 'var(--rd-text-muted)', marginBottom: 7, letterSpacing: .4 } }, 'ИНСТРУМЕНТ'), h('div', { style: { display: 'flex', flexWrap: 'wrap', gap: 6 } }, member.m.tools.map(function (t, i) { return h('span', { key: i, style: { fontSize: 11, color: 'var(--rd-text)', background: 'var(--rd-surface-3)', borderRadius: 13, padding: '4px 10px' } }, t); }))) : null, member.m.certs ? h('div', { style: { marginBottom: 14 } }, h('div', { style: { fontSize: 10, fontWeight: 600, color: 'var(--rd-text-muted)', marginBottom: 7, letterSpacing: .4 } }, 'ДОПУСКИ / СЕРТИФИКАТЫ'), h('div', { style: { display: 'flex', flexWrap: 'wrap', gap: 6 } }, member.m.certs.map(function (t, i) { return h('span', { key: i, style: { fontSize: 11, color: 'var(--rd-good)', background: 'var(--rd-good-soft,#e7f4ec)', borderRadius: 13, padding: '4px 10px' } }, t); }))) : null, member.m.note ? h('div', { style: { border: '1px solid var(--rd-border)', borderRadius: 9, padding: '11px 12px', marginBottom: 9 } }, h('div', { style: { fontSize: 10.5, color: 'var(--rd-text-muted)', marginBottom: 4 } }, 'ОЦЕНКА ПРОРАБА'), h('div', { style: { fontSize: 12, color: 'var(--rd-text)', lineHeight: 1.4 } }, member.m.note)) : null, member.m.wants ? h('div', { style: { border: '1px solid #cdd7fb', background: 'var(--rd-accent-soft)', borderRadius: 9, padding: '11px 12px' } }, h('div', { style: { fontSize: 10.5, color: 'var(--rd-accent)', fontWeight: 600, marginBottom: 4 } }, 'ХОЧЕТ РАЗВИВАТЬСЯ В'), h('div', { style: { fontSize: 12, color: 'var(--rd-text)', lineHeight: 1.4 } }, member.m.wants)) : null ) ) ) : null ); };