99 <!-- Settings Form -->
1010 <form v-else @submit.prevent =" saveSettings" class =" space-y-6" >
1111 <!-- Tab Navigation -->
12- <div class =" sticky top-0 z-10 overflow-x-auto scrollbar-hide " >
12+ <div class =" sticky top-0 z-10 overflow-x-auto settings-tabs-scroll " >
1313 <nav class =" settings-tabs" >
1414 <button
1515 v-for =" tab in settingsTabs"
16491649 </div >
16501650 </div ><!-- /Tab: Email -->
16511651
1652+ <!-- Tab: Backup -->
1653+ <div v-show =" activeTab === 'backup'" >
1654+ <BackupSettings />
1655+ </div >
1656+
1657+ <!-- Tab: Data Management -->
1658+ <div v-show =" activeTab === 'data'" >
1659+ <DataManagementSettings />
1660+ </div >
1661+
16521662 <!-- Save Button -->
1653- <div class =" flex justify-end" >
1663+ <div v-show = " activeTab !== 'backup' && activeTab !== 'data' " class =" flex justify-end" >
16541664 <button type =" submit" :disabled =" saving" class =" btn btn-primary" >
16551665 <svg v-if =" saving" class =" h-4 w-4 animate-spin" fill =" none" viewBox =" 0 0 24 24" >
16561666 <circle
@@ -1692,6 +1702,8 @@ import GroupBadge from '@/components/common/GroupBadge.vue'
16921702import GroupOptionItem from ' @/components/common/GroupOptionItem.vue'
16931703import Toggle from ' @/components/common/Toggle.vue'
16941704import ImageUpload from ' @/components/common/ImageUpload.vue'
1705+ import BackupSettings from ' @/views/admin/BackupView.vue'
1706+ import DataManagementSettings from ' @/views/admin/DataManagementView.vue'
16951707import { useClipboard } from ' @/composables/useClipboard'
16961708import { useAppStore } from ' @/stores'
16971709import { useAdminSettingsStore } from ' @/stores/adminSettings'
@@ -1706,14 +1718,16 @@ const { t } = useI18n()
17061718const appStore = useAppStore ()
17071719const adminSettingsStore = useAdminSettingsStore ()
17081720
1709- type SettingsTab = ' general' | ' security' | ' users' | ' gateway' | ' email'
1721+ type SettingsTab = ' general' | ' security' | ' users' | ' gateway' | ' email' | ' backup ' | ' data '
17101722const activeTab = ref <SettingsTab >(' general' )
17111723const settingsTabs = [
17121724 { key: ' general' as SettingsTab , icon: ' home' as const },
17131725 { key: ' security' as SettingsTab , icon: ' shield' as const },
17141726 { key: ' users' as SettingsTab , icon: ' user' as const },
17151727 { key: ' gateway' as SettingsTab , icon: ' server' as const },
17161728 { key: ' email' as SettingsTab , icon: ' mail' as const },
1729+ { key: ' backup' as SettingsTab , icon: ' database' as const },
1730+ { key: ' data' as SettingsTab , icon: ' cube' as const },
17171731]
17181732const { copyToClipboard } = useClipboard ()
17191733
@@ -2378,9 +2392,38 @@ onMounted(() => {
23782392}
23792393
23802394/* ============ Settings Tab Navigation ============ */
2395+
2396+ /* Scroll container: thin scrollbar on PC, auto-hide on mobile */
2397+ .settings-tabs-scroll {
2398+ scrollbar-width : thin ;
2399+ scrollbar-color : transparent transparent ;
2400+ }
2401+ .settings-tabs-scroll :hover {
2402+ scrollbar-color : rgb (0 0 0 / 0.15 ) transparent ;
2403+ }
2404+ :root .dark .settings-tabs-scroll :hover {
2405+ scrollbar-color : rgb (255 255 255 / 0.2 ) transparent ;
2406+ }
2407+ .settings-tabs-scroll ::-webkit-scrollbar {
2408+ height : 3px ;
2409+ }
2410+ .settings-tabs-scroll ::-webkit-scrollbar-track {
2411+ background : transparent ;
2412+ }
2413+ .settings-tabs-scroll ::-webkit-scrollbar-thumb {
2414+ background : transparent ;
2415+ border-radius : 3px ;
2416+ }
2417+ .settings-tabs-scroll :hover ::-webkit-scrollbar-thumb {
2418+ background : rgb (0 0 0 / 0.15 );
2419+ }
2420+ :root .dark .settings-tabs-scroll :hover ::-webkit-scrollbar-thumb {
2421+ background : rgb (255 255 255 / 0.2 );
2422+ }
2423+
23812424.settings-tabs {
2382- @apply inline-flex min-w-full gap- 1 rounded- 2xl
2383- border border-gray- 100 bg-white /80 p- 1.5 backdrop-blur-sm
2425+ @apply inline-flex min-w-full gap- 0.5 rounded- 2xl
2426+ border border-gray- 100 bg-white /80 p- 1 backdrop-blur-sm
23842427 dark :border-dark-700/50 dark :bg-dark-800/80 ;
23852428 box-shadow : 0 1px 3px rgb (0 0 0 / 0.04 ), 0 1px 2px rgb (0 0 0 / 0.02 );
23862429}
@@ -2392,8 +2435,8 @@ onMounted(() => {
23922435}
23932436
23942437.settings-tab {
2395- @apply relative flex flex- 1 items-center justify-center gap- 2
2396- whitespace-nowrap rounded-xl px- 4 py- 2.5
2438+ @apply relative flex flex- 1 items-center justify-center gap- 1.5
2439+ whitespace-nowrap rounded-xl px- 2.5 py- 2
23972440 text-sm font-medium
23982441 text-gray- 500 dark :text-dark-400
23992442 transition-all duration-200 ease-out ;
@@ -2420,7 +2463,7 @@ onMounted(() => {
24202463}
24212464
24222465.settings-tab-icon {
2423- @apply flex h- 7 w- 7 items-center justify-center rounded-lg
2466+ @apply flex h- 6 w- 6 items-center justify-center rounded-lg
24242467 transition-all duration- 200;
24252468}
24262469
0 commit comments