feat: refactor layouts and login components

This commit is contained in:
skytek_xinliang
2026-03-30 15:04:27 +08:00
parent f7413111c0
commit 79b20ded3b
21 changed files with 159 additions and 210 deletions
+88
View File
@@ -0,0 +1,88 @@
<template>
<v-sheet class="d-flex flex-column ga-2 h-100">
<v-card border class="flex-shrink-0" variant="flat">
<v-card-title class="d-flex align-center ga-3">
<span class="text-h6">{{ title }}</span>
<v-spacer />
<v-btn
:icon="mdAndUp ? false : mdiMagnify"
:prepend-icon="mdAndUp ? mdiMagnify : undefined"
size="small"
:text="mdAndUp ? '搜尋條件' : false"
variant="text"
@click="$emit('toggle-search')"
>
</v-btn>
<v-btn
color="primary"
:icon="mdAndUp ? false : mdiPlus"
:prepend-icon="mdAndUp ? mdiPlus : undefined"
size="small"
:text="mdAndUp ? createLabel : false"
@click="$emit('create')"
>
</v-btn>
</v-card-title>
<!-- Desktopinline 展開 -->
<template v-if="mdAndUp">
<v-divider />
<v-card-text v-show="searchPanelOpen" class="px-2 py-1">
<v-row density="compact">
<slot name="search-fields" />
</v-row>
</v-card-text>
</template>
</v-card>
<slot name="table" />
</v-sheet>
<!-- 手機 / TabletBottom Sheet -->
<v-bottom-sheet
v-if="!mdAndUp"
:model-value="searchPanelOpen"
@update:model-value="$emit('toggle-search')"
>
<v-card rounded="t-xl">
<v-card-title class="d-flex align-center py-3 px-4">
<span class="text-subtitle-1 font-weight-medium">搜尋條件</span>
<v-spacer />
<v-btn :icon="mdiClose" size="small" variant="text" @click="$emit('toggle-search')" />
</v-card-title>
<v-divider />
<v-card-text class="px-2 py-1">
<v-row density="compact">
<slot name="search-fields" />
</v-row>
</v-card-text>
</v-card>
</v-bottom-sheet>
</template>
<script setup lang="ts">
import { mdiClose, mdiMagnify, mdiPlus } from '@mdi/js'
import { useDisplay } from 'vuetify'
const { mdAndUp } = useDisplay()
defineProps({
title: {
type: String,
default: '學生資料維護',
},
createLabel: {
type: String,
default: '新增資料',
},
searchPanelOpen: {
type: Boolean,
required: true,
},
})
defineEmits<{
(event: 'toggle-search'): void
(event: 'create'): void
}>()
</script>