Summary table: split Rooms and D/S/A into separate columns per day
Match the original WP plugin layout — left cell has occupied count, vac, and pickup controls; right cell has departs/stays/arrivals stacked vertically, right-aligned, with delta indicators above them. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
135f1f6cf0
commit
31fd73ce1e
1 changed files with 70 additions and 70 deletions
|
|
@ -439,10 +439,10 @@ function SummaryTable({ bookings, pickup, onPickupChange }: SummaryProps) {
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
{dates.map(d => (
|
{dates.map(d => (
|
||||||
<th key={d} colSpan={2} style={{ fontSize: '0.72rem', fontWeight: 400, background: '#1e2d42' }}>
|
<>
|
||||||
<span style={{ padding: '0 0.5rem' }}>Occ</span>
|
<th key={d + '-r'} style={{ fontSize: '0.72rem', fontWeight: 400, background: '#1e2d42', minWidth: '72px' }}>Rooms</th>
|
||||||
<span style={{ borderLeft: '1px solid rgba(255,255,255,0.15)', padding: '0 0.5rem' }}>D / S / A</span>
|
<th key={d + '-d'} style={{ fontSize: '0.72rem', fontWeight: 400, background: '#1e2d42', minWidth: '56px', borderLeft: '1px solid rgba(255,255,255,0.1)' }}>D / S / A</th>
|
||||||
</th>
|
</>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
@ -471,65 +471,61 @@ function CatRows({ cat, dates, pickup, onPickupChange, isLast }: {
|
||||||
onPickupChange: (date: string, delta: number) => void
|
onPickupChange: (date: string, delta: number) => void
|
||||||
isLast: boolean
|
isLast: boolean
|
||||||
}) {
|
}) {
|
||||||
|
const bbStyle = isLast ? '2px solid var(--card-border)' : undefined
|
||||||
return (
|
return (
|
||||||
<>
|
<tr>
|
||||||
{/* Row 1: Occ + Departs */}
|
<td className="col-label" style={{ borderBottom: bbStyle }}>{cat.name}</td>
|
||||||
<tr className="row-depart">
|
{dates.map((date, di) => {
|
||||||
<td className="col-label" rowSpan={3} style={{ borderBottom: isLast ? '2px solid var(--card-border)' : undefined }}>
|
const d = cat.days[date]
|
||||||
{cat.name}
|
const occupied = d.stays + d.arrivals
|
||||||
</td>
|
const vacant = Math.max(0, cat.total_rooms - occupied)
|
||||||
{dates.map((date, di) => {
|
const pu = getDisplayPickup(pickup, cat.id, date, occupied, cat.total_rooms)
|
||||||
const d = cat.days[date]
|
const prevDate = dates[di - 1]
|
||||||
const occupied = d.stays + d.arrivals
|
const prevOcc = prevDate ? (cat.days[prevDate].stays + cat.days[prevDate].arrivals) : 0
|
||||||
const vacant = Math.max(0, cat.total_rooms - occupied)
|
const prevPu = prevDate ? getDisplayPickup(pickup, cat.id, prevDate, prevOcc, cat.total_rooms) : 0
|
||||||
const pu = getDisplayPickup(pickup, cat.id, date, occupied, cat.total_rooms)
|
const dNew = d.delta_new || 0
|
||||||
const prevDate = dates[di - 1]
|
const dCanc = d.delta_cancelled || 0
|
||||||
const prevOcc = prevDate ? (cat.days[prevDate].stays + cat.days[prevDate].arrivals) : 0
|
|
||||||
const prevPu = prevDate ? getDisplayPickup(pickup, cat.id, prevDate, prevOcc, cat.total_rooms) : 0
|
|
||||||
const dNew = d.delta_new || 0
|
|
||||||
const dCanc = d.delta_cancelled || 0
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<td key={date} colSpan={2} rowSpan={3}
|
<>
|
||||||
style={{ verticalAlign: 'top', paddingTop: '0.5rem',
|
{/* Left cell: Rooms / vac / pickup controls */}
|
||||||
borderBottom: isLast ? '2px solid var(--card-border)' : undefined }}>
|
<td key={date + '-r'} style={{ textAlign: 'center', verticalAlign: 'middle', borderBottom: bbStyle, padding: '0.4rem 0.3rem' }}>
|
||||||
{(dNew > 0 || dCanc > 0) && (
|
<div style={{ fontWeight: 700, fontSize: '1.1rem' }}>
|
||||||
<div style={{ display: 'flex', justifyContent: 'center', gap: '0.25rem', marginBottom: '2px' }}>
|
{occupied}{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
||||||
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
|
||||||
{dCanc > 0 && <span className="delta-canc">▼{dCanc}</span>}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div style={{ textAlign: 'center', fontWeight: 700, fontSize: '1rem' }}>
|
|
||||||
{occupied}
|
|
||||||
{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
|
||||||
</div>
|
</div>
|
||||||
<div style={{ textAlign: 'center', fontSize: '0.78rem', color: 'var(--text-mid)' }}>
|
<div style={{ fontSize: '0.72rem', color: 'var(--text-mid)', marginBottom: '4px' }}>
|
||||||
{vacant} vac{pu > 0 && <span className="pickup-tag"> ({vacant - pu})</span>}
|
{vacant} vac{pu > 0 && <span className="pickup-tag"> ({vacant - pu})</span>}
|
||||||
</div>
|
</div>
|
||||||
<div className="pickup-ctrl">
|
<div className="pickup-ctrl">
|
||||||
<button className="pickup-btn" disabled={pu <= 0}
|
<button className="pickup-btn" disabled={pu <= 0} onClick={() => onPickupChange(date, -1)}>−</button>
|
||||||
onClick={() => onPickupChange(date, -1)}>−</button>
|
|
||||||
<span className="pickup-num">{pu}</span>
|
<span className="pickup-num">{pu}</span>
|
||||||
<button className="pickup-btn" disabled={pu >= vacant}
|
<button className="pickup-btn" disabled={pu >= vacant}
|
||||||
title={d.pickup_hint > 0 ? `${d.pickup_hint} late pickup${d.pickup_hint > 1 ? 's' : ''} last ${getDayName(date)}` : 'No late pickups last week'}
|
title={d.pickup_hint > 0 ? `${d.pickup_hint} late pickup${d.pickup_hint > 1 ? 's' : ''} last ${getDayName(date)}` : 'No late pickups last week'}
|
||||||
onClick={() => onPickupChange(date, 1)}>+</button>
|
onClick={() => onPickupChange(date, 1)}>+</button>
|
||||||
</div>
|
</div>
|
||||||
{/* D/S/A breakdown: sits to the right via colSpan trick — shown as sub-rows via CSS */}
|
</td>
|
||||||
<div style={{ fontSize: '0.72rem', color: 'var(--text-mid)', textAlign: 'center', marginTop: '4px', borderTop: '1px dashed var(--card-border)', paddingTop: '3px' }}>
|
{/* Right cell: D / S / A */}
|
||||||
<span style={{ color: '#c2502e' }}>{d.departs}d{prevPu > 0 && <span className="pickup-tag"> +{prevPu}</span>}</span>
|
<td key={date + '-dsa'} style={{ verticalAlign: 'middle', borderLeft: '1px solid var(--card-border)', borderBottom: bbStyle, padding: '0.4rem 0.5rem 0.4rem 0.4rem', textAlign: 'right' }}>
|
||||||
{' / '}
|
{(dNew > 0 || dCanc > 0) && (
|
||||||
<span style={{ color: '#1d6fb8' }}>{d.stays}s</span>
|
<div style={{ marginBottom: '3px' }}>
|
||||||
{' / '}
|
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
||||||
<span style={{ color: '#1a7a4a' }}>{d.arrivals}a{pu > 0 && <span className="pickup-tag"> +{pu}</span>}</span>
|
{dCanc > 0 && <span className="delta-canc"> ▼{dCanc}</span>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div style={{ fontSize: '0.8rem', color: '#c2502e', fontWeight: 600 }}>
|
||||||
|
{d.departs}d{prevPu > 0 && <span className="pickup-tag"> +{prevPu}</span>}
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: '0.8rem', color: '#1d6fb8', fontWeight: 600 }}>
|
||||||
|
{d.stays}s
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: '0.8rem', color: '#1a7a4a', fontWeight: 600 }}>
|
||||||
|
{d.arrivals}a{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
)
|
</>
|
||||||
})}
|
)
|
||||||
</tr>
|
})}
|
||||||
{/* Rows 2 & 3 are consumed by rowSpan — needed for tbody structure */}
|
</tr>
|
||||||
<tr className="row-stay" />
|
|
||||||
<tr className={`row-arrive${isLast ? ' row-group-last' : ''}`} />
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,27 +554,31 @@ function TotalRows({ dates, cats, pickup }: {
|
||||||
dCanc += d.delta_cancelled || 0
|
dCanc += d.delta_cancelled || 0
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<td key={date} colSpan={2}>
|
<>
|
||||||
{(dNew > 0 || dCanc > 0) && (
|
<td key={date + '-r'} style={{ textAlign: 'center', verticalAlign: 'middle', padding: '0.4rem 0.3rem' }}>
|
||||||
<div style={{ display: 'flex', justifyContent: 'center', gap: '0.25rem', marginBottom: '2px' }}>
|
<div style={{ fontWeight: 700, fontSize: '1.1rem' }}>
|
||||||
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
{occupied}{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
||||||
{dCanc > 0 && <span className="delta-canc">▼{dCanc}</span>}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
<div style={{ fontSize: '0.72rem', color: 'var(--text-mid)' }}>
|
||||||
<div style={{ fontWeight: 700 }}>
|
{vacant} vac{pu > 0 && <span className="pickup-tag"> ({vacant - pu})</span>}
|
||||||
{occupied}{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
</div>
|
||||||
</div>
|
</td>
|
||||||
<div style={{ fontSize: '0.78rem', color: 'var(--text-mid)' }}>
|
<td key={date + '-dsa'} style={{ verticalAlign: 'middle', borderLeft: '1px solid var(--card-border)', padding: '0.4rem 0.5rem 0.4rem 0.4rem', textAlign: 'right' }}>
|
||||||
{vacant} vac{pu > 0 && <span className="pickup-tag"> ({vacant - pu})</span>}
|
{(dNew > 0 || dCanc > 0) && (
|
||||||
</div>
|
<div style={{ marginBottom: '3px' }}>
|
||||||
<div style={{ fontSize: '0.72rem', color: 'var(--text-mid)', borderTop: '1px dashed var(--card-border)', paddingTop: '3px', marginTop: '3px' }}>
|
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
||||||
<span style={{ color: '#c2502e' }}>{departs}d{prevPu > 0 && <span className="pickup-tag"> +{prevPu}</span>}</span>
|
{dCanc > 0 && <span className="delta-canc"> ▼{dCanc}</span>}
|
||||||
{' / '}
|
</div>
|
||||||
<span style={{ color: '#1d6fb8' }}>{stays}s</span>
|
)}
|
||||||
{' / '}
|
<div style={{ fontSize: '0.8rem', color: '#c2502e', fontWeight: 600 }}>
|
||||||
<span style={{ color: '#1a7a4a' }}>{arrivals}a{pu > 0 && <span className="pickup-tag"> +{pu}</span>}</span>
|
{departs}d{prevPu > 0 && <span className="pickup-tag"> +{prevPu}</span>}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
<div style={{ fontSize: '0.8rem', color: '#1d6fb8', fontWeight: 600 }}>{stays}s</div>
|
||||||
|
<div style={{ fontSize: '0.8rem', color: '#1a7a4a', fontWeight: 600 }}>
|
||||||
|
{arrivals}a{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue