fix: classname

This commit is contained in:
skytek_xinliang
2026-10-06 09:55:30 +08:00
parent 12b067632f
commit 3211c3b78b
12 changed files with 471 additions and 400 deletions
@@ -6,7 +6,9 @@
<v-app-bar-nav-icon variant="text" @click="drawer = !drawer" />
</template>
<v-app-bar-title class="font-weight-bold flex-grow-1"> 運動玩轉健康力 </v-app-bar-title>
<v-app-bar-title class="font-weight-bold flex-grow-1">
運動玩轉健康力
</v-app-bar-title>
<template #append>
<div class="d-flex align-center">
@@ -19,7 +21,10 @@
variant="text"
@click="isLargeText = !isLargeText"
>
<v-icon :color="isLargeText ? 'accent' : 'white'" icon="mdi-format-size" />
<v-icon
:color="isLargeText ? 'accent' : 'white'"
icon="mdi-format-size"
/>
</v-btn>
</div>
</template>
@@ -61,7 +66,9 @@
</v-avatar>
</template>
<v-list-item-subtitle class="text-white-50">未登入訪客</v-list-item-subtitle>
<v-list-item-subtitle class="text-white-50"
>未登入訪客</v-list-item-subtitle
>
</v-list-item>
<v-divider />
@@ -74,7 +81,12 @@
<v-list-item-title>大字體模式</v-list-item-title>
<template #append>
<v-switch v-model="isLargeText" color="secondary" density="compact" hide-details />
<v-switch
v-model="isLargeText"
color="secondary"
density="compact"
hide-details
/>
</template>
</v-list-item>
@@ -191,11 +203,16 @@
</v-navigation-drawer>
<!-- 主要內容區 -->
<v-main class="bg-white min-vh-100" :class="{ 'pb-16': BOTTOM_NAVIGATION_ENABLED }">
<v-main
class="bg-white min-vh-100"
:class="{ 'pb-16': BOTTOM_NAVIGATION_ENABLED }"
>
<v-container class="px-4 py-2">
<v-alert
v-if="
store.isLoggedIn && store.requiresEmailCompletion && route.name !== 'complete-email'
store.isLoggedIn &&
store.requiresEmailCompletion &&
route.name !== 'complete-email'
"
class="mb-2"
color="warning"
@@ -206,11 +223,16 @@
<span class="text-title-small">
{{
EMAIL_COMPLETION_REQUIRED
? '請先註冊 E-Mail,才能繼續使用平台。'
: '尚未設定 E-Mail,前往註冊以接收重要通知。'
? "請先註冊 E-Mail,才能繼續使用平台。"
: "尚未設定 E-Mail,前往註冊以接收重要通知。"
}}
</span>
<v-btn color="warning" size="small" :to="emailCompletionLocation" variant="flat">
<v-btn
color="warning"
size="small"
:to="emailCompletionLocation"
variant="flat"
>
前往補登
</v-btn>
</div>
@@ -230,7 +252,9 @@
tag="div"
>
<v-btn to="/" value="home">
<v-icon :color="getBottomNavIconColor('home')">mdi-view-dashboard</v-icon>
<v-icon :color="getBottomNavIconColor('home')"
>mdi-view-dashboard</v-icon
>
<span class="bottom-nav-text">首頁</span>
</v-btn>
@@ -246,13 +270,25 @@
<span class="bottom-nav-text">自評</span>
</v-btn>
<v-btn v-if="CHECKIN_ENABLED && store.isLoggedIn" to="/checkin" value="checkin">
<v-icon :color="getBottomNavIconColor('checkin')">mdi-qrcode-scan</v-icon>
<v-btn
v-if="CHECKIN_ENABLED && store.isLoggedIn"
to="/checkin"
value="checkin"
>
<v-icon :color="getBottomNavIconColor('checkin')"
>mdi-qrcode-scan</v-icon
>
<span class="bottom-nav-text">量測</span>
</v-btn>
<v-btn v-if="APPOINTMENT_ENABLED && store.isLoggedIn" to="/appointment" value="appointment">
<v-icon :color="getBottomNavIconColor('appointment')">mdi-calendar-check</v-icon>
<v-btn
v-if="APPOINTMENT_ENABLED && store.isLoggedIn"
to="/appointment"
value="appointment"
>
<v-icon :color="getBottomNavIconColor('appointment')"
>mdi-calendar-check</v-icon
>
<span class="bottom-nav-text">預約</span>
</v-btn>
</v-bottom-navigation>
@@ -260,12 +296,14 @@
<!-- 隱私授權對話框 -->
<v-dialog v-model="showPrivacy" max-width="500">
<v-card class="rounded-xl">
<v-card-title class="bg-primary text-white font-weight-bold d-flex align-center">
<v-card-title
class="bg-primary text-white font-weight-bold d-flex align-center"
>
<v-icon class="mr-2" icon="mdi-shield-check" />
個資同意與資料授權
</v-card-title>
<v-card-text class="pt-4 text-body-1">
<v-card-text class="pt-4 text-body-large">
<p class="mb-3">
「運動玩轉健康力」平台非常重視您的個人隱私。我們所蒐集的身體活動自評、血壓、體脂以及現場運動表現數據,將僅用於以下用途:
</p>
@@ -293,8 +331,8 @@
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { computed, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
APPOINTMENT_ENABLED,
BODY_COMPOSITION_ENABLED,
@@ -302,53 +340,54 @@ import {
CHECKIN_ENABLED,
EMAIL_COMPLETION_REQUIRED,
SELF_ASSESSMENT_ENABLED,
} from '@/config/features'
import { useAppStore } from '@/stores/app'
import { useCourseStore } from '@/stores/course'
} from "@/config/features";
import { useAppStore } from "@/stores/app";
import { useCourseStore } from "@/stores/course";
const store = useAppStore()
const courseStore = useCourseStore()
const router = useRouter()
const route = useRoute()
const store = useAppStore();
const courseStore = useCourseStore();
const router = useRouter();
const route = useRoute();
const drawer = ref(false)
const activeTab = ref('home')
const showPrivacy = ref(false)
const drawer = ref(false);
const activeTab = ref("home");
const showPrivacy = ref(false);
const emailCompletionLocation = computed(() => ({
name: 'complete-email',
name: "complete-email",
query: {
redirect: route.name === 'complete-email' ? '/' : route.fullPath,
redirect: route.name === "complete-email" ? "/" : route.fullPath,
},
}))
}));
// 無障礙狀態 (可持久化儲存於 localStorage)
const isLargeText = ref(localStorage.getItem('mode-large-text') === 'true')
const isLargeText = ref(localStorage.getItem("mode-large-text") === "true");
watch(isLargeText, (newVal) => {
localStorage.setItem('mode-large-text', String(newVal))
})
localStorage.setItem("mode-large-text", String(newVal));
});
// 同步底部導航狀態與當前路由
watch(
() => route.path,
(path) => {
if (path === '/') activeTab.value = 'home'
else if (path.startsWith('/self-assessment')) activeTab.value = 'self-assessment'
else if (path.startsWith('/appointment')) activeTab.value = 'appointment'
else if (path.startsWith('/checkin')) activeTab.value = 'checkin'
if (path === "/") activeTab.value = "home";
else if (path.startsWith("/self-assessment"))
activeTab.value = "self-assessment";
else if (path.startsWith("/appointment")) activeTab.value = "appointment";
else if (path.startsWith("/checkin")) activeTab.value = "checkin";
},
{ immediate: true }
)
{ immediate: true },
);
function getBottomNavIconColor(value: string) {
return activeTab.value === value ? 'secondary' : 'secondary-darken-1'
return activeTab.value === value ? "secondary" : "secondary-darken-1";
}
async function handleLogout() {
await store.logout()
courseStore.resetGroup()
await router.push('/login')
drawer.value = false
await store.logout();
courseStore.resetGroup();
await router.push("/login");
drawer.value = false;
}
</script>
@@ -370,8 +409,8 @@ async function handleLogout() {
line-height: unset !important;
}
.v-card-text,
.text-body-1,
.text-body-2,
.text-body-large,
.text-body-medium,
p {
font-size: 1.15rem !important;
line-height: 1.6 !important;