From 4ed470ac35bbabc12438e1e55f3d15d9672304f9 Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Sat, 9 May 2026 01:44:59 +0200 Subject: [PATCH] =?UTF-8?q?feat(timetable):=20leaf=20visual=20components?= =?UTF-8?q?=20=E2=80=94=20TimeAxis,=20GridBg,=20StageHeaderCell,=20Perform?= =?UTF-8?q?anceBlock,=20StageRow,=20EmptyDayState=20(Session=204=20step=20?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PerformanceBlock is the heart of the canvas: - Status palette via CSS tokens (D21) — one class per booking_status enum value - Cancelled hatch overlay + line-through (D5) - Trashed-artist dashed border + ⌂ overlay icon (D27) - Conflict ring + glow when warnings.includes('overlap') (D5) - Capacity icon driven by evaluateCapacity() with warn/critical levels (D25) - B2B left/right dots (D26 — 3-min threshold) - Cascade-pulse class fired by parent on cascaded[] non-empty (D18) - aria-label structure per D20: artist, stage, time window, status, advancing - tabindex 0 + Enter/Space → select; Delete → emit delete StageRow positions blocks by lane_resolved (D19) — server is authoritative. StageHeaderCell uses Vuexy VMenu pattern for the per-stage actions. EmptyDayState routes the user to LineupMatrix when no stages are active. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../components/timetable/EmptyDayState.vue | 29 ++ apps/app/src/components/timetable/GridBg.vue | 47 +++ .../components/timetable/PerformanceBlock.vue | 338 ++++++++++++++++++ .../components/timetable/StageHeaderCell.vue | 117 ++++++ .../app/src/components/timetable/StageRow.vue | 93 +++++ .../app/src/components/timetable/TimeAxis.vue | 62 ++++ 6 files changed, 686 insertions(+) create mode 100644 apps/app/src/components/timetable/EmptyDayState.vue create mode 100644 apps/app/src/components/timetable/GridBg.vue create mode 100644 apps/app/src/components/timetable/PerformanceBlock.vue create mode 100644 apps/app/src/components/timetable/StageHeaderCell.vue create mode 100644 apps/app/src/components/timetable/StageRow.vue create mode 100644 apps/app/src/components/timetable/TimeAxis.vue diff --git a/apps/app/src/components/timetable/EmptyDayState.vue b/apps/app/src/components/timetable/EmptyDayState.vue new file mode 100644 index 00000000..5a357ee5 --- /dev/null +++ b/apps/app/src/components/timetable/EmptyDayState.vue @@ -0,0 +1,29 @@ + + + diff --git a/apps/app/src/components/timetable/GridBg.vue b/apps/app/src/components/timetable/GridBg.vue new file mode 100644 index 00000000..accb313a --- /dev/null +++ b/apps/app/src/components/timetable/GridBg.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/apps/app/src/components/timetable/PerformanceBlock.vue b/apps/app/src/components/timetable/PerformanceBlock.vue new file mode 100644 index 00000000..76270434 --- /dev/null +++ b/apps/app/src/components/timetable/PerformanceBlock.vue @@ -0,0 +1,338 @@ + + + + + diff --git a/apps/app/src/components/timetable/StageHeaderCell.vue b/apps/app/src/components/timetable/StageHeaderCell.vue new file mode 100644 index 00000000..1b9f45a8 --- /dev/null +++ b/apps/app/src/components/timetable/StageHeaderCell.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/apps/app/src/components/timetable/StageRow.vue b/apps/app/src/components/timetable/StageRow.vue new file mode 100644 index 00000000..d87faf9f --- /dev/null +++ b/apps/app/src/components/timetable/StageRow.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/apps/app/src/components/timetable/TimeAxis.vue b/apps/app/src/components/timetable/TimeAxis.vue new file mode 100644 index 00000000..99b39708 --- /dev/null +++ b/apps/app/src/components/timetable/TimeAxis.vue @@ -0,0 +1,62 @@ + + + + +