Initial project scaffold

Full-stack homeschool web app with FastAPI backend, Vue 3 frontend,
MySQL database, and Docker Compose orchestration. Includes JWT auth,
WebSocket real-time TV dashboard, schedule builder, activity logging,
and multi-child support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 22:56:31 -08:00
parent 93e0494864
commit 417b3adfe8
68 changed files with 3919 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
<template>
<div
class="block-card"
:class="{
'is-current': isCurrent,
'is-completed': isCompleted,
compact,
}"
>
<div class="block-indicator" :style="{ background: subjectColor }"></div>
<div class="block-body">
<div class="block-title">
{{ block.label || subjectName || 'Block' }}
</div>
<div class="block-time">{{ block.time_start }} {{ block.time_end }}</div>
</div>
<div class="block-status" v-if="isCompleted"></div>
<div class="block-status active" v-else-if="isCurrent"></div>
</div>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
block: { type: Object, required: true },
isCurrent: { type: Boolean, default: false },
isCompleted: { type: Boolean, default: false },
compact: { type: Boolean, default: false },
})
const subjectColor = computed(() => props.block.subject?.color || '#475569')
const subjectName = computed(() => props.block.subject?.name || null)
</script>
<style scoped>
.block-card {
display: flex;
align-items: center;
gap: 0.75rem;
background: #1e293b;
border-radius: 0.75rem;
padding: 0.75rem 1rem;
border: 1px solid transparent;
transition: all 0.2s;
cursor: default;
}
.block-card.is-current {
border-color: #4f46e5;
background: #1e1b4b;
}
.block-card.is-completed {
opacity: 0.5;
}
.block-card.compact {
padding: 0.5rem 0.75rem;
border-radius: 0.5rem;
}
.block-indicator {
width: 4px;
height: 36px;
border-radius: 2px;
flex-shrink: 0;
}
.block-card.compact .block-indicator {
height: 24px;
}
.block-body { flex: 1; min-width: 0; }
.block-title {
font-size: 0.95rem;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.block-card.compact .block-title { font-size: 0.85rem; }
.block-time {
font-size: 0.75rem;
color: #64748b;
margin-top: 0.15rem;
font-variant-numeric: tabular-nums;
}
.block-status {
font-size: 0.85rem;
color: #64748b;
flex-shrink: 0;
}
.block-status.active { color: #818cf8; }
</style>