style: course

This commit is contained in:
skytek_xinliang
2026-08-13 11:49:28 +08:00
parent 3839f8f4cc
commit 6000639b1c
2 changed files with 121 additions and 89 deletions
+40 -8
View File
@@ -164,13 +164,18 @@
<!-- 運動時間建議對應 doc/運動時間建議.png --> <!-- 運動時間建議對應 doc/運動時間建議.png -->
<v-card class="rounded-lg elevation-1 mt-4 overflow-hidden"> <v-card class="rounded-lg elevation-1 mt-4 overflow-hidden">
<v-card-title class="text-title-medium font-weight-bold text-primary d-flex align-center"> <v-expansion-panels v-model="durationTablePanel" flat variant="accordion">
<v-expansion-panel value="duration">
<v-expansion-panel-title
class="course-table-panel-title text-title-medium font-weight-bold text-primary"
>
<v-icon class="mr-2" color="primary" icon="mdi-timer-outline" size="20" /> <v-icon class="mr-2" color="primary" icon="mdi-timer-outline" size="20" />
運動時間建議 運動時間建議
</v-card-title> </v-expansion-panel-title>
<v-divider /> <v-divider />
<v-expansion-panel-text class="pa-0">
<v-table class="course-table" density="comfortable"> <v-table class="course-table" density="comfortable">
<thead> <thead>
<tr> <tr>
@@ -198,9 +203,24 @@
</tr> </tr>
</tbody> </tbody>
</v-table> </v-table>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card> </v-card>
<v-card class="rounded-lg elevation-1 mt-4 overflow-hidden"> <v-card class="rounded-lg elevation-1 mt-4 overflow-hidden">
<v-expansion-panels v-model="scheduleTablePanel" flat variant="accordion">
<v-expansion-panel value="schedule">
<v-expansion-panel-title
class="course-table-panel-title text-title-medium font-weight-bold text-primary"
>
<v-icon class="mr-2" color="primary" icon="mdi-timer-outline" size="20" />
運動課表
</v-expansion-panel-title>
<v-divider />
<v-expansion-panel-text class="pa-0">
<v-table class="course-table" density="comfortable"> <v-table class="course-table" density="comfortable">
<thead> <thead>
<tr> <tr>
@@ -247,6 +267,9 @@
</tr> </tr>
</tbody> </tbody>
</v-table> </v-table>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card> </v-card>
<v-card class="rounded-lg elevation-1 mt-4 overflow-hidden"> <v-card class="rounded-lg elevation-1 mt-4 overflow-hidden">
@@ -275,6 +298,10 @@ const detail = computed(() => COURSE_DETAIL[store.group])
// 課程說明預設只展開第一個面板(族群特徵) // 課程說明預設只展開第一個面板(族群特徵)
const openPanels = ref([0]) const openPanels = ref([0])
// 兩張表格預設展開,使用者可分別收合以減少頁面長度。
const durationTablePanel = ref<string | null>('duration')
const scheduleTablePanel = ref<string | null>('schedule')
const GROUP_ILLUSTRATIONS: Record<FitnessGroup, string> = { const GROUP_ILLUSTRATIONS: Record<FitnessGroup, string> = {
low: lowIllustration, low: lowIllustration,
medium: mediumIllustration, medium: mediumIllustration,
@@ -291,7 +318,7 @@ const DAY_NAMES = ['一', '二', '三', '四', '五', '六', '日']
// 課表小卡:檔名為「星期-時段」,逐一匯入 21 張圖並依 day/slot 查表取用 // 課表小卡:檔名為「星期-時段」,逐一匯入 21 張圖並依 day/slot 查表取用
const scheduleCardModules = import.meta.glob<{ default: string }>( const scheduleCardModules = import.meta.glob<{ default: string }>(
'../assets/course/schedule/*.png', '../assets/course/schedule/*.png',
{ eager: true } { eager: true },
) )
const SCHEDULE_CARD_DAY_KEYS = [ const SCHEDULE_CARD_DAY_KEYS = [
@@ -313,22 +340,22 @@ const SCHEDULE_CARDS: Record<string, string> = Object.fromEntries(
Object.entries(scheduleCardModules).map(([path, module]) => [ Object.entries(scheduleCardModules).map(([path, module]) => [
path.replace(/^.*\/|\.png$/g, ''), path.replace(/^.*\/|\.png$/g, ''),
module.default, module.default,
]) ]),
) )
function scheduleCardImage(day: number, slot: TimeSlot): string { function scheduleCardImage (day: number, slot: TimeSlot): string {
const key = `${SCHEDULE_CARD_DAY_KEYS[day - 1]}-${SCHEDULE_CARD_SLOT_KEYS[slot]}` const key = `${SCHEDULE_CARD_DAY_KEYS[day - 1]}-${SCHEDULE_CARD_SLOT_KEYS[slot]}`
return SCHEDULE_CARDS[key] return SCHEDULE_CARDS[key]
} }
const SLOTS: { key: TimeSlot; label: string; icon: string; headerClass: string }[] = [ const SLOTS: { key: TimeSlot, label: string, icon: string, headerClass: string }[] = [
{ key: 'morning', label: '早上', icon: 'mdi-weather-sunset-up', headerClass: 'bg-deep-orange' }, { key: 'morning', label: '早上', icon: 'mdi-weather-sunset-up', headerClass: 'bg-deep-orange' },
{ key: 'noon', label: '中午', icon: 'mdi-white-balance-sunny', headerClass: 'bg-amber-darken-2' }, { key: 'noon', label: '中午', icon: 'mdi-white-balance-sunny', headerClass: 'bg-amber-darken-2' },
{ key: 'night', label: '晚上', icon: 'mdi-weather-night', headerClass: 'bg-deep-purple' }, { key: 'night', label: '晚上', icon: 'mdi-weather-night', headerClass: 'bg-deep-purple' },
] ]
// 依目前選取的時段決定表格要顯示哪幾欄,順序固定為早上/中午/晚上 // 依目前選取的時段決定表格要顯示哪幾欄,順序固定為早上/中午/晚上
const visibleSlots = computed(() => SLOTS.filter((slot) => store.selectedSlots.includes(slot.key))) const visibleSlots = computed(() => SLOTS.filter(slot => store.selectedSlots.includes(slot.key)))
// 今天對應的星期幾,換算成與 CourseRow.day 相同的規則(1 = 週一 … 7 = 週日) // 今天對應的星期幾,換算成與 CourseRow.day 相同的規則(1 = 週一 … 7 = 週日)
const todayDay = computed(() => { const todayDay = computed(() => {
@@ -339,7 +366,7 @@ const todayDay = computed(() => {
// v-btn-toggle 以陣列表達勾選狀態,store 則以 Y/N 保存,兩者在此橋接 // v-btn-toggle 以陣列表達勾選狀態,store 則以 Y/N 保存,兩者在此橋接
const selectedSlots = computed<TimeSlot[]>({ const selectedSlots = computed<TimeSlot[]>({
get: () => store.selectedSlots, get: () => store.selectedSlots,
set: (value) => { set: value => {
for (const slot of SLOTS) { for (const slot of SLOTS) {
const next: YesNo = value.includes(slot.key) ? 'Y' : 'N' const next: YesNo = value.includes(slot.key) ? 'Y' : 'N'
store.setSlot(slot.key, next) store.setSlot(slot.key, next)
@@ -359,6 +386,11 @@ onMounted(() => {
table-layout: fixed; table-layout: fixed;
} }
.course-table-panel-title {
min-height: 40px;
padding: 8px 16px;
}
.day-col { .day-col {
width: 15%; width: 15%;
} }
+9 -9
View File
@@ -14,17 +14,17 @@ import 'vuetify/styles'
const HPTheme: ThemeDefinition = { const HPTheme: ThemeDefinition = {
dark: false, dark: false,
colors: { colors: {
background: '#F0F9F6', // 頁面背景 'background': '#F0F9F6', // 頁面背景
surface: '#FFFFFF', // 卡片與白底區塊 'surface': '#FFFFFF', // 卡片與白底區塊
primary: '#1D7063', // 主要品牌色 'primary': '#1D7063', // 主要品牌色
'primary-darken-1': '#145248', 'primary-darken-1': '#145248',
secondary: '#dc5349', // CTA 按鈕 'secondary': '#dc5349', // CTA 按鈕
'secondary-darken-1': '#ab4c3d', 'secondary-darken-1': '#ab4c3d',
accent: '#47C2A6', // 標籤與強調 'accent': '#47C2A6', // 標籤與強調
error: '#B00020', 'error': '#B00020',
info: '#2196F3', 'info': '#2196F3',
success: '#4CAF50', 'success': '#4CAF50',
warning: '#FB8C00', 'warning': '#FB8C00',
}, },
} }