/* Модуль «Платежи» — финансовые транзакции проекта Показывает payments из API: дата, контрагент, сумма, назначение, статус */ window.RD = window.RD || { core: {}, modules: {} }; window.RD.modules.PaymentsTab = function PaymentsTab() { var store = RD.core.useStore(); var h = React.createElement; var fmt = RD.core; var useState = React.useState; var payments = store.raw.payments || []; var filterState = useState('all'); var filter = filterState[0]; var setFilter = filterState[1]; var filtered = filter === 'all' ? payments : payments.filter(function (p) { return p.status === filter; }); var totalPaid = payments.filter(function (p) { return p.status === 'paid'; }) .reduce(function (s, p) { return s + (p.amount || 0); }, 0); var totalPending = payments.filter(function (p) { return p.status === 'pending' || p.status === 'scheduled'; }) .reduce(function (s, p) { return s + (p.amount || 0); }, 0); var totalAmount = payments.reduce(function (s, p) { return s + (p.amount || 0); }, 0); function statusBadge(status) { var colors = { pending: { bg: 'var(--rd-surface-2)', text: 'var(--rd-text-muted)' }, scheduled: { bg: 'var(--rd-info)', text: '#fff' }, paid: { bg: 'var(--rd-good)', text: '#fff' }, partial: { bg: 'var(--rd-warn)', text: '#000' }, cancelled: { bg: 'var(--rd-bad)', text: '#fff' } }; var labels = { pending: 'Ожидание', scheduled: 'Запланирован', paid: 'Оплачен', partial: 'Частично', cancelled: 'Отменён' }; var c = colors[status] || colors.pending; return h('span', { style: { fontSize: 10, fontWeight: 700, background: c.bg, color: c.text, padding: '4px 8px', borderRadius: 6, textTransform: 'uppercase' } }, labels[status] || status); } return h('div', { style: { flex: 1, overflow: 'auto', padding: 20, display: 'flex', flexDirection: 'column', gap: 16 } }, // Header h('div', null, h('h2', { style: { fontSize: 20, fontWeight: 700, color: 'var(--rd-text)', marginBottom: 6 } }, 'Платежи'), h('p', { style: { fontSize: 13, color: 'var(--rd-text-muted)' } }, payments.length + ' платежей · ' + fmt.money(totalAmount) + ' всего' ) ), // KPI cards h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12 } }, h('div', { style: { background: 'var(--rd-surface)', border: '1px solid var(--rd-border)', borderRadius: 10, padding: 14 } }, h('div', { style: { fontSize: 11, color: 'var(--rd-text-muted)', fontWeight: 600, marginBottom: 4 } }, 'ВСЕГО ПЛАТЕЖЕЙ'), h('div', { style: { fontSize: 24, fontWeight: 700, color: 'var(--rd-text)' } }, payments.length) ), h('div', { style: { background: 'var(--rd-surface)', border: '1px solid var(--rd-border)', borderRadius: 10, padding: 14 } }, h('div', { style: { fontSize: 11, color: 'var(--rd-text-muted)', fontWeight: 600, marginBottom: 4 } }, 'ОПЛАЧЕНО'), h('div', { style: { fontSize: 18, fontWeight: 700, color: 'var(--rd-good)' } }, fmt.money(totalPaid)) ), h('div', { style: { background: 'var(--rd-surface)', border: '1px solid var(--rd-border)', borderRadius: 10, padding: 14 } }, h('div', { style: { fontSize: 11, color: 'var(--rd-text-muted)', fontWeight: 600, marginBottom: 4 } }, 'ОЖИДАЕТ ОПЛАТЫ'), h('div', { style: { fontSize: 18, fontWeight: 700, color: 'var(--rd-warn)' } }, fmt.money(totalPending)) ), h('div', { style: { background: 'var(--rd-surface)', border: '1px solid var(--rd-border)', borderRadius: 10, padding: 14 } }, h('div', { style: { fontSize: 11, color: 'var(--rd-text-muted)', fontWeight: 600, marginBottom: 4 } }, 'ОБЩАЯ СУММА'), h('div', { style: { fontSize: 18, fontWeight: 700, color: 'var(--rd-accent)' } }, fmt.money(totalAmount)) ) ), // Filters h('div', { style: { display: 'flex', gap: 8, flexWrap: 'wrap' } }, ['all', 'pending', 'scheduled', 'paid', 'partial', 'cancelled'].map(function (f) { var labels = { all: 'Все', pending: 'Ожидание', scheduled: 'Запланированы', paid: 'Оплачены', partial: 'Частичные', cancelled: 'Отменённые' }; var isActive = filter === f; return h('button', { key: f, onClick: function () { setFilter(f); }, style: { fontSize: 12, fontWeight: 600, padding: '8px 14px', border: '1px solid var(--rd-border)', borderRadius: 8, background: isActive ? 'var(--rd-accent)' : 'var(--rd-surface)', color: isActive ? '#fff' : 'var(--rd-text)', cursor: 'pointer', transition: 'all 0.2s' } }, labels[f]); }) ), // Table h('div', { style: { background: 'var(--rd-surface)', border: '1px solid var(--rd-border)', borderRadius: 12, overflow: 'hidden' } }, h('table', { style: { width: '100%', borderCollapse: 'collapse' } }, h('thead', null, h('tr', { style: { background: 'var(--rd-surface-2)', borderBottom: '1px solid var(--rd-border)' } }, ['Дата', 'Контрагент', 'Назначение', 'Сумма', 'Категория', 'Статус'].map(function (col) { return h('th', { key: col, style: { padding: '12px 14px', textAlign: 'left', fontSize: 11, fontWeight: 700, color: 'var(--rd-text-muted)', textTransform: 'uppercase' } }, col); }) ) ), h('tbody', null, filtered.length === 0 ? h('tr', null, h('td', { colSpan: 6, style: { padding: 40, textAlign: 'center', color: 'var(--rd-text-muted)', fontSize: 13 } }, 'Нет платежей')) : filtered.map(function (p, i) { return h('tr', { key: p.id || i, style: { borderBottom: i < filtered.length - 1 ? '1px solid var(--rd-border)' : 'none', transition: 'background 0.2s' }, onMouseEnter: function (e) { e.currentTarget.style.background = 'var(--rd-surface-2)'; }, onMouseLeave: function (e) { e.currentTarget.style.background = 'transparent'; } }, h('td', { style: { padding: '12px 14px', fontSize: 12, color: 'var(--rd-text-2)' } }, p.date ? fmt.dayLabel(p.date) : (p.dueDate ? fmt.dayLabel(p.dueDate) : '—') ), h('td', { style: { padding: '12px 14px', fontSize: 12, fontWeight: 600, color: 'var(--rd-text)' } }, p.contractor || p.recipient || 'Не указан'), h('td', { style: { padding: '12px 14px', fontSize: 12, color: 'var(--rd-text-2)' } }, p.purpose || p.description || '—'), h('td', { style: { padding: '12px 14px', fontSize: 13, fontWeight: 700, color: 'var(--rd-accent)' } }, fmt.money(p.amount || 0)), h('td', { style: { padding: '12px 14px', fontSize: 11, color: 'var(--rd-text-muted)' } }, p.category || '—'), h('td', { style: { padding: '12px 14px' } }, statusBadge(p.status || 'pending')) ); }) ) ) ) ); };