Files

51 lines
2.0 KiB
TypeScript

'use client'
import React from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import { X, Info, AlertTriangle, CheckCircle, AlertCircle } from 'lucide-react'
import { useNotificationStore, type NotificationType } from '../../store/notificationStore'
const icons: Record<NotificationType, React.ReactNode> = {
info: <Info className="w-4 h-4 flex-shrink-0" />,
warning: <AlertTriangle className="w-4 h-4 flex-shrink-0" />,
success: <CheckCircle className="w-4 h-4 flex-shrink-0" />,
error: <AlertCircle className="w-4 h-4 flex-shrink-0" />,
}
const styles: Record<NotificationType, string> = {
info: 'bg-[#1e293b] text-white border-l-4 border-l-blue-400',
warning: 'bg-[#1e293b] text-white border-l-4 border-l-amber-400',
success: 'bg-[#1e293b] text-white border-l-4 border-l-emerald-400',
error: 'bg-[#1e293b] text-white border-l-4 border-l-red-400',
}
export default function NotificationToast() {
const { notifications, remove } = useNotificationStore()
return (
<div className="fixed top-4 right-4 z-[9999] flex flex-col gap-2 pointer-events-none">
<AnimatePresence>
{notifications.map((n) => (
<motion.div
key={n.id}
initial={{ opacity: 0, x: 60, scale: 0.95 }}
animate={{ opacity: 1, x: 0, scale: 1 }}
exit={{ opacity: 0, x: 60, scale: 0.95 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
className={`pointer-events-auto flex items-start gap-3 px-4 py-3 rounded-lg shadow-xl text-sm max-w-sm ${styles[n.type]}`}
>
<span className="mt-0.5">{icons[n.type]}</span>
<span className="flex-1 leading-snug">{n.message}</span>
<button
onClick={() => remove(n.id)}
className="ml-1 opacity-60 hover:opacity-100 transition-opacity"
>
<X className="w-3.5 h-3.5" />
</button>
</motion.div>
))}
</AnimatePresence>
</div>
)
}