fix: clipboard error handling, Escape key support, per-notification read state

This commit is contained in:
Agent Zero
2026-06-28 12:24:35 +02:00
parent 91dceaae14
commit 0f6889cd06
3 changed files with 26 additions and 9 deletions
+5 -1
View File
@@ -27,8 +27,12 @@ const quickStart: { step: number; text: string }[] = [
const HelpPanel: React.FC<HelpPanelProps> = ({ open, onClose }) => {
if (!open) return null;
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
return (
<div className="modal-backdrop" onClick={onClose}>
<div className="modal-backdrop" onClick={onClose} onKeyDown={handleKeyDown} tabIndex={-1}>
<div className="modal-panel help-panel" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h2>Hilfe</h2>
+14 -7
View File
@@ -6,17 +6,17 @@ interface Notification {
icon: string;
title: string;
timestamp: string;
read: boolean;
}
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.' },
{ id: 'n1', icon: '💾', title: 'Projekt automatisch gespeichert', timestamp: 'vor 2 Min.', read: false },
{ id: 'n2', icon: '🔄', title: 'Neue Version verfügbar', timestamp: 'vor 15 Min.', read: false },
{ id: 'n3', icon: '👤', title: 'Benutzer ist beigetreten', timestamp: 'vor 1 Std.', read: false },
];
const NotificationPanel: React.FC<NotificationPanelProps> = ({ open, onClose }) => {
const [notifications, setNotifications] = useState<Notification[]>(initialNotifications);
const [allRead, setAllRead] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
@@ -26,8 +26,15 @@ const NotificationPanel: React.FC<NotificationPanelProps> = ({ open, onClose })
onClose();
}
};
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
document.addEventListener('keydown', handleKeyDown);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('keydown', handleKeyDown);
};
}, [open, onClose]);
if (!open) return null;
@@ -37,7 +44,7 @@ const NotificationPanel: React.FC<NotificationPanelProps> = ({ open, onClose })
};
const handleMarkAllRead = () => {
setAllRead(true);
setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
};
return (
@@ -53,7 +60,7 @@ const NotificationPanel: React.FC<NotificationPanelProps> = ({ open, onClose })
<p className="notif-empty">Keine Benachrichtigungen</p>
) : (
notifications.map((n) => (
<div key={n.id} className={`notif-item ${allRead ? 'read' : ''}`}>
<div key={n.id} className={`notif-item ${n.read ? 'read' : ''}`}>
<span className="notif-icon">{n.icon}</span>
<div className="notif-content">
<span className="notif-title">{n.title}</span>
+7 -1
View File
@@ -14,9 +14,15 @@ const ShareDialog: React.FC<ShareDialogProps> = ({ open, onClose, projectName })
navigator.clipboard.writeText(shareLink).then(() => {
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}).catch(() => {
setCopied(false);
});
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
const handleInvite = () => {
if (email.trim()) {
setInvited(true);
@@ -26,7 +32,7 @@ const ShareDialog: React.FC<ShareDialogProps> = ({ open, onClose, projectName })
};
return (
<div className="modal-backdrop" onClick={onClose}>
<div className="modal-backdrop" onClick={onClose} onKeyDown={handleKeyDown} tabIndex={-1}>
<div className="modal-panel share-dialog" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h2>Projekt teilen</h2>