Files
web-cad/frontend/src/components/NotificationPanel.tsx
T

79 lines
3.0 KiB
TypeScript
Raw Normal View History

import React, { useState, useEffect, useRef } from 'react';
import type { NotificationPanelProps } from '../types/ui.types';
interface Notification {
id: string;
icon: string;
title: string;
timestamp: string;
}
const initialNotifications: Notification[] = [
{ id: 'n1', icon: '💾', title: 'Projekt automatisch gespeichert', timestamp: 'vor 2 Min.' },
{ id: 'n2', icon: '🔄', title: 'Neue Version verfügbar', timestamp: 'vor 15 Min.' },
{ id: 'n3', icon: '👤', title: 'Benutzer ist beigetreten', timestamp: 'vor 1 Std.' },
];
const NotificationPanel: React.FC<NotificationPanelProps> = ({ open, onClose }) => {
const [notifications, setNotifications] = useState<Notification[]>(initialNotifications);
const [allRead, setAllRead] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!open) return;
const handleClickOutside = (e: MouseEvent) => {
if (ref.current && !ref.current.contains(e.target as Node)) {
onClose();
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [open, onClose]);
if (!open) return null;
const handleDismiss = (id: string) => {
setNotifications((prev) => prev.filter((n) => n.id !== id));
};
const handleMarkAllRead = () => {
setAllRead(true);
};
return (
<div className="notif-panel" ref={ref}>
<div className="notif-header">
<h3>Benachrichtigungen</h3>
<button className="notif-close" aria-label="Schließen" onClick={onClose}>
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<div className="notif-list">
{notifications.length === 0 ? (
<p className="notif-empty">Keine Benachrichtigungen</p>
) : (
notifications.map((n) => (
<div key={n.id} className={`notif-item ${allRead ? 'read' : ''}`}>
<span className="notif-icon">{n.icon}</span>
<div className="notif-content">
<span className="notif-title">{n.title}</span>
<span className="notif-time">{n.timestamp}</span>
</div>
<button className="notif-dismiss" aria-label="Entfernen" onClick={() => handleDismiss(n.id)}>
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
))
)}
</div>
{notifications.length > 0 && (
<button className="notif-mark-all" onClick={handleMarkAllRead}>
Alle als gelesen markieren
</button>
)}
</div>
);
};
export default NotificationPanel;