feat: 課程表格

This commit is contained in:
skytek_xinliang
2026-08-05 17:25:45 +08:00
parent 76aa074506
commit 7938903ada
3 changed files with 267 additions and 2 deletions
+121 -2
View File
@@ -78,7 +78,7 @@
<!-- 一週課表:仿 doc/課程表示意 的表格版型,星期為列、時段為欄 -->
<template v-else>
<v-card class="rounded-xl elevation-1 mb-4 overflow-hidden">
<v-card class="rounded-lg elevation-1 mb-4 overflow-hidden">
<v-img :alt="`${store.groupMeta.label}課表示意圖`" :src="groupIllustration" />
</v-card>
@@ -117,6 +117,114 @@
</tbody>
</v-table>
</v-card>
<!-- 運動時間建議:對應 doc/運動時間建議.png -->
<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-icon class="mr-2" color="primary" icon="mdi-timer-outline" size="20" />
運動時間建議
</v-card-title>
<v-divider />
<v-table class="course-table" density="comfortable">
<thead>
<tr>
<th class="day-col bg-primary text-white text-center">星期</th>
<th class="bg-primary text-white text-center">運動內容</th>
<th class="time-col bg-primary text-white text-center">時間</th>
</tr>
</thead>
<tbody>
<tr
v-for="row in detail.duration"
:key="row.day"
:class="{ 'bg-teal-lighten-5': row.day === todayDay }"
>
<td class="day-col text-center font-weight-bold text-primary">
{{ DAY_NAMES[row.day - 1] }}
</td>
<td class="text-body-medium text-wrap">{{ row.content }}</td>
<td class="time-col text-center text-body-medium">
{{ row.minutes === null ? '—' : `${row.minutes} 分` }}
</td>
</tr>
</tbody>
</v-table>
</v-card>
<!-- 課程說明:對應 doc/課程說明.md -->
<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-icon class="mr-2" color="primary" icon="mdi-book-open-variant" size="20" />
課程說明
</v-card-title>
<v-divider />
<v-expansion-panels v-model="openPanels" multiple variant="accordion">
<v-expansion-panel>
<v-expansion-panel-title class="font-weight-bold">族群特徵</v-expansion-panel-title>
<v-expansion-panel-text>
<p class="text-body-medium text-grey-darken-2 mb-3">
{{ detail.profile.summary }}
</p>
<div
v-for="(item, index) in detail.profile.items"
:key="index"
class="d-flex align-start ga-3 mb-2"
>
<v-icon color="secondary" :icon="`mdi-numeric-${index + 1}-circle`" size="20" />
<div class="text-body-medium">{{ item }}</div>
</div>
</v-expansion-panel-text>
</v-expansion-panel>
<v-expansion-panel>
<v-expansion-panel-title class="font-weight-bold">
精準運動處方建議
</v-expansion-panel-title>
<v-expansion-panel-text>
<div
v-for="(item, index) in detail.prescription"
:key="index"
class="d-flex align-start ga-3 mb-4"
>
<v-icon color="secondary" :icon="`mdi-numeric-${index + 1}-circle`" size="20" />
<div>
<div class="font-weight-bold">{{ item.title }}</div>
<div class="text-body-medium text-grey-darken-2 mt-1">{{ item.detail }}</div>
</div>
</div>
</v-expansion-panel-text>
</v-expansion-panel>
<v-expansion-panel>
<v-expansion-panel-title class="font-weight-bold">
{{ detail.outcome.label }}
</v-expansion-panel-title>
<v-expansion-panel-text>
<div
v-for="(item, index) in detail.outcome.items"
:key="index"
class="d-flex align-start ga-3 mb-2"
>
<v-icon color="secondary" :icon="`mdi-numeric-${index + 1}-circle`" size="20" />
<div class="text-body-medium">{{ item }}</div>
</div>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card>
</template>
</template>
</Layout>
@@ -124,15 +232,22 @@
<script setup lang="ts">
import type { FitnessGroup, TimeSlot, YesNo } from '@/api/types'
import { computed, onMounted } from 'vue'
import { computed, onMounted, ref } from 'vue'
import highIllustration from '@/assets/course/high.png'
import lowIllustration from '@/assets/course/low.png'
import mediumIllustration from '@/assets/course/medium.png'
import Layout from '@/components/layout/DefaultLayout.vue'
import { COURSE_DETAIL } from '@/data/courseDetail'
import { useCourseStore } from '@/stores/course'
const store = useCourseStore()
// 運動時間建議與課程說明的靜態內容,依組別對應
const detail = computed(() => COURSE_DETAIL[store.group])
// 課程說明預設只展開第一個面板(族群特徵)
const openPanels = ref([0])
const GROUP_ILLUSTRATIONS: Record<FitnessGroup, string> = {
low: lowIllustration,
medium: mediumIllustration,
@@ -187,4 +302,8 @@ onMounted(() => {
.day-col {
width: 15%;
}
.time-col {
width: 22%;
}
</style>