refactor: comprehensive frontend review — consistency, a11y, code quality
- Replace event dispatchers with BookingContext (Hero, Header, FloatingContact) - Add focus trap hook for modals (SignupModal, NewsModal) - Extract shared components: CollapsibleSection, ConfirmDialog, PriceField, AdminSkeleton - Add delete confirmation dialog to ArrayEditor - Replace hardcoded colors (#050505, #0a0a0a, #c9a96e, #2ecc71) with theme tokens - Add CSS variables --color-surface-deep/dark for consistent dark surfaces - Improve contrast: muted text neutral-500 → neutral-400 in dark mode - Fix modal z-index hierarchy (modals z-60, header z-50, floats z-40) - Consolidate duplicate formatDate → shared formatting.ts - Add useMemo to TeamProfile groupMap computation - Fix typography: responsive price text in Pricing section - Add ARIA labels/expanded to FAQ, OpenDay, ArrayEditor grip handles - Hide number input spinners globally - Reorder admin sidebar: Dashboard → SEO → Bookings → site section order - Use shared PriceField in Open Day editor - Fix schedule grid first time slot (09:00) clipped by container - Fix pre-existing type errors (bookings, hero, db interfaces)
This commit is contained in:
@@ -95,8 +95,10 @@ function timeToMinutes(timeStr: string): number {
|
||||
return t.h * 60 + t.m;
|
||||
}
|
||||
|
||||
const GRID_TOP_PAD = 8; // px — space so the first time label isn't clipped
|
||||
|
||||
function minutesToY(minutes: number): number {
|
||||
return ((minutes - HOUR_START * 60) / 60) * HOUR_HEIGHT;
|
||||
return ((minutes - HOUR_START * 60) / 60) * HOUR_HEIGHT + GRID_TOP_PAD;
|
||||
}
|
||||
|
||||
function yToMinutes(y: number): number {
|
||||
@@ -927,12 +929,12 @@ function CalendarGrid({
|
||||
{/* Time grid */}
|
||||
<div className="flex">
|
||||
{/* Time labels */}
|
||||
<div className="w-14 shrink-0 relative" style={{ height: `${TOTAL_HOURS * HOUR_HEIGHT}px` }}>
|
||||
<div className="w-14 shrink-0 relative" style={{ height: `${TOTAL_HOURS * HOUR_HEIGHT + GRID_TOP_PAD}px` }}>
|
||||
{hours.slice(0, -1).map((h) => (
|
||||
<div
|
||||
key={h}
|
||||
className="absolute left-0 right-0 text-right pr-2 text-xs text-neutral-500"
|
||||
style={{ top: `${(h - HOUR_START) * HOUR_HEIGHT - 6}px` }}
|
||||
style={{ top: `${(h - HOUR_START) * HOUR_HEIGHT + GRID_TOP_PAD - 6}px` }}
|
||||
>
|
||||
{String(h).padStart(2, "0")}:00
|
||||
</div>
|
||||
@@ -951,7 +953,7 @@ function CalendarGrid({
|
||||
key={day.day}
|
||||
ref={(el) => { columnRefs.current[di] = el; }}
|
||||
className={`flex-1 border-l border-white/10 relative ${drag ? "cursor-grabbing" : "cursor-pointer"}`}
|
||||
style={{ height: `${TOTAL_HOURS * HOUR_HEIGHT}px` }}
|
||||
style={{ height: `${TOTAL_HOURS * HOUR_HEIGHT + GRID_TOP_PAD}px` }}
|
||||
onMouseMove={(e) => {
|
||||
if (drag) return;
|
||||
// Ignore if hovering over a class block
|
||||
@@ -978,7 +980,7 @@ function CalendarGrid({
|
||||
<div
|
||||
key={h}
|
||||
className="absolute left-0 right-0 border-t border-white/5"
|
||||
style={{ top: `${(h - HOUR_START) * HOUR_HEIGHT}px` }}
|
||||
style={{ top: `${(h - HOUR_START) * HOUR_HEIGHT + GRID_TOP_PAD}px` }}
|
||||
/>
|
||||
))}
|
||||
{/* Half-hour lines */}
|
||||
@@ -986,7 +988,7 @@ function CalendarGrid({
|
||||
<div
|
||||
key={`${h}-30`}
|
||||
className="absolute left-0 right-0 border-t border-white/[0.02]"
|
||||
style={{ top: `${(h - HOUR_START) * HOUR_HEIGHT + HOUR_HEIGHT / 2}px` }}
|
||||
style={{ top: `${(h - HOUR_START) * HOUR_HEIGHT + HOUR_HEIGHT / 2 + GRID_TOP_PAD}px` }}
|
||||
/>
|
||||
))}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user