From b435638774717c4f2ed8f291c8a26c4f3fd778e6 Mon Sep 17 00:00:00 2001 From: lethdat Date: Sun, 29 Mar 2026 22:31:41 +0700 Subject: [PATCH] feat: update icons and improve loading states in various components - Updated `hard-drive.vue` and `shield-user.vue` icons to use `currentColor` for better color management. - Enhanced `BaseTable.vue` to support skeleton loading rows and improved loading state rendering. - Refactored notification components to use new icon components (`Inbox`, `Video`, `Credit`, `BellOff`, `BellDot`) instead of icon classes. - Added new icons for `BellDot` and `BellOff`. - Improved the `QuickActions.vue` component for better hover effects. - Updated various settings components to use consistent icon styling and improved accessibility. - Refactored `AdsVastTable.tsx`, `DangerZone.vue`, `DomainsDnsTable.vue`, `PlayerConfigsTable.vue`, and `PopupAdsTable.tsx` to streamline loading states and skeleton rendering. --- components.d.ts | 6 ++ src/components/DashboardNav.vue | 10 ++-- src/components/NotificationDrawer.vue | 3 +- src/components/icons/AlertTriangle.vue | 7 +-- src/components/icons/Bell.vue | 2 +- src/components/icons/BellDot.vue | 7 +++ src/components/icons/BellOff.vue | 7 +++ src/components/icons/Chart.vue | 4 +- src/components/icons/CoinsIcon.vue | 2 +- src/components/icons/Credit.vue | 2 +- src/components/icons/Globe.vue | 2 +- src/components/icons/Home.vue | 2 +- src/components/icons/Inbox.vue | 7 +++ src/components/icons/ListIcon.vue | 2 +- src/components/icons/MoneyCheck.vue | 2 +- src/components/icons/SettingsIcon.vue | 2 +- src/components/icons/Upload.vue | 2 +- src/components/icons/Video.vue | 2 +- src/components/icons/VideoPlayIcon.vue | 2 +- src/components/icons/hard-drive.vue | 2 +- src/components/icons/shield-user.vue | 2 +- src/components/ui/BaseTable.vue | 56 ++++++++++++++++--- src/routes/notification/Notification.vue | 13 +++-- .../components/NotificationActions.vue | 9 ++- .../components/NotificationList.vue | 3 +- .../components/NotificationTabs.vue | 5 +- .../overview/components/QuickActions.vue | 2 +- .../AdsVast/components/AdsVastTable.tsx | 7 +-- src/routes/settings/DangerZone/DangerZone.vue | 14 +---- .../DomainsDns/components/DomainsDnsTable.vue | 4 +- .../components/PlayerConfigsTable.vue | 5 +- .../PopupAds/components/PopupAdsTable.tsx | 22 +++----- .../components/SecurityAccountStatusRow.vue | 2 +- .../components/SecurityChangePasswordRow.vue | 2 +- .../components/SecurityEmailRow.vue | 2 +- .../components/SecurityLanguageRow.vue | 2 +- uno.config.ts | 8 +-- 37 files changed, 143 insertions(+), 90 deletions(-) create mode 100644 src/components/icons/BellDot.vue create mode 100644 src/components/icons/BellOff.vue create mode 100644 src/components/icons/Inbox.vue diff --git a/components.d.ts b/components.d.ts index 3d83647..6f7f8d8 100644 --- a/components.d.ts +++ b/components.d.ts @@ -30,6 +30,8 @@ declare module 'vue' { AsyncSelect: typeof import('./src/components/ui/AsyncSelect.vue')['default'] BaseTable: typeof import('./src/components/ui/BaseTable.vue')['default'] Bell: typeof import('./src/components/icons/Bell.vue')['default'] + BellDot: typeof import('./src/components/icons/BellDot.vue')['default'] + BellOff: typeof import('./src/components/icons/BellOff.vue')['default'] Chart: typeof import('./src/components/icons/Chart.vue')['default'] CheckCircleIcon: typeof import('./src/components/icons/CheckCircleIcon.vue')['default'] CheckIcon: typeof import('./src/components/icons/CheckIcon.vue')['default'] @@ -53,6 +55,7 @@ declare module 'vue' { HeartIcon: typeof import('./src/components/icons/HeartIcon.vue')['default'] Home: typeof import('./src/components/icons/Home.vue')['default'] ImageIcon: typeof import('./src/components/icons/ImageIcon.vue')['default'] + Inbox: typeof import('./src/components/icons/Inbox.vue')['default'] InfoIcon: typeof import('./src/components/icons/InfoIcon.vue')['default'] LanguageIcon: typeof import('./src/components/icons/LanguageIcon.vue')['default'] Layout: typeof import('./src/components/icons/Layout.vue')['default'] @@ -121,6 +124,8 @@ declare global { const AsyncSelect: typeof import('./src/components/ui/AsyncSelect.vue')['default'] const BaseTable: typeof import('./src/components/ui/BaseTable.vue')['default'] const Bell: typeof import('./src/components/icons/Bell.vue')['default'] + const BellDot: typeof import('./src/components/icons/BellDot.vue')['default'] + const BellOff: typeof import('./src/components/icons/BellOff.vue')['default'] const Chart: typeof import('./src/components/icons/Chart.vue')['default'] const CheckCircleIcon: typeof import('./src/components/icons/CheckCircleIcon.vue')['default'] const CheckIcon: typeof import('./src/components/icons/CheckIcon.vue')['default'] @@ -144,6 +149,7 @@ declare global { const HeartIcon: typeof import('./src/components/icons/HeartIcon.vue')['default'] const Home: typeof import('./src/components/icons/Home.vue')['default'] const ImageIcon: typeof import('./src/components/icons/ImageIcon.vue')['default'] + const Inbox: typeof import('./src/components/icons/Inbox.vue')['default'] const InfoIcon: typeof import('./src/components/icons/InfoIcon.vue')['default'] const LanguageIcon: typeof import('./src/components/icons/LanguageIcon.vue')['default'] const Layout: typeof import('./src/components/icons/Layout.vue')['default'] diff --git a/src/components/DashboardNav.vue b/src/components/DashboardNav.vue index ee20e4b..e3b67a2 100644 --- a/src/components/DashboardNav.vue +++ b/src/components/DashboardNav.vue @@ -9,18 +9,16 @@ import { useAuthStore } from "@/stores/auth"; import { useTranslation } from "i18next-vue"; import { computed, createStaticVNode, h, ref } from "vue"; import NotificationDrawer from "./NotificationDrawer.vue"; +import Chart from "./icons/Chart.vue"; const className = ":uno: w-12 h-12 p-2 rounded-2xl hover:bg-primary/15 flex press-animated items-center justify-center shrink-0"; const homeHoist = createStaticVNode(`Logo`, 1); const notificationPopover = ref>(); const isNotificationOpen = ref(false); const { t } = useTranslation(); -const auth = useAuthStore(); const notificationStore = useNotifications(); const unreadCount = computed(() => notificationStore.unreadCount.value); -const isAdmin = computed(() => String(auth.user?.role || "").toLowerCase() === "admin"); - const handleNotificationClick = (event: Event) => { notificationPopover.value?.toggle(event); }; @@ -39,6 +37,10 @@ const links = computed>(() => { id: "videos", href: "/videos", label: t("nav.videos"), icon: Video, action: null, className }, + { + id: "analytics", + href: "/analytics", label: t("nav.analytics"), icon: Chart, action: null, className + }, { id: "notification", href: "/notification", @@ -70,7 +72,7 @@ const links = computed>(() => {
{ @@ -98,7 +99,7 @@ defineExpose({ toggle });
- +

{{ t('notification.empty.title') }}

diff --git a/src/components/icons/AlertTriangle.vue b/src/components/icons/AlertTriangle.vue index 92b75e9..6279d97 100644 --- a/src/components/icons/AlertTriangle.vue +++ b/src/components/icons/AlertTriangle.vue @@ -5,9 +5,6 @@ defineProps<{ diff --git a/src/components/icons/Bell.vue b/src/components/icons/Bell.vue index d7d675f..62bf0f5 100644 --- a/src/components/icons/Bell.vue +++ b/src/components/icons/Bell.vue @@ -1,5 +1,5 @@ + diff --git a/src/components/icons/BellOff.vue b/src/components/icons/BellOff.vue new file mode 100644 index 0000000..40bd21a --- /dev/null +++ b/src/components/icons/BellOff.vue @@ -0,0 +1,7 @@ + + diff --git a/src/components/icons/Chart.vue b/src/components/icons/Chart.vue index 5768f5c..9261c17 100644 --- a/src/components/icons/Chart.vue +++ b/src/components/icons/Chart.vue @@ -1,6 +1,6 @@ diff --git a/src/components/icons/Credit.vue b/src/components/icons/Credit.vue index 2d6ecbd..8546f35 100644 --- a/src/components/icons/Credit.vue +++ b/src/components/icons/Credit.vue @@ -1,5 +1,5 @@ diff --git a/src/components/icons/Home.vue b/src/components/icons/Home.vue index 8e172c4..f2800c8 100644 --- a/src/components/icons/Home.vue +++ b/src/components/icons/Home.vue @@ -4,7 +4,7 @@ fill="var(--fill1)" /> + fill="currentColor" /> + + + + diff --git a/src/components/icons/ListIcon.vue b/src/components/icons/ListIcon.vue index 59434ac..f902573 100644 --- a/src/components/icons/ListIcon.vue +++ b/src/components/icons/ListIcon.vue @@ -1,5 +1,5 @@ diff --git a/src/components/icons/SettingsIcon.vue b/src/components/icons/SettingsIcon.vue index 29d5e6d..dd7a483 100644 --- a/src/components/icons/SettingsIcon.vue +++ b/src/components/icons/SettingsIcon.vue @@ -1,5 +1,5 @@
+
+
+
+ + + { const unreadCount = computed(() => notificationStore.unreadCount.value); const tabs = computed(() => [ - { key: 'all', label: t('notification.tabs.all'), icon: 'i-lucide-inbox', count: notificationStore.notifications.value.length }, - { key: 'unread', label: t('notification.tabs.unread'), icon: 'i-lucide-bell-dot', count: unreadCount.value }, - { key: 'video', label: t('notification.tabs.videos'), icon: 'i-lucide-video', count: notificationStore.notifications.value.filter(n => n.type === 'video').length }, - { key: 'payment', label: t('notification.tabs.payments'), icon: 'i-lucide-credit-card', count: notificationStore.notifications.value.filter(n => n.type === 'payment').length }, + { key: 'all', label: t('notification.tabs.all'), icon: Inbox, count: notificationStore.notifications.value.length }, + { key: 'unread', label: t('notification.tabs.unread'), icon: BellDot, count: unreadCount.value }, + { key: 'video', label: t('notification.tabs.videos'), icon: Video, count: notificationStore.notifications.value.filter(n => n.type === 'video').length }, + { key: 'payment', label: t('notification.tabs.payments'), icon: Credit, count: notificationStore.notifications.value.filter(n => n.type === 'payment').length }, ]); const filteredNotifications = computed(() => { diff --git a/src/routes/notification/components/NotificationActions.vue b/src/routes/notification/components/NotificationActions.vue index 07dff75..21bfb69 100644 --- a/src/routes/notification/components/NotificationActions.vue +++ b/src/routes/notification/components/NotificationActions.vue @@ -1,4 +1,7 @@