krona-front/src/app/shell/NotificationsDrawer.tsx

107 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import { useDemoStore } from '../../mock/store';
import { Drawer } from '../../shared/components/Drawer';
import { Button } from '../../shared/components/Button';
import { Bell, AlertTriangle, AlertCircle, CheckCircle2, Info, Check, Trash2 } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
export const NotificationsDrawer: React.FC = () => {
const {
isNotificationsOpen,
setIsNotificationsOpen,
notifications,
dismissNotification,
markAllNotificationsRead,
} = useDemoStore();
const navigate = useNavigate();
const getIcon = (type: string) => {
switch (type) {
case 'danger':
return <AlertCircle className="w-4 h-4 text-krona-danger" />;
case 'warning':
return <AlertTriangle className="w-4 h-4 text-krona-warning" />;
case 'success':
return <CheckCircle2 className="w-4 h-4 text-krona-green" />;
default:
return <Info className="w-4 h-4 text-krona-info" />;
}
};
return (
<Drawer
isOpen={isNotificationsOpen}
onClose={() => setIsNotificationsOpen(false)}
title="Центр внимания и уведомлений"
subtitle="Срочные алерты, статус кассы, стоп-листы и опоздания"
width="md"
footer={
<div className="w-full flex items-center justify-between">
<Button variant="ghost" size="sm" onClick={markAllNotificationsRead}>
<Check className="w-3.5 h-3.5 mr-1.5" />
Прочитать все
</Button>
<Button variant="secondary" size="sm" onClick={() => setIsNotificationsOpen(false)}>
Закрыть
</Button>
</div>
}
>
<div className="space-y-3">
{notifications.length === 0 ? (
<div className="py-12 text-center text-krona-secondary text-xs">
<Bell className="w-8 h-8 mx-auto mb-2 opacity-30" />
Нет активных уведомлений. Все системы в норме!
</div>
) : (
notifications.map((n) => (
<div
key={n.id}
className={`p-3.5 rounded-lg border transition-all ${
n.read
? 'bg-krona-surface/40 border-krona-border/60 opacity-80'
: 'bg-krona-surface border-krona-border shadow-krona-soft'
}`}
>
<div className="flex items-start gap-2.5">
<div className="mt-0.5 shrink-0">{getIcon(n.type)}</div>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between gap-2 mb-1">
<h5 className="text-xs font-semibold text-krona-primary truncate">{n.title}</h5>
<span className="text-[10px] text-krona-secondary whitespace-nowrap">{n.timestamp}</span>
</div>
<p className="text-xs text-krona-secondary leading-relaxed">{n.message}</p>
<div className="mt-2.5 flex items-center justify-between pt-1 border-t border-krona-border/40">
{n.actionUrl ? (
<button
onClick={() => {
setIsNotificationsOpen(false);
navigate(n.actionUrl!);
}}
className="text-xs text-krona-green font-medium hover:underline"
>
Перейти к решению →
</button>
) : (
<span />
)}
<button
onClick={() => dismissNotification(n.id)}
className="text-krona-secondary hover:text-krona-danger p-1 rounded"
title="Удалить"
>
<Trash2 className="w-3.5 h-3.5" />
</button>
</div>
</div>
</div>
</div>
))
)}
</div>
</Drawer>
);
};