From 9554030054bf5be3949b8bd83a532e4fedec2a93 Mon Sep 17 00:00:00 2001 From: Tim <135014430+nagisa77@users.noreply.github.com> Date: Thu, 21 Aug 2025 12:36:02 +0800 Subject: [PATCH] refactor: add reusable switch component --- frontend_nuxt/components/BaseSwitch.vue | 65 +++++++++++++++++++++++++ frontend_nuxt/pages/message.vue | 46 ++++++++--------- frontend_nuxt/pages/settings.vue | 51 +------------------ 3 files changed, 87 insertions(+), 75 deletions(-) create mode 100644 frontend_nuxt/components/BaseSwitch.vue diff --git a/frontend_nuxt/components/BaseSwitch.vue b/frontend_nuxt/components/BaseSwitch.vue new file mode 100644 index 000000000..f04197c92 --- /dev/null +++ b/frontend_nuxt/components/BaseSwitch.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/frontend_nuxt/pages/message.vue b/frontend_nuxt/pages/message.vue index 3a8098f3b..7d0a54723 100644 --- a/frontend_nuxt/pages/message.vue +++ b/frontend_nuxt/pages/message.vue @@ -33,15 +33,13 @@
通知设置
-
-
- {{ formatType(pref.type) }} +
+
+
{{ formatType(pref.type) }}
+
@@ -550,6 +548,7 @@ import { updateNotificationPreference, } from '~/utils/notification' import TimeManager from '~/utils/time' +import BaseSwitch from '~/components/BaseSwitch.vue' const config = useRuntimeConfig() const API_BASE_URL = config.public.apiBaseUrl @@ -582,10 +581,10 @@ const fetchPrefs = async () => { notificationPrefs.value = await fetchNotificationPreferences() } -const togglePref = async (pref) => { - const ok = await updateNotificationPreference(pref.type, !pref.enabled) +const togglePref = async (pref, value) => { + const ok = await updateNotificationPreference(pref.type, value) if (ok) { - pref.enabled = !pref.enabled + pref.enabled = value await fetchNotifications({ page: page.value, size: pageSize, @@ -846,26 +845,21 @@ onActivated(async () => { padding: 20px; } -.message-control-push-item-container { +.message-control-item-container { display: flex; - flex-direction: row; - flex-wrap: wrap; + flex-direction: column; gap: 10px; } -.message-control-push-item { - font-size: 14px; - margin-bottom: 5px; - padding: 8px 16px; - border: 1px solid var(--normal-border-color); - border-radius: 10px; - cursor: pointer; - transition: all 0.3s ease; +.message-control-item { + display: flex; + align-items: center; + justify-content: space-between; + max-width: 200px; } -.message-control-push-item.select { - background-color: var(--primary-color); - color: white; +.message-control-item-label { + font-size: 14px; } @media (max-width: 768px) { diff --git a/frontend_nuxt/pages/settings.vue b/frontend_nuxt/pages/settings.vue index 7178ee347..cc2028e38 100644 --- a/frontend_nuxt/pages/settings.vue +++ b/frontend_nuxt/pages/settings.vue @@ -38,10 +38,7 @@
毛玻璃效果
- +
@@ -76,6 +73,7 @@ import { ref, onMounted, watch } from 'vue' import AvatarCropper from '~/components/AvatarCropper.vue' import BaseInput from '~/components/BaseInput.vue' import Dropdown from '~/components/Dropdown.vue' +import BaseSwitch from '~/components/BaseSwitch.vue' import { toast } from '~/main' import { fetchCurrentUser, getToken, setToken } from '~/utils/auth' import { frostedState, setFrosted } from '~/utils/frosted' @@ -318,51 +316,6 @@ const save = async () => { max-width: 200px; } -.switch { - position: relative; - display: inline-block; - width: 40px; - height: 20px; -} - -.switch input { - opacity: 0; - width: 0; - height: 0; -} - -.slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #ccc; - transition: 0.2s; - border-radius: 20px; -} - -.slider:before { - position: absolute; - content: ''; - height: 16px; - width: 16px; - left: 2px; - bottom: 2px; - background-color: white; - transition: 0.2s; - border-radius: 50%; -} - -input:checked + .slider { - background-color: var(--primary-color); -} - -input:checked + .slider:before { - transform: translateX(20px); -} - .profile-section { margin-bottom: 30px; }