diff --git a/client/src/components/notification-center/notification-center.component.jsx b/client/src/components/notification-center/notification-center.component.jsx index 3db86d108..c7e6d4f58 100644 --- a/client/src/components/notification-center/notification-center.component.jsx +++ b/client/src/components/notification-center/notification-center.component.jsx @@ -1,5 +1,5 @@ import { Virtuoso } from "react-virtuoso"; -import { Alert, Badge, Button, Space, Spin, Tooltip, Typography } from "antd"; +import { Alert, Badge, Button, Space, Spin, Switch, Tooltip, Typography } from "antd"; import { CheckCircleFilled, CheckCircleOutlined, EyeFilled, EyeOutlined } from "@ant-design/icons"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; @@ -11,7 +11,7 @@ const { Text, Title } = Typography; /** * Notification Center Component - * @type {React.ForwardRefExoticComponent & React.RefAttributes>} + * @type {React.ForwardRefExoticComponent & React.RefAttributes>} */ const NotificationCenterComponent = forwardRef( ( @@ -20,7 +20,6 @@ const NotificationCenterComponent = forwardRef( onClose, notifications, loading, - error, showUnreadOnly, toggleUnreadOnly, markAllRead, @@ -79,20 +78,23 @@ const NotificationCenterComponent = forwardRef(

{t("notifications.labels.notification-center")}

- {loading && !error && } + {loading && }
-
- {error && onClose()} />} { const [showUnreadOnly, setShowUnreadOnly] = useState(false); const [notifications, setNotifications] = useState([]); - const [error, setError] = useState(null); const { isConnected, markNotificationRead, markAllNotificationsRead } = useSocket(); const notificationRef = useRef(null); // Add ref for the notification center @@ -37,13 +36,7 @@ const NotificationCenterContainer = ({ visible, onClose, bodyshop, unreadCount } return showUnreadOnly ? { ...baseWhereClause, read: { _is_null: true } } : baseWhereClause; }, [baseWhereClause, showUnreadOnly]); - const { - data, - fetchMore, - loading, - error: queryError, - refetch - } = useQuery(GET_NOTIFICATIONS, { + const { data, fetchMore, loading, refetch } = useQuery(GET_NOTIFICATIONS, { variables: { limit: INITIAL_NOTIFICATIONS, offset: 0, @@ -54,7 +47,6 @@ const NotificationCenterContainer = ({ visible, onClose, bodyshop, unreadCount } pollInterval: isConnected ? 0 : day.duration(NOTIFICATION_POLL_INTERVAL_SECONDS, "seconds").asMilliseconds(), skip: !userAssociationId, onError: (err) => { - setError(err.message); console.error(`Error polling Notifications in notification-center: ${err?.message || ""}`); setTimeout(() => refetch(), day.duration(2, "seconds").asMilliseconds()); } @@ -63,6 +55,11 @@ const NotificationCenterContainer = ({ visible, onClose, bodyshop, unreadCount } // Handle click outside to close useEffect(() => { const handleClickOutside = (event) => { + // Prevent open + close behavior from the header + if (event.target.closest("#header-notifications")) { + return; + } + if (visible && notificationRef.current && !notificationRef.current.contains(event.target)) { onClose(); } @@ -104,16 +101,9 @@ const NotificationCenterContainer = ({ visible, onClose, bodyshop, unreadCount } }) .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); setNotifications(processedNotifications); - setError(null); } }, [data]); - useEffect(() => { - if (queryError) { - setError(queryError.message); - } - }, [queryError]); - const loadMore = useCallback(() => { if (!loading && data?.notifications.length) { fetchMore({ @@ -125,7 +115,6 @@ const NotificationCenterContainer = ({ visible, onClose, bodyshop, unreadCount } }; } }).catch((err) => { - setError(err.message); console.error("Fetch more error:", err); }); } @@ -187,7 +176,6 @@ const NotificationCenterContainer = ({ visible, onClose, bodyshop, unreadCount } onClose={onClose} notifications={notifications} loading={loading} - error={error} showUnreadOnly={showUnreadOnly} toggleUnreadOnly={handleToggleUnreadOnly} markAllRead={handleMarkAllRead} diff --git a/client/src/components/notification-center/notification-center.styles.scss b/client/src/components/notification-center/notification-center.styles.scss index 44e3fa601..89ae0beae 100644 --- a/client/src/components/notification-center/notification-center.styles.scss +++ b/client/src/components/notification-center/notification-center.styles.scss @@ -36,6 +36,38 @@ align-items: center; gap: 8px; + // Styles for the eye icon and switch (custom classes) + .notification-toggle { + align-items: center; // Ensure vertical alignment + } + + .notification-toggle-icon { + font-size: 14px; + color: #1677ff; + vertical-align: middle; + } + + .ant-switch { + &.ant-switch-small { + min-width: 28px; + height: 16px; + line-height: 16px; + + .ant-switch-handle { + width: 12px; + height: 12px; + } + + &.ant-switch-checked { + background-color: #1677ff; + .ant-switch-handle { + left: calc(100% - 14px); + } + } + } + } + + // Styles for the "Mark All Read" button (restore original link button style) .ant-btn-link { padding: 0; color: #1677ff; @@ -67,16 +99,16 @@ } .notification-item { - padding: 12px 16px; // Increased padding from 8px to 12px for more space + padding: 12px 16px; border-bottom: 1px solid #f0f0f0; display: block; overflow: visible; width: 100%; box-sizing: border-box; - cursor: pointer; // Add pointer cursor to indicate clickability + cursor: pointer; &:hover { - background: #fafafa; // Optional: Add hover effect for better UX + background: #fafafa; } .notification-content { diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 9eab4bf1d..fcc81ce1b 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -3779,8 +3779,8 @@ "teams-search": "Search for a Team", "add-watchers-team": "Add Team Members", "new-notification-title": "New Notification:", - "show-unread-only": "Show Unread", - "mark-all-read": "Mark Read", + "show-unread-only": "Show Unread Only", + "mark-all-read": "Mark All Read", "notification-popup-title": "Changes for Job #{{ro_number}}", "ro-number": "RO #{{ro_number}}", "no-watchers": "No Watchers",