Add subject options and redesign TV dashboard layout
Subject options: - New subject_options table (auto-created on startup) - SubjectOut now includes options list; all eager-loading chains updated - Admin: Options panel per subject with add, inline edit, and delete - WS broadcast and dashboard API include options in block subject data TV dashboard: - Three equal columns: Timer | Activities | Schedule - Activities column shows current subject's options in large readable text - Activities area has subject-colored border and tinted background - Subject name and label displayed correctly using embedded subject data Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,12 +25,9 @@
|
||||
|
||||
<!-- Active session -->
|
||||
<div v-else class="tv-main">
|
||||
<!-- Current block (big display) -->
|
||||
<div class="tv-current" v-if="scheduleStore.currentBlock">
|
||||
<div
|
||||
class="tv-subject-badge"
|
||||
:style="{ background: currentSubjectColor }"
|
||||
>
|
||||
<!-- Left: timer -->
|
||||
<div class="tv-timer-col" v-if="scheduleStore.currentBlock">
|
||||
<div class="tv-subject-badge" :style="{ background: currentSubjectColor }">
|
||||
{{ currentSubjectIcon }} {{ currentSubjectName }}
|
||||
</div>
|
||||
<TimerDisplay
|
||||
@@ -45,8 +42,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Center: subject options -->
|
||||
<div class="tv-options-col" :style="{ background: currentSubjectColor + '22', borderColor: currentSubjectColor }">
|
||||
<div class="tv-options-title">Activities</div>
|
||||
<div
|
||||
v-if="currentSubjectOptions.length"
|
||||
class="tv-options-list"
|
||||
>
|
||||
<div
|
||||
v-for="opt in currentSubjectOptions"
|
||||
:key="opt.id"
|
||||
class="tv-option-item"
|
||||
>
|
||||
{{ opt.text }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="tv-options-empty">No activities listed for this subject.</div>
|
||||
</div>
|
||||
|
||||
<!-- Right: schedule list -->
|
||||
<div class="tv-sidebar">
|
||||
<!-- Schedule list -->
|
||||
<div class="tv-schedule-list">
|
||||
<ScheduleBlock
|
||||
v-for="block in scheduleStore.blocks"
|
||||
@@ -123,6 +138,9 @@ const currentSubjectIcon = computed(() => scheduleStore.currentBlock?.subject?.i
|
||||
const currentSubjectName = computed(() =>
|
||||
scheduleStore.currentBlock?.label || scheduleStore.currentBlock?.subject?.name || 'Current Block'
|
||||
)
|
||||
const currentSubjectOptions = computed(() =>
|
||||
scheduleStore.currentBlock?.subject?.options || []
|
||||
)
|
||||
|
||||
// WebSocket
|
||||
const { connected: wsConnected } = useWebSocket(childId, (msg) => {
|
||||
@@ -188,11 +206,12 @@ onMounted(async () => {
|
||||
.tv-main {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 380px;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 2rem;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.tv-current {
|
||||
.tv-timer-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
@@ -201,18 +220,56 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
.tv-subject-badge {
|
||||
font-size: 1.75rem;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 600;
|
||||
padding: 0.75rem 2rem;
|
||||
padding: 0.6rem 1.5rem;
|
||||
border-radius: 999px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tv-block-notes {
|
||||
font-size: 1.25rem;
|
||||
font-size: 1rem;
|
||||
color: #94a3b8;
|
||||
text-align: center;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.tv-options-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
border: 2px solid;
|
||||
border-radius: 1rem;
|
||||
padding: 1.5rem 2rem;
|
||||
}
|
||||
|
||||
.tv-options-title {
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.tv-options-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.tv-option-item {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 500;
|
||||
color: #e2e8f0;
|
||||
padding: 0.6rem 0;
|
||||
border-bottom: 1px solid #1e293b;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.tv-options-empty {
|
||||
font-size: 1.1rem;
|
||||
color: #334155;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.tv-day-progress {
|
||||
|
||||
Reference in New Issue
Block a user