From d292676b7399396332665039b2a3f6bcba7dbb45 Mon Sep 17 00:00:00 2001 From: Nick Sandstrom <32273437+nick4810@users.noreply.github.com> Date: Mon, 2 Mar 2026 23:23:01 -0800 Subject: [PATCH] Component cleanup and refactoring --- .../src/components/M3URefreshNotification.jsx | 24 +--------- .../src/components/NotificationCenter.jsx | 48 +++++++++++-------- frontend/src/components/Sidebar.jsx | 32 ++++++------- 3 files changed, 45 insertions(+), 59 deletions(-) diff --git a/frontend/src/components/M3URefreshNotification.jsx b/frontend/src/components/M3URefreshNotification.jsx index af7f9aa5..5b40cadb 100644 --- a/frontend/src/components/M3URefreshNotification.jsx +++ b/frontend/src/components/M3URefreshNotification.jsx @@ -48,7 +48,7 @@ export default function M3URefreshNotification() { const refreshProgress = usePlaylistsStore((s) => s.refreshProgress); const fetchStreams = useStreamsStore((s) => s.fetchStreams); const fetchChannelGroups = useChannelsStore((s) => s.fetchChannelGroups); - const fetchChannelIds = useChannelsStore((s) => s.fetchChannelIds); + const fetchChannels = useChannelsStore((s) => s.fetchChannels); const fetchPlaylists = usePlaylistsStore((s) => s.fetchPlaylists); const fetchEPGData = useEPGsStore((s) => s.fetchEPGData); const fetchCategories = useVODStore((s) => s.fetchCategories); @@ -151,28 +151,6 @@ export default function M3URefreshNotification() { triggerPostCompletionFetches(data.action); } - if (taskProgress == 0) { - message = `${message} starting...`; - } else if (taskProgress == 100) { - message = `${message} complete!`; - - // Only trigger additional fetches on successful completion - if (data.action == 'parsing') { - fetchStreams(); - API.requeryChannels(); - fetchChannelIds(); - } else if (data.action == 'processing_groups') { - fetchStreams(); - fetchChannelGroups(); - fetchEPGData(); - fetchPlaylists(); - } else if (data.action == 'vod_refresh') { - // VOD refresh completed, trigger VOD categories refresh - fetchPlaylists(); // Refresh playlist data to show updated VOD info - fetchCategories(); // Refresh VOD categories to make them visible - } - } - showNotification({ title: `M3U Processing: ${playlist.name}`, message, diff --git a/frontend/src/components/NotificationCenter.jsx b/frontend/src/components/NotificationCenter.jsx index f7da56ad..b6bbdcfb 100644 --- a/frontend/src/components/NotificationCenter.jsx +++ b/frontend/src/components/NotificationCenter.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useCallback } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { ActionIcon, @@ -10,7 +10,9 @@ import { Group, Indicator, Popover, - ScrollArea, + PopoverDropdown, + PopoverTarget, + ScrollAreaAutosize, Stack, Text, ThemeIcon, @@ -18,22 +20,26 @@ import { useMantineTheme, } from '@mantine/core'; import { + AlertTriangle, + ArrowRight, Bell, Check, CheckCheck, Download, ExternalLink, - Info, - Settings, - AlertTriangle, - Megaphone, - X, Eye, EyeOff, - ArrowRight, + Info, + Megaphone, + Settings, + X, } from 'lucide-react'; import useNotificationsStore from '../store/notifications'; -import API from '../api'; +import { + dismissAllNotifications, + dismissNotification, + getNotifications, +} from '../utils/components/NotificationCenterUtils.js'; // Get icon for notification type const getNotificationIcon = (type) => { @@ -139,7 +145,9 @@ const NotificationItem = ({ notification, onDismiss, onAction, onClose }) => { color="gray" size="sm" onClick={handleDismiss} - style={{ position: 'absolute', top: 8, right: 8 }} + pos='absolute' + top={8} + right={8} > @@ -149,7 +157,7 @@ const NotificationItem = ({ notification, onDismiss, onAction, onClose }) => { {getNotificationIcon(notification.notification_type)} - + {notification.title} @@ -249,7 +257,7 @@ const NotificationCenter = ({ onSettingAction }) => { // Fetch notifications on mount and periodically const fetchNotifications = useCallback(async () => { try { - await API.getNotifications(showDismissed); + await getNotifications(showDismissed); } catch (error) { console.error('Failed to fetch notifications:', error); } @@ -265,7 +273,7 @@ const NotificationCenter = ({ onSettingAction }) => { const handleDismiss = async (notificationId, actionTaken = null) => { try { - await API.dismissNotification(notificationId, actionTaken); + await dismissNotification(notificationId, actionTaken); } catch (error) { console.error('Failed to dismiss notification:', error); } @@ -273,7 +281,7 @@ const NotificationCenter = ({ onSettingAction }) => { const handleDismissAll = async () => { try { - await API.dismissAllNotifications(); + await dismissAllNotifications(); } catch (error) { console.error('Failed to dismiss all notifications:', error); } @@ -302,7 +310,7 @@ const NotificationCenter = ({ onSettingAction }) => { shadow="lg" withArrow > - + { - + - + {/* Header */} @@ -367,7 +375,7 @@ const NotificationCenter = ({ onSettingAction }) => { {/* Notification list */} - + {displayedNotifications.length === 0 ? ( { ))} )} - + {/* Footer with info text */} {!showDismissed && @@ -421,7 +429,7 @@ const NotificationCenter = ({ onSettingAction }) => { )} - + ); }; diff --git a/frontend/src/components/Sidebar.jsx b/frontend/src/components/Sidebar.jsx index a90a8d96..67f721cd 100644 --- a/frontend/src/components/Sidebar.jsx +++ b/frontend/src/components/Sidebar.jsx @@ -84,18 +84,16 @@ function NavGroup({ label, icon, paths, location, collapsed }) { .includes(location.pathname); return ( - - setOpen((o) => !o)} className={`navlink ${parentActive ? 'navlink-parent-active' : ''} ${open ? 'navlink-collapsed' : ''}`} - style={{ width: '100%' }} > {icon} {!collapsed && ( - + - + {open ? : } @@ -117,13 +115,13 @@ function NavGroup({ label, icon, paths, location, collapsed }) { {open && ( - + {paths.map((child) => { const active = location.pathname === child.path; return ( { p="xs" mih="100vh" display='flex' + br='1px solid #2A2A2E' style={{ backgroundColor: '#1A1A1E', - borderRight: '1px solid #2A2A2E', flexDirection: 'column', }} > @@ -297,9 +295,9 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => { { mt='auto' p={16} display='flex' + bt='1px solid #2A2A2E' style={{ alignItems: 'center', gap: 10, - borderTop: '1px solid #2A2A2E', justifyContent: collapsed ? 'center' : 'flex-start', }} > @@ -378,7 +376,8 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => { {!collapsed && authUser && ( @@ -404,7 +403,8 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => { {!collapsed && ( v{appVersion?.version || '0.0.0'} @@ -415,9 +415,9 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => { )} {collapsed && isAuthenticated && (