58 lines
2.8 KiB
React
58 lines
2.8 KiB
React
const money = (v) => Number(v).toLocaleString('ru-RU', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
|
|
function BigTile({ label, value, color }) {
|
|
return (
|
|
<div style={{ flex: '1 1 160px', minWidth: '150px' }}>
|
|
<p style={{ fontSize: '0.78rem', color: 'var(--text-muted)', marginBottom: '4px' }}>{label}</p>
|
|
<p style={{ fontSize: '1.35rem', fontWeight: 590, color: color || 'var(--text-main)' }}>{money(value)} ₽</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function BreakdownRow({ label, value, hint }) {
|
|
return (
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', padding: '7px 0', borderBottom: '1px solid var(--border-light)' }}>
|
|
<span style={{ fontSize: '0.85rem', color: 'var(--text-muted)' }}>{label}{hint ? <span style={{ fontSize: '0.74rem' }}> {hint}</span> : null}</span>
|
|
<span style={{ fontSize: '0.92rem', fontWeight: 510 }}>{money(value)} ₽</span>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
// Live view of one staff member's pay — reused by both the owner-facing
|
|
// StaffPayrollModal (any staff, via api.payroll.summary) and the
|
|
// self-service MyPayrollPage (own numbers only, via api.payroll.mySummary).
|
|
// Deliberately no dependence on which endpoint fed it — same shape either
|
|
// way (see backend's internal/payroll/summary.go staffSummary struct).
|
|
function PayrollSummaryCard({ summary, loading }) {
|
|
if (loading) return <p style={{ color: 'var(--text-muted)', fontSize: '0.85rem' }}>Загрузка...</p>
|
|
if (!summary) return null
|
|
|
|
const owed = Number(summary.owed_total)
|
|
|
|
return (
|
|
<div className="glass-panel" style={{ padding: '18px', marginBottom: '18px' }}>
|
|
<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap', marginBottom: '16px' }}>
|
|
<BigTile label="Заработано всего" value={summary.earned_total} />
|
|
<BigTile label="Выплачено" value={summary.paid_total} color="var(--color-success, #16a34a)" />
|
|
<BigTile label="Осталось выплатить" value={summary.owed_total} color={owed > 0 ? 'var(--color-warn, #d97706)' : undefined} />
|
|
</div>
|
|
<div>
|
|
<BreakdownRow label="За смены" value={summary.shift_earned} />
|
|
<BreakdownRow
|
|
label="Проценты с заявок"
|
|
value={summary.commission_earned}
|
|
hint={summary.pending_orders > 0 ? `(в т.ч. ${summary.pending_orders} ещё не оформлено в начисление)` : ''}
|
|
/>
|
|
<BreakdownRow
|
|
label="За картриджи"
|
|
value={summary.cartridge_earned}
|
|
hint={summary.pending_cartridges > 0 ? `(в т.ч. ${summary.pending_cartridges} ещё не оформлено в начисление)` : ''}
|
|
/>
|
|
<BreakdownRow label="Корректировки" value={summary.adjustment_total} />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default PayrollSummaryCard
|