feat: Add visual feedback and polish (Task 15)
- Implement toast notification system for success/error messages - Add loading states with skeleton loaders for async operations - Create smooth CSS transitions and animations - Enhance empty states with EmptyState component - Add loading.tsx files for Next.js loading states - Integrate toast notifications across all CRUD operations - Add fade-in and scale-in animations for better UX - Improve visual feedback for user actions
This commit is contained in:
51
components/Toast.tsx
Normal file
51
components/Toast.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { CheckCircle, XCircle, AlertCircle, X } from 'lucide-react'
|
||||
|
||||
export type ToastType = 'success' | 'error' | 'info'
|
||||
|
||||
interface ToastProps {
|
||||
message: string
|
||||
type: ToastType
|
||||
onClose: () => void
|
||||
duration?: number
|
||||
}
|
||||
|
||||
export default function Toast({ message, type, onClose, duration = 3000 }: ToastProps) {
|
||||
useEffect(() => {
|
||||
if (duration > 0) {
|
||||
const timer = setTimeout(onClose, duration)
|
||||
return () => clearTimeout(timer)
|
||||
}
|
||||
}, [duration, onClose])
|
||||
|
||||
const icons = {
|
||||
success: <CheckCircle size={20} className="flex-shrink-0" />,
|
||||
error: <XCircle size={20} className="flex-shrink-0" />,
|
||||
info: <AlertCircle size={20} className="flex-shrink-0" />,
|
||||
}
|
||||
|
||||
const styles = {
|
||||
success: 'bg-green-50 border-green-200 text-green-800',
|
||||
error: 'bg-red-50 border-red-200 text-red-800',
|
||||
info: 'bg-blue-50 border-blue-200 text-blue-800',
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center gap-3 px-4 py-3 rounded-lg border shadow-lg ${styles[type]} animate-slide-in-right`}
|
||||
role="alert"
|
||||
>
|
||||
{icons[type]}
|
||||
<p className="flex-1 text-sm font-medium">{message}</p>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="text-current opacity-70 hover:opacity-100 transition-opacity tap-target-sm"
|
||||
aria-label="Close notification"
|
||||
>
|
||||
<X size={18} />
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user