veza/apps/web/src/components/notifications/NotificationItem.tsx

95 lines
2.7 KiB
TypeScript
Raw Normal View History

import React from 'react';
import {
Heart,
UserPlus,
MessageSquare,
DollarSign,
Info,
ShieldAlert,
Circle,
} from 'lucide-react';
import { Notification } from '../../types';
import { Button } from '../ui/button';
interface NotificationItemProps {
notification: Notification;
onRead: (id: string) => void;
onAction?: (notification: Notification) => void;
}
export const NotificationItem: React.FC<NotificationItemProps> = ({
notification,
onRead,
onAction,
}) => {
const getIcon = () => {
switch (notification.type) {
case 'like':
return <Heart className="w-4 h-4 text-kodo-magenta fill-current" />;
case 'follow':
return <UserPlus className="w-4 h-4 text-kodo-cyan" />;
case 'mention':
return <MessageSquare className="w-4 h-4 text-kodo-gold" />;
case 'sale':
return <DollarSign className="w-4 h-4 text-kodo-lime" />;
case 'security':
return <ShieldAlert className="w-4 h-4 text-kodo-red" />;
default:
return <Info className="w-4 h-4 text-kodo-content-dim" />;
}
};
const getBgColor = () => {
if (notification.read) return 'bg-transparent';
switch (notification.type) {
case 'sale':
return 'bg-kodo-lime/5 border-l-2 border-l-kodo-lime';
case 'security':
return 'bg-kodo-red/5 border-l-2 border-l-kodo-red';
default:
return 'bg-kodo-cyan/5 border-l-2 border-l-kodo-cyan';
}
};
return (
<div
className={`p-4 rounded-lg flex items-start gap-4 transition-all hover:bg-white/5 group border border-transparent ${getBgColor()}`}
>
<div className="flex-shrink-0 mt-1 p-2 bg-kodo-graphite rounded-full border border-kodo-steel shadow-sm">
{getIcon()}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm text-kodo-text-main leading-relaxed">
{notification.message}
</p>
<span className="text-xs text-kodo-content-dim font-mono mt-1 block">
{notification.timestamp}
</span>
</div>
<div className="flex flex-col gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
{!notification.read && (
<button
onClick={() => onRead(notification.id)}
className="p-1.5 hover:bg-white/10 rounded-full text-kodo-cyan"
title="Mark as read"
>
<Circle className="w-3 h-3 fill-current" />
</button>
)}
{notification.actionUrl && (
<Button
variant="ghost"
size="sm"
className="text-xs"
onClick={() => onAction && onAction(notification)}
>
View
</Button>
)}
</div>
</div>
);
};