PY wages/sales as sub-labels not separate cards
Show PY value + % change as a subtitle line under the period card, same pattern as the original PY sales sub-label. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1d7cb229e4
commit
dc1a14a070
2 changed files with 18 additions and 29 deletions
|
|
@ -131,7 +131,12 @@ export default function Monthly() {
|
||||||
const pctBudget = budget != null && budget > 0 ? (totalForecast / budget) * 100 : null
|
const pctBudget = budget != null && budget > 0 ? (totalForecast / budget) * 100 : null
|
||||||
const pctSales = netSales > 0 ? (totalActual / netSales) * 100 : null
|
const pctSales = netSales > 0 ? (totalActual / netSales) * 100 : null
|
||||||
const variance = budget != null ? totalForecast - budget : null
|
const variance = budget != null ? totalForecast - budget : null
|
||||||
const pyWagesDiff = pyWages != null && totalActual > 0 ? totalActual - pyWages : null
|
|
||||||
|
function pyPct(current: number, py: number): string {
|
||||||
|
if (py <= 0 || current <= 0) return ''
|
||||||
|
const p = ((current - py) / py) * 100
|
||||||
|
return ` (${p >= 0 ? '+' : ''}${p.toFixed(1)}%)`
|
||||||
|
}
|
||||||
|
|
||||||
// Build chart data with per-dept costs per week so Bar dataKey works
|
// Build chart data with per-dept costs per week so Bar dataKey works
|
||||||
type WeekEntry = { label: string; isPast: boolean; [dept: string]: number | boolean | string }
|
type WeekEntry = { label: string; isPast: boolean; [dept: string]: number | boolean | string }
|
||||||
|
|
@ -187,15 +192,7 @@ export default function Monthly() {
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
<div className="label">{isCurrentMonth ? 'Actual MTD' : 'Actual'}</div>
|
<div className="label">{isCurrentMonth ? 'Actual MTD' : 'Actual'}</div>
|
||||||
<div className="value">{fmtMoney(totalActual)}</div>
|
<div className="value">{fmtMoney(totalActual)}</div>
|
||||||
</div>
|
{pyWages != null && <div className="sub">PY {fmtMoney(pyWages)}{pyPct(totalActual, pyWages)}</div>}
|
||||||
<div className="summary-card">
|
|
||||||
<div className="label">{isCurrentMonth ? 'PY Wages MTD' : 'PY Wages'}</div>
|
|
||||||
<div className="value">{pyWages != null ? fmtMoney(pyWages) : '—'}</div>
|
|
||||||
{pyWagesDiff != null && (
|
|
||||||
<div className={`sub ${pyWagesDiff > 0 ? 'variance-over' : 'variance-under'}`}>
|
|
||||||
{pyWagesDiff > 0 ? '+' : ''}{fmtMoney(pyWagesDiff)} vs PY
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{isCurrentMonth && (
|
{isCurrentMonth && (
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
|
|
@ -224,10 +221,7 @@ export default function Monthly() {
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
<div className="label">{isCurrentMonth ? 'Net Sales MTD' : 'Net Sales'}</div>
|
<div className="label">{isCurrentMonth ? 'Net Sales MTD' : 'Net Sales'}</div>
|
||||||
<div className="value">{fmtMoney(netSales)}</div>
|
<div className="value">{fmtMoney(netSales)}</div>
|
||||||
</div>
|
{pySales > 0 && <div className="sub">PY {fmtMoney(pySales)}{pyPct(netSales, pySales)}</div>}
|
||||||
<div className="summary-card">
|
|
||||||
<div className="label">{isCurrentMonth ? 'PY Net Sales MTD' : 'PY Net Sales'}</div>
|
|
||||||
<div className="value">{pySales > 0 ? fmtMoney(pySales) : '—'}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
<div className="label">% Net Sales</div>
|
<div className="label">% Net Sales</div>
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,12 @@ export default function Weekly() {
|
||||||
const totalWages = deptTotals.reduce((s, d) => s + d.cost, 0)
|
const totalWages = deptTotals.reduce((s, d) => s + d.cost, 0)
|
||||||
const pctBudget = budget != null && budget > 0 ? (totalWages / budget) * 100 : null
|
const pctBudget = budget != null && budget > 0 ? (totalWages / budget) * 100 : null
|
||||||
const pctSales = netSales > 0 ? (totalWages / netSales) * 100 : null
|
const pctSales = netSales > 0 ? (totalWages / netSales) * 100 : null
|
||||||
const pyWagesDiff = pyWages != null && totalWages > 0 ? totalWages - pyWages : null
|
|
||||||
|
function pyPct(current: number, py: number): string {
|
||||||
|
if (py <= 0 || current <= 0) return ''
|
||||||
|
const p = ((current - py) / py) * 100
|
||||||
|
return ` (${p >= 0 ? '+' : ''}${p.toFixed(1)}%)`
|
||||||
|
}
|
||||||
|
|
||||||
const weekLabel = `${fmtDisplay(fromStr)} – ${fmtDisplay(toStr)} ${new Date(toStr + 'T00:00:00').getFullYear()}`
|
const weekLabel = `${fmtDisplay(fromStr)} – ${fmtDisplay(toStr)} ${new Date(toStr + 'T00:00:00').getFullYear()}`
|
||||||
|
|
||||||
|
|
@ -148,16 +153,9 @@ export default function Weekly() {
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
<div className="label">Total Wages</div>
|
<div className="label">Total Wages</div>
|
||||||
<div className="value">{fmtMoney(totalWages)}</div>
|
<div className="value">{fmtMoney(totalWages)}</div>
|
||||||
<div className="sub">{showOncosts ? 'incl. on-costs' : 'base cost'}</div>
|
{pyWages != null
|
||||||
</div>
|
? <div className="sub">PY {fmtMoney(pyWages)}{pyPct(totalWages, pyWages)}</div>
|
||||||
<div className="summary-card">
|
: <div className="sub">{showOncosts ? 'incl. on-costs' : 'base cost'}</div>}
|
||||||
<div className="label">PY Wages</div>
|
|
||||||
<div className="value">{pyWages != null ? fmtMoney(pyWages) : '—'}</div>
|
|
||||||
{pyWagesDiff != null && (
|
|
||||||
<div className={`sub ${pyWagesDiff > 0 ? 'variance-over' : 'variance-under'}`}>
|
|
||||||
{pyWagesDiff > 0 ? '+' : ''}{fmtMoney(pyWagesDiff)} vs PY
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
<div className="label">Pro-rata Budget</div>
|
<div className="label">Pro-rata Budget</div>
|
||||||
|
|
@ -175,10 +173,7 @@ export default function Weekly() {
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
<div className="label">Net Sales</div>
|
<div className="label">Net Sales</div>
|
||||||
<div className="value">{fmtMoney(netSales)}</div>
|
<div className="value">{fmtMoney(netSales)}</div>
|
||||||
</div>
|
{pySales > 0 && <div className="sub">PY {fmtMoney(pySales)}{pyPct(netSales, pySales)}</div>}
|
||||||
<div className="summary-card">
|
|
||||||
<div className="label">PY Net Sales</div>
|
|
||||||
<div className="value">{pySales > 0 ? fmtMoney(pySales) : '—'}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="summary-card">
|
<div className="summary-card">
|
||||||
<div className="label">% of Net Sales</div>
|
<div className="label">% of Net Sales</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue