style: index page
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
<div class="text-subtitle-1 text-grey font-weight-bold">目前沒有相關活動</div>
|
||||
</div>
|
||||
|
||||
<v-row v-else dense>
|
||||
<v-row v-else>
|
||||
<v-col v-for="apt in filteredAppointments" :key="apt.id" class="mb-4" cols="12">
|
||||
<v-card class="rounded-xl elevation-3 border-accent-light" color="surface">
|
||||
<!-- 卡片頂部狀態條 -->
|
||||
@@ -63,7 +63,12 @@
|
||||
<v-icon class="mr-2 mt-0.5" color="primary" icon="mdi-human-capacity" 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> 位
|
||||
剩餘名額:<span
|
||||
class="font-weight-bold"
|
||||
:class="apt.slots < 10 ? 'text-error' : 'text-success'"
|
||||
>{{ apt.slots }}</span
|
||||
>
|
||||
位
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -106,7 +111,7 @@
|
||||
|
||||
<!-- 已報名狀態 -->
|
||||
<template v-else-if="apt.status === '已報名'">
|
||||
<v-row class="w-100" dense>
|
||||
<v-row class="w-100">
|
||||
<v-col cols="6">
|
||||
<v-btn
|
||||
block
|
||||
@@ -166,7 +171,9 @@
|
||||
<p class="text-caption text-grey mb-4">請在現場合對處出示此條碼進行報到</p>
|
||||
|
||||
<!-- 模擬 QR Code SVG,更高級精緻 -->
|
||||
<div class="qrcode-wrapper mx-auto mb-4 elevation-3 rounded-lg pa-3 bg-white border d-flex justify-center align-center">
|
||||
<div
|
||||
class="qrcode-wrapper mx-auto mb-4 elevation-3 rounded-lg pa-3 bg-white border d-flex justify-center align-center"
|
||||
>
|
||||
<svg class="qrcode-svg" height="180" viewBox="0 0 100 100" width="180">
|
||||
<!-- 四個角定位框 -->
|
||||
<path d="M 0,0 H 25 V 8 H 8 V 25 H 0 Z" fill="#1D7063" />
|
||||
@@ -174,142 +181,40 @@
|
||||
<path d="M 0,75 V 100 H 25 V 92 H 8 V 75 Z" fill="#1D7063" />
|
||||
<path d="M 92,75 V 92 H 75 V 100 H 100 V 75 Z" fill="#1D7063" />
|
||||
<!-- 內嵌二維碼方塊 -->
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="20"
|
||||
width="20"
|
||||
x="12"
|
||||
y="12"
|
||||
/>
|
||||
<rect fill="#1D7063" height="20" width="20" x="12" y="12" />
|
||||
|
||||
<rect
|
||||
fill="white"
|
||||
height="12"
|
||||
width="12"
|
||||
x="16"
|
||||
y="16"
|
||||
/>
|
||||
<rect fill="white" height="12" width="12" x="16" y="16" />
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="6"
|
||||
width="6"
|
||||
x="19"
|
||||
y="19"
|
||||
/>
|
||||
<rect fill="#E66926" height="6" width="6" x="19" y="19" />
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="20"
|
||||
width="20"
|
||||
x="68"
|
||||
y="12"
|
||||
/>
|
||||
<rect fill="#1D7063" height="20" width="20" x="68" y="12" />
|
||||
|
||||
<rect
|
||||
fill="white"
|
||||
height="12"
|
||||
width="12"
|
||||
x="72"
|
||||
y="16"
|
||||
/>
|
||||
<rect fill="white" height="12" width="12" x="72" y="16" />
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="6"
|
||||
width="6"
|
||||
x="75"
|
||||
y="75"
|
||||
/>
|
||||
<rect fill="#E66926" height="6" width="6" x="75" y="75" />
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="20"
|
||||
width="20"
|
||||
x="12"
|
||||
y="68"
|
||||
/>
|
||||
<rect fill="#1D7063" height="20" width="20" x="12" y="68" />
|
||||
|
||||
<rect
|
||||
fill="white"
|
||||
height="12"
|
||||
width="12"
|
||||
x="16"
|
||||
y="72"
|
||||
/>
|
||||
<rect fill="white" height="12" width="12" x="16" y="72" />
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="6"
|
||||
width="6"
|
||||
x="19"
|
||||
y="75"
|
||||
/>
|
||||
<rect fill="#1D7063" height="6" width="6" x="19" y="75" />
|
||||
|
||||
<!-- 中間隨機小方塊 -->
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="8"
|
||||
width="8"
|
||||
x="40"
|
||||
y="20"
|
||||
/>
|
||||
<rect fill="#1D7063" height="8" width="8" x="40" y="20" />
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="14"
|
||||
width="6"
|
||||
x="52"
|
||||
y="12"
|
||||
/>
|
||||
<rect fill="#E66926" height="14" width="6" x="52" y="12" />
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="6"
|
||||
width="16"
|
||||
x="42"
|
||||
y="36"
|
||||
/>
|
||||
<rect fill="#1D7063" height="6" width="16" x="42" y="36" />
|
||||
|
||||
<rect
|
||||
fill="#47C2A6"
|
||||
height="10"
|
||||
width="28"
|
||||
x="36"
|
||||
y="48"
|
||||
/>
|
||||
<rect fill="#47C2A6" height="10" width="28" x="36" y="48" />
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="12"
|
||||
width="14"
|
||||
x="68"
|
||||
y="42"
|
||||
/>
|
||||
<rect fill="#1D7063" height="12" width="14" x="68" y="42" />
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="16"
|
||||
width="16"
|
||||
x="72"
|
||||
y="60"
|
||||
/>
|
||||
<rect fill="#E66926" height="16" width="16" x="72" y="60" />
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="12"
|
||||
width="18"
|
||||
x="44"
|
||||
y="68"
|
||||
/>
|
||||
<rect fill="#1D7063" height="12" width="18" x="44" y="68" />
|
||||
|
||||
<rect
|
||||
fill="#47C2A6"
|
||||
height="6"
|
||||
width="24"
|
||||
x="40"
|
||||
y="82"
|
||||
/>
|
||||
<rect fill="#47C2A6" height="6" width="24" x="40" y="82" />
|
||||
</svg>
|
||||
<!-- 紅色掃描雷射線 -->
|
||||
<div class="laser-line" />
|
||||
@@ -335,7 +240,12 @@
|
||||
<v-divider />
|
||||
|
||||
<v-card-actions class="pa-4 justify-center">
|
||||
<v-btn class="rounded-lg px-6" color="primary" variant="flat" @click="qrcodeDialog = false">
|
||||
<v-btn
|
||||
class="rounded-lg px-6"
|
||||
color="primary"
|
||||
variant="flat"
|
||||
@click="qrcodeDialog = false"
|
||||
>
|
||||
關閉條碼
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@@ -346,55 +256,59 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import Layout from '@/components/layout/DefaultLayout.vue'
|
||||
import { type Appointment, useAppStore } from '@/stores/app'
|
||||
import { computed, ref } from 'vue'
|
||||
import Layout from '@/components/layout/DefaultLayout.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 === '已報到')
|
||||
const filteredAppointments = computed(() => {
|
||||
if (filterTab.value === 'registered') {
|
||||
return store.appointments.filter((a) => a.status === '已報名' || a.status === '已報到')
|
||||
}
|
||||
return store.appointments
|
||||
})
|
||||
|
||||
function getStatusColor(status: string) {
|
||||
switch (status) {
|
||||
case '未報名': {
|
||||
return 'grey-darken-1'
|
||||
}
|
||||
return store.appointments
|
||||
})
|
||||
|
||||
function getStatusColor (status: string) {
|
||||
switch (status) {
|
||||
case '未報名': { return 'grey-darken-1'
|
||||
}
|
||||
case '已報名': { return 'secondary'
|
||||
}
|
||||
case '已報到': { return 'success'
|
||||
}
|
||||
default: { return 'grey'
|
||||
}
|
||||
case '已報名': {
|
||||
return 'secondary'
|
||||
}
|
||||
case '已報到': {
|
||||
return 'success'
|
||||
}
|
||||
default: {
|
||||
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 () {
|
||||
if (selectedApt.value) {
|
||||
store.checkinAppointment(selectedApt.value.id)
|
||||
qrcodeDialog.value = false
|
||||
}
|
||||
function simulateOnSiteCheckin() {
|
||||
if (selectedApt.value) {
|
||||
store.checkinAppointment(selectedApt.value.id)
|
||||
qrcodeDialog.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -429,8 +343,14 @@
|
||||
}
|
||||
|
||||
@keyframes scan {
|
||||
0% { top: 0%; }
|
||||
50% { top: 100%; }
|
||||
100% { top: 0%; }
|
||||
0% {
|
||||
top: 0%;
|
||||
}
|
||||
50% {
|
||||
top: 100%;
|
||||
}
|
||||
100% {
|
||||
top: 0%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user