From 4b49605ed118fb9d7a0e1ecd3e64df669be7912b Mon Sep 17 00:00:00 2001 From: derekc Date: Sat, 28 Feb 2026 16:57:19 -0800 Subject: [PATCH] Add greeting and countdown timer to TV dashboard before session starts Shows "Good Morning! Ready to start school?" placeholder when a session is active but no block has been selected, along with a live countdown to the first scheduled block's start time. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/views/TVView.vue | 68 ++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/TVView.vue b/frontend/src/views/TVView.vue index 212d0d8..fee4a03 100644 --- a/frontend/src/views/TVView.vue +++ b/frontend/src/views/TVView.vue @@ -26,7 +26,15 @@
-
+
+
Good Morning!
+
Ready to start school?
+
+
First block starts in
+
{{ firstBlockCountdown }}
+
+
+
{{ currentSubjectIcon }} {{ currentSubjectName }}
@@ -129,6 +137,23 @@ const dayProgressPercent = computed(() => { return Math.max(0, Math.min(100, Math.round((nowMin - start) / (end - start) * 100))) }) +// Countdown to first block +const firstBlockCountdown = computed(() => { + const first = scheduleStore.blocks[0] + if (!first?.time_start) return null + const [h, m, s] = first.time_start.split(':').map(Number) + const target = new Date(now.value) + target.setHours(h, m, s || 0, 0) + const diffMs = target - now.value + if (diffMs <= 0) return null + const totalSec = Math.floor(diffMs / 1000) + const hours = Math.floor(totalSec / 3600) + const mins = Math.floor((totalSec % 3600) / 60) + const secs = totalSec % 60 + if (hours > 0) return `${hours}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}` + return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}` +}) + // Subject display helpers const currentSubjectColor = computed(() => { const block = scheduleStore.currentBlock @@ -228,6 +253,47 @@ onMounted(async () => { text-align: center; } +.tv-greeting-col { + justify-content: center; + gap: 1rem; +} + +.tv-greeting { + font-size: 3rem; + font-weight: 700; + color: #818cf8; + text-align: center; +} + +.tv-greeting-sub { + font-size: 1.6rem; + color: #64748b; + text-align: center; +} + +.tv-countdown-wrap { + margin-top: 1.5rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.4rem; +} + +.tv-countdown-label { + font-size: 1rem; + text-transform: uppercase; + letter-spacing: 0.08em; + color: #475569; +} + +.tv-countdown { + font-size: 4rem; + font-weight: 300; + font-variant-numeric: tabular-nums; + color: #c7d2fe; + letter-spacing: 0.05em; +} + .tv-block-notes { font-size: 1rem; color: #94a3b8;