tahamajs/IE / Projects /front /src /components /dashboard /NotificationsPanel.tsx
tahamajs's picture
download
raw
4.83 kB
// src/components/dashboard/NotificationsPanel.tsx
import { Link } from "react-router-dom";
import { Bell, Heart, MessageCircle, User, AtSign, Sparkles, ArrowRight, CheckCheck } from "lucide-react";
import type { Notification } from "@/pages/DashboardPage";
interface NotificationsPanelProps {
notifications: Notification[];
unreadCount: number;
onMarkRead: (id: number) => void;
onMarkAllRead: () => void;
}
function getNotificationIcon(type: string) {
switch (type) {
case "like": return <Heart className="h-4 w-4 text-pink-500" />;
case "comment": return <MessageCircle className="h-4 w-4 text-blue-500" />;
case "follow": return <User className="h-4 w-4 text-green-500" />;
case "mention": return <AtSign className="h-4 w-4 text-purple-500" />;
default: return <Bell className="h-4 w-4 text-gray-500" />;
}
}
export function NotificationsPanel({ notifications: rawNotifications, unreadCount, onMarkRead, onMarkAllRead }: NotificationsPanelProps) {
const notifications = Array.isArray(rawNotifications) ? rawNotifications : [];
return (
<div className="rounded-[2rem] border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-700 dark:bg-slate-800">
<div className="mb-4 flex flex-wrap items-start justify-between gap-4">
<div>
<div className="inline-flex items-center gap-2 rounded-full bg-blue-50 px-3 py-1 text-xs font-semibold text-blue-700 dark:bg-blue-950/40 dark:text-blue-300">
<Sparkles className="h-3.5 w-3.5" />
Live updates
</div>
<h2 className="mt-3 flex items-center gap-2 text-xl font-semibold text-slate-900 dark:text-white">
<Bell className="h-5 w-5 text-primary" /> Notifications
{unreadCount > 0 && (
<span className="rounded-full bg-rose-500 px-2.5 py-0.5 text-xs text-white">
{unreadCount}
</span>
)}
</h2>
<p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
Keep track of reactions, mentions, follows, and system updates in one place.
</p>
</div>
{unreadCount > 0 && (
<button
onClick={onMarkAllRead}
className="inline-flex items-center gap-2 rounded-full border border-slate-300 px-3 py-1.5 text-xs font-medium text-slate-700 transition hover:border-sky-200 hover:text-sky-600 dark:border-slate-700 dark:text-slate-200"
>
<CheckCheck className="h-3.5 w-3.5" />
Mark all read
</button>
)}
</div>
<div className="space-y-2 max-h-[420px] overflow-y-auto pr-1">
{notifications.length === 0 ? (
<div className="rounded-[1.75rem] border border-dashed border-slate-200 bg-slate-50/80 p-6 text-center dark:border-slate-700 dark:bg-slate-900/60">
<Bell className="mx-auto h-10 w-10 text-slate-400" />
<p className="mt-2 text-sm font-medium text-slate-700 dark:text-slate-200">You’re all caught up</p>
<p className="mt-1 text-xs text-slate-500 dark:text-slate-400">
New likes, comments, follows, and mentions will appear here as they come in.
</p>
<Link to="/notifications" className="mt-4 inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-xs font-medium text-white transition hover:bg-primary/90">
Open notifications <ArrowRight className="h-3.5 w-3.5" />
</Link>
</div>
) : (
notifications.map((notification) => (
<Link
key={notification.id}
to={notification.link || "#"}
onClick={() => onMarkRead(notification.id)}
className={`block rounded-[1.5rem] border p-3 transition hover:-translate-y-0.5 ${
!notification.read
? "border-blue-100 bg-blue-50/70 dark:border-blue-900/40 dark:bg-blue-950/20"
: "border-slate-200 bg-slate-50/70 dark:border-slate-700 dark:bg-slate-900/60"
}`}
>
<div className="flex gap-3">
<div className="flex-shrink-0">
{getNotificationIcon(notification.type)}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-slate-900 dark:text-white">{notification.title}</p>
<p className="mt-0.5 text-xs leading-5 text-slate-500 dark:text-slate-400">{notification.body}</p>
<p className="mt-1 text-xs text-slate-400 dark:text-slate-500">
{new Date(notification.createdAt).toLocaleDateString()}
</p>
</div>
</div>
</Link>
))
)}
</div>
</div>
);
}

Xet Storage Details

Size:
4.83 kB
·
Xet hash:
91cddabc6e520a0d215c9446baba803495efe0bd1393a979959077ce1cc5ec1f

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.