diff --git a/frontend/src/components/AppShell.tsx b/frontend/src/components/AppShell.tsx
index 1f7bb5d5..e702a5f0 100644
--- a/frontend/src/components/AppShell.tsx
+++ b/frontend/src/components/AppShell.tsx
@@ -76,6 +76,25 @@ function Header({ onOpenLeftNav, onOpenCalendar }: HeaderProps) {
return () => document.removeEventListener("mousedown", handler);
}, [userMenuOpen]);
+ // Закрытие панели уведомлений при клике вне
+ useEffect(() => {
+ if (!isNotificationsOpen) return;
+ const handler = (e: MouseEvent) => {
+ const target = e.target as Node;
+ const notificationButton = document.querySelector('[aria-label="Уведомления"]');
+ const notificationPanel = document.querySelector('.notification-panel-mobile');
+
+ const insideButton = notificationButton && notificationButton.contains(target);
+ const insidePanel = notificationPanel && notificationPanel.contains(target);
+
+ if (!insideButton && !insidePanel) {
+ setIsNotificationsOpen(false);
+ }
+ };
+ document.addEventListener("mousedown", handler);
+ return () => document.removeEventListener("mousedown", handler);
+ }, [isNotificationsOpen]);
+
const userInitials = user
? `${user.last_name?.[0] || ''}${user.first_name?.[0] || ''}`
: 'Г';
@@ -226,7 +245,7 @@ function Header({ onOpenLeftNav, onOpenCalendar }: HeaderProps) {
{/* Мобильная панель уведомлений */}
diff --git a/frontend/src/components/NotificationCenter.tsx b/frontend/src/components/NotificationCenter.tsx
index c10e487f..bab4be8b 100644
--- a/frontend/src/components/NotificationCenter.tsx
+++ b/frontend/src/components/NotificationCenter.tsx
@@ -40,8 +40,12 @@ export function NotificationCenter({ variant = 'default', isOpen: externalIsOpen
}
};
- // Закрытие при клике вне компонента
+ // Закрытие при клике вне компонента (только для desktop варианта)
useEffect(() => {
+ // Для mobile варианта не используем этот обработчик,
+ // т.к. панель уведомлений рендерится отдельно в AppShell
+ if (!isOpen || variant === 'mobile') return;
+
function handleClickOutside(event: MouseEvent) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
close();
@@ -50,7 +54,7 @@ export function NotificationCenter({ variant = 'default', isOpen: externalIsOpen
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
- }, [isOpen]);
+ }, [isOpen, variant]);
const handleNotificationClick = async (notification: any) => {
if (!notification.is_read) {
@@ -92,7 +96,10 @@ export function NotificationCenter({ variant = 'default', isOpen: externalIsOpen
{unreadCount > 0 && (