fix: 課程表活版
@@ -1,3 +1,5 @@
|
|||||||
|
claude --resume 8ea22150-4078-44e3-9080-f2327c34aa04
|
||||||
|
|
||||||
# citizen-frontend
|
# citizen-frontend
|
||||||
|
|
||||||
Scaffolded with Vuetify CLI.
|
Scaffolded with Vuetify CLI.
|
||||||
|
|||||||
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 87 KiB |
@@ -120,8 +120,17 @@
|
|||||||
{{ DAY_NAMES[row.day - 1] }}
|
{{ DAY_NAMES[row.day - 1] }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td v-for="slot in visibleSlots" :key="slot.key" class="text-body-medium text-wrap">
|
<td v-for="slot in visibleSlots" :key="slot.key" class="slot-cell text-body-medium text-wrap">
|
||||||
{{ row[slot.key] }}
|
<div class="d-flex flex-column flex-md-row align-center ga-1 ga-md-3">
|
||||||
|
<v-avatar class="slot-avatar flex-shrink-0" rounded="lg">
|
||||||
|
<v-img
|
||||||
|
:alt="`${DAY_NAMES[row.day - 1]}${slot.label}課表插圖`"
|
||||||
|
:src="scheduleCardImage(row.day, slot.key)"
|
||||||
|
/>
|
||||||
|
</v-avatar>
|
||||||
|
|
||||||
|
<span>{{ row[slot.key] }}</span>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -271,6 +280,24 @@ const SHOW_SLOT_FILTER = false
|
|||||||
|
|
||||||
const DAY_NAMES = ['一', '二', '三', '四', '五', '六', '日']
|
const DAY_NAMES = ['一', '二', '三', '四', '五', '六', '日']
|
||||||
|
|
||||||
|
// 課表小卡:檔名為「星期-時段」,逐一匯入 21 張圖並依 day/slot 查表取用
|
||||||
|
const scheduleCardModules = import.meta.glob<{ default: string }>('../assets/course/schedule/*.png', { eager: true })
|
||||||
|
|
||||||
|
const SCHEDULE_CARD_DAY_KEYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
|
||||||
|
const SCHEDULE_CARD_SLOT_KEYS: Record<TimeSlot, string> = { morning: 'morning', noon: 'noon', night: 'evening' }
|
||||||
|
|
||||||
|
const SCHEDULE_CARDS: Record<string, string> = Object.fromEntries(
|
||||||
|
Object.entries(scheduleCardModules).map(([path, module]) => [
|
||||||
|
path.replace(/^.*\/|\.png$/g, ''),
|
||||||
|
module.default,
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
|
||||||
|
function scheduleCardImage (day: number, slot: TimeSlot): string {
|
||||||
|
const key = `${SCHEDULE_CARD_DAY_KEYS[day - 1]}-${SCHEDULE_CARD_SLOT_KEYS[slot]}`
|
||||||
|
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' },
|
||||||
@@ -317,6 +344,17 @@ onMounted(() => {
|
|||||||
width: 22%;
|
width: 22%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 課表小卡:欄寬有限,圖片改用 clamp 隨欄寬縮放,避免在手機版把文字擠出可讀範圍 */
|
||||||
|
.slot-cell {
|
||||||
|
padding-block: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-avatar {
|
||||||
|
width: clamp(32px, 18vw, 56px);
|
||||||
|
height: clamp(32px, 18vw, 56px);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
/* 組別卡片:半透明白底圓形與次級白字,Vuetify 沒有對應的 utility class */
|
/* 組別卡片:半透明白底圓形與次級白字,Vuetify 沒有對應的 utility class */
|
||||||
.group-avatar {
|
.group-avatar {
|
||||||
background-color: rgba(255, 255, 255, 0.22);
|
background-color: rgba(255, 255, 255, 0.22);
|
||||||
|
|||||||