Summary table: stronger day borders, weekend bg, and WP-accurate tooltips
- 2px left border on Rooms th/td marks each day boundary clearly - Saturday/Sunday columns get a subtle blue-tinted background - Occupied number shows pickup-change context + prior week stats on hover - '+' pickup button shows prior week line (matching original WP plugin logic) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
31fd73ce1e
commit
97e99735ce
1 changed files with 70 additions and 9 deletions
|
|
@ -34,6 +34,25 @@ function getDayName(date: string) {
|
||||||
return ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'][(d.getDay() + 6) % 7]
|
return ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'][(d.getDay() + 6) % 7]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fullDayName(date: string) {
|
||||||
|
const d = new Date(date + 'T00:00:00')
|
||||||
|
return ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'][d.getDay()]
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWeekend(date: string) {
|
||||||
|
const day = new Date(date + 'T00:00:00').getDay()
|
||||||
|
return day === 0 || day === 6
|
||||||
|
}
|
||||||
|
|
||||||
|
function priorLineFor(date: string, d: DayData): string {
|
||||||
|
const hint = d.pickup_hint ?? 0
|
||||||
|
const lead = d.pickup_lead ?? 0
|
||||||
|
const late = hint > 0
|
||||||
|
? `${hint} room${hint === 1 ? '' : 's'} picked up within ${lead} day${lead === 1 ? '' : 's'} of arrival`
|
||||||
|
: 'no late pickups'
|
||||||
|
return `Last ${fullDayName(date)}: ${d.prior_occ} occ (${d.prior_vac} vac) — ${late}`
|
||||||
|
}
|
||||||
|
|
||||||
function fmtDate(date: string) {
|
function fmtDate(date: string) {
|
||||||
return new Date(date + 'T00:00:00').toLocaleDateString('en-GB', {
|
return new Date(date + 'T00:00:00').toLocaleDateString('en-GB', {
|
||||||
weekday: 'short', day: 'numeric', month: 'short',
|
weekday: 'short', day: 'numeric', month: 'short',
|
||||||
|
|
@ -435,13 +454,26 @@ function SummaryTable({ bookings, pickup, onPickupChange }: SummaryProps) {
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="col-label" rowSpan={2}>Category</th>
|
<th className="col-label" rowSpan={2}>Category</th>
|
||||||
{dates.map(d => <th key={d} colSpan={2}>{fmtDayHeader(d)}</th>)}
|
{dates.map(d => (
|
||||||
|
<th key={d} colSpan={2} style={{
|
||||||
|
borderLeft: '2px solid rgba(255,255,255,0.3)',
|
||||||
|
...(isWeekend(d) ? { background: '#253555' } : {}),
|
||||||
|
}}>{fmtDayHeader(d)}</th>
|
||||||
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
{dates.map(d => (
|
{dates.map(d => (
|
||||||
<>
|
<>
|
||||||
<th key={d + '-r'} style={{ fontSize: '0.72rem', fontWeight: 400, background: '#1e2d42', minWidth: '72px' }}>Rooms</th>
|
<th key={d + '-r'} style={{
|
||||||
<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>
|
fontSize: '0.72rem', fontWeight: 400, minWidth: '72px',
|
||||||
|
background: isWeekend(d) ? '#2a3d5e' : '#1e2d42',
|
||||||
|
borderLeft: '2px solid rgba(255,255,255,0.3)',
|
||||||
|
}}>Rooms</th>
|
||||||
|
<th key={d + '-d'} style={{
|
||||||
|
fontSize: '0.72rem', fontWeight: 400, minWidth: '56px',
|
||||||
|
background: isWeekend(d) ? '#2a3d5e' : '#1e2d42',
|
||||||
|
borderLeft: '1px solid rgba(255,255,255,0.1)',
|
||||||
|
}}>D / S / A</th>
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -485,12 +517,28 @@ function CatRows({ cat, dates, pickup, onPickupChange, isLast }: {
|
||||||
const prevPu = prevDate ? getDisplayPickup(pickup, cat.id, prevDate, prevOcc, cat.total_rooms) : 0
|
const prevPu = prevDate ? getDisplayPickup(pickup, cat.id, prevDate, prevOcc, cat.total_rooms) : 0
|
||||||
const dNew = d.delta_new || 0
|
const dNew = d.delta_new || 0
|
||||||
const dCanc = d.delta_cancelled || 0
|
const dCanc = d.delta_cancelled || 0
|
||||||
|
const wknd = isWeekend(date)
|
||||||
|
const saved = pickup[cat.id]?.[date]
|
||||||
|
const priorLine = priorLineFor(date, d)
|
||||||
|
let occTooltip = ''
|
||||||
|
if (saved && saved.count) {
|
||||||
|
const savedBooked = saved.total - saved.count
|
||||||
|
const changeDesc = occupied > savedBooked ? 'changed' : 'unchanged'
|
||||||
|
const pickupDesc = occupied > savedBooked ? 'decreased' : 'remains'
|
||||||
|
occTooltip = `+${saved.count} pickup set when booked was ${savedBooked} (target ${saved.total}). Booked ${changeDesc}, so pickup ${pickupDesc}.`
|
||||||
|
}
|
||||||
|
occTooltip = (occTooltip ? occTooltip + ' | ' : '') + priorLine
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Left cell: Rooms / vac / pickup controls */}
|
{/* Left cell: Rooms / vac / pickup controls */}
|
||||||
<td key={date + '-r'} style={{ textAlign: 'center', verticalAlign: 'middle', borderBottom: bbStyle, padding: '0.4rem 0.3rem' }}>
|
<td key={date + '-r'} style={{
|
||||||
<div style={{ fontWeight: 700, fontSize: '1.1rem' }}>
|
textAlign: 'center', verticalAlign: 'middle', borderBottom: bbStyle,
|
||||||
|
padding: '0.4rem 0.3rem',
|
||||||
|
borderLeft: '2px solid var(--card-border)',
|
||||||
|
...(wknd ? { background: 'rgba(100,120,160,0.07)' } : {}),
|
||||||
|
}}>
|
||||||
|
<div style={{ fontWeight: 700, fontSize: '1.1rem' }} title={occTooltip}>
|
||||||
{occupied}{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
{occupied}{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: '0.72rem', color: 'var(--text-mid)', marginBottom: '4px' }}>
|
<div style={{ fontSize: '0.72rem', color: 'var(--text-mid)', marginBottom: '4px' }}>
|
||||||
|
|
@ -500,12 +548,16 @@ function CatRows({ cat, dates, pickup, onPickupChange, isLast }: {
|
||||||
<button className="pickup-btn" disabled={pu <= 0} onClick={() => onPickupChange(date, -1)}>−</button>
|
<button className="pickup-btn" disabled={pu <= 0} 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={priorLine}
|
||||||
onClick={() => onPickupChange(date, 1)}>+</button>
|
onClick={() => onPickupChange(date, 1)}>+</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{/* Right cell: D / S / A */}
|
{/* Right cell: D / S / A */}
|
||||||
<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' }}>
|
<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',
|
||||||
|
...(wknd ? { background: 'rgba(100,120,160,0.07)' } : {}),
|
||||||
|
}}>
|
||||||
{(dNew > 0 || dCanc > 0) && (
|
{(dNew > 0 || dCanc > 0) && (
|
||||||
<div style={{ marginBottom: '3px' }}>
|
<div style={{ marginBottom: '3px' }}>
|
||||||
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
||||||
|
|
@ -553,9 +605,14 @@ function TotalRows({ dates, cats, pickup }: {
|
||||||
dNew += d.delta_new || 0
|
dNew += d.delta_new || 0
|
||||||
dCanc += d.delta_cancelled || 0
|
dCanc += d.delta_cancelled || 0
|
||||||
}
|
}
|
||||||
|
const wknd = isWeekend(date)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<td key={date + '-r'} style={{ textAlign: 'center', verticalAlign: 'middle', padding: '0.4rem 0.3rem' }}>
|
<td key={date + '-r'} style={{
|
||||||
|
textAlign: 'center', verticalAlign: 'middle', padding: '0.4rem 0.3rem',
|
||||||
|
borderLeft: '2px solid var(--card-border)',
|
||||||
|
...(wknd ? { background: 'rgba(100,120,160,0.07)' } : {}),
|
||||||
|
}}>
|
||||||
<div style={{ fontWeight: 700, fontSize: '1.1rem' }}>
|
<div style={{ fontWeight: 700, fontSize: '1.1rem' }}>
|
||||||
{occupied}{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
{occupied}{pu > 0 && <span className="pickup-tag"> +{pu}</span>}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -563,7 +620,11 @@ function TotalRows({ dates, cats, pickup }: {
|
||||||
{vacant} vac{pu > 0 && <span className="pickup-tag"> ({vacant - pu})</span>}
|
{vacant} vac{pu > 0 && <span className="pickup-tag"> ({vacant - pu})</span>}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td key={date + '-dsa'} style={{ verticalAlign: 'middle', borderLeft: '1px solid var(--card-border)', padding: '0.4rem 0.5rem 0.4rem 0.4rem', textAlign: 'right' }}>
|
<td key={date + '-dsa'} style={{
|
||||||
|
verticalAlign: 'middle', borderLeft: '1px solid var(--card-border)',
|
||||||
|
padding: '0.4rem 0.5rem 0.4rem 0.4rem', textAlign: 'right',
|
||||||
|
...(wknd ? { background: 'rgba(100,120,160,0.07)' } : {}),
|
||||||
|
}}>
|
||||||
{(dNew > 0 || dCanc > 0) && (
|
{(dNew > 0 || dCanc > 0) && (
|
||||||
<div style={{ marginBottom: '3px' }}>
|
<div style={{ marginBottom: '3px' }}>
|
||||||
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
{dNew > 0 && <span className="delta-new">▲{dNew}</span>}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue