chore: OXC Formatter
This commit is contained in:
@@ -10,19 +10,36 @@
|
||||
</v-card>
|
||||
|
||||
<!-- 活動分類選擇 -->
|
||||
<v-tabs v-model="filterTab" class="mb-4 bg-white rounded-xl elevation-1" color="primary" grow>
|
||||
<v-tabs
|
||||
v-model="filterTab"
|
||||
class="mb-4 bg-white rounded-xl elevation-1"
|
||||
color="primary"
|
||||
grow
|
||||
>
|
||||
<v-tab value="all">全部活動</v-tab>
|
||||
<v-tab value="registered">我的報名</v-tab>
|
||||
</v-tabs>
|
||||
|
||||
<!-- 活動列表 -->
|
||||
<div v-if="filteredAppointments.length === 0" class="text-center py-12">
|
||||
<v-icon class="mb-3" color="grey-lighten-1" icon="mdi-calendar-blank" size="64" />
|
||||
<div class="text-title-small text-grey font-weight-bold">目前沒有相關活動</div>
|
||||
<v-icon
|
||||
class="mb-3"
|
||||
color="grey-lighten-1"
|
||||
icon="mdi-calendar-blank"
|
||||
size="64"
|
||||
/>
|
||||
<div class="text-title-small text-grey font-weight-bold">
|
||||
目前沒有相關活動
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-row v-else>
|
||||
<v-col v-for="apt in filteredAppointments" :key="apt.id" class="mb-4" cols="12">
|
||||
<v-col
|
||||
v-for="apt in filteredAppointments"
|
||||
:key="apt.id"
|
||||
class="mb-4"
|
||||
cols="12"
|
||||
>
|
||||
<v-card class="rounded-xl elevation-3" color="surface">
|
||||
<!-- 卡片頂部狀態條 -->
|
||||
<v-card-item class="bg-teal-lighten-5 py-4">
|
||||
@@ -44,12 +61,19 @@
|
||||
</v-card-item>
|
||||
|
||||
<v-card-text>
|
||||
<h2 class="text-title-large font-weight-bold text-grey-darken-4 mb-4">
|
||||
<h2
|
||||
class="text-title-large font-weight-bold text-grey-darken-4 mb-4"
|
||||
>
|
||||
{{ apt.title }}
|
||||
</h2>
|
||||
|
||||
<div class="d-flex align-start mb-2">
|
||||
<v-icon class="mr-2" color="primary" icon="mdi-calendar-clock" size="18" />
|
||||
<v-icon
|
||||
class="mr-2"
|
||||
color="primary"
|
||||
icon="mdi-calendar-clock"
|
||||
size="18"
|
||||
/>
|
||||
|
||||
<div class="text-body-2 text-grey-darken-3">
|
||||
<span class="font-weight-bold">{{ apt.date }}</span>
|
||||
@@ -63,13 +87,19 @@
|
||||
</div> -->
|
||||
|
||||
<div class="d-flex align-start mb-3">
|
||||
<v-icon class="mr-2" color="primary" icon="mdi-human-queue" size="18" />
|
||||
<v-icon
|
||||
class="mr-2"
|
||||
color="primary"
|
||||
icon="mdi-human-queue"
|
||||
size="18"
|
||||
/>
|
||||
|
||||
<div class="text-body-2 text-grey-darken-3">
|
||||
剩餘名額:<span
|
||||
class="font-weight-bold"
|
||||
:class="apt.slots < 10 ? 'text-error' : 'text-success'"
|
||||
>{{ apt.slots }}</span>
|
||||
>{{ apt.slots }}</span
|
||||
>
|
||||
位
|
||||
</div>
|
||||
</div>
|
||||
@@ -107,7 +137,7 @@
|
||||
variant="flat"
|
||||
@click="handleRegister(apt.id)"
|
||||
>
|
||||
{{ apt.slots === 0 ? '名額已滿' : '線上報名活動' }}
|
||||
{{ apt.slots === 0 ? "名額已滿" : "線上報名活動" }}
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
@@ -165,11 +195,15 @@
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="pa-6">
|
||||
<h3 class="text-subtitle-1 font-weight-bold mb-1 text-grey-darken-4">
|
||||
<h3
|
||||
class="text-subtitle-1 font-weight-bold mb-1 text-grey-darken-4"
|
||||
>
|
||||
{{ selectedApt?.title }}
|
||||
</h3>
|
||||
|
||||
<p class="text-caption text-grey mb-4">請在現場合對處出示此條碼進行報到</p>
|
||||
<p class="text-caption text-grey mb-4">
|
||||
請在現場合對處出示此條碼進行報到
|
||||
</p>
|
||||
|
||||
<div
|
||||
class="qrcode-wrapper mx-auto mb-4 elevation-3 rounded-lg pa-3 bg-white border d-flex justify-center align-center"
|
||||
@@ -178,7 +212,8 @@
|
||||
</div>
|
||||
|
||||
<div class="text-caption text-grey-darken-2 font-weight-bold mb-4">
|
||||
姓名: {{ store.userProfile.name }} 先生 | 電話: {{ store.userProfile.phone }}
|
||||
姓名: {{ store.userProfile.name }} 先生 | 電話:
|
||||
{{ store.userProfile.phone }}
|
||||
</div>
|
||||
|
||||
<!-- 模擬現場合對處,高齡測試快捷鍵 -->
|
||||
@@ -213,66 +248,68 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import Layout from '@/components/layout/DefaultLayout.vue'
|
||||
import QRCode from '@/components/QRCode.vue'
|
||||
import { type Appointment, useAppStore } from '@/stores/app'
|
||||
import { computed, ref } from "vue";
|
||||
import Layout from "@/components/layout/DefaultLayout.vue";
|
||||
import QRCode from "@/components/QRCode.vue";
|
||||
import { type Appointment, useAppStore } from "@/stores/app";
|
||||
|
||||
const store = useAppStore()
|
||||
const filterTab = ref('all')
|
||||
const store = useAppStore();
|
||||
const filterTab = ref("all");
|
||||
|
||||
const qrcodeDialog = ref(false)
|
||||
const selectedApt = ref<Appointment | null>(null)
|
||||
const qrcodeDialog = ref(false);
|
||||
const selectedApt = ref<Appointment | null>(null);
|
||||
|
||||
const filteredAppointments = computed(() => {
|
||||
if (filterTab.value === 'registered') {
|
||||
return store.appointments.filter(a => a.status === '已報名' || a.status === '已報到')
|
||||
if (filterTab.value === "registered") {
|
||||
return store.appointments.filter(
|
||||
(a) => a.status === "已報名" || a.status === "已報到",
|
||||
);
|
||||
}
|
||||
return store.appointments
|
||||
})
|
||||
return store.appointments;
|
||||
});
|
||||
|
||||
const selectedCheckinPayload = computed(() => {
|
||||
if (!selectedApt.value) {
|
||||
return 'https://hp.local/c'
|
||||
return "https://hp.local/c";
|
||||
}
|
||||
|
||||
return `https://hp.local/c/${selectedApt.value.id}`
|
||||
})
|
||||
return `https://hp.local/c/${selectedApt.value.id}`;
|
||||
});
|
||||
|
||||
function getStatusColor (status: string) {
|
||||
function getStatusColor(status: string) {
|
||||
switch (status) {
|
||||
case '未報名': {
|
||||
return 'grey-darken-1'
|
||||
case "未報名": {
|
||||
return "grey-darken-1";
|
||||
}
|
||||
case '已報名': {
|
||||
return 'secondary'
|
||||
case "已報名": {
|
||||
return "secondary";
|
||||
}
|
||||
case '已報到': {
|
||||
return 'success'
|
||||
case "已報到": {
|
||||
return "success";
|
||||
}
|
||||
default: {
|
||||
return 'grey'
|
||||
return "grey";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleRegister (id: string) {
|
||||
store.registerAppointment(id)
|
||||
function handleRegister(id: string) {
|
||||
store.registerAppointment(id);
|
||||
}
|
||||
|
||||
function handleCancel (id: string) {
|
||||
store.cancelAppointment(id)
|
||||
function handleCancel(id: string) {
|
||||
store.cancelAppointment(id);
|
||||
}
|
||||
|
||||
function showCheckinQRCode (apt: Appointment) {
|
||||
selectedApt.value = apt
|
||||
qrcodeDialog.value = true
|
||||
function showCheckinQRCode(apt: Appointment) {
|
||||
selectedApt.value = apt;
|
||||
qrcodeDialog.value = true;
|
||||
}
|
||||
|
||||
function simulateOnSiteCheckin () {
|
||||
function simulateOnSiteCheckin() {
|
||||
if (selectedApt.value) {
|
||||
store.checkinAppointment(selectedApt.value.id)
|
||||
qrcodeDialog.value = false
|
||||
store.checkinAppointment(selectedApt.value.id);
|
||||
qrcodeDialog.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user