| 1 |
/** |
| 2 |
* Alert Component |
| 3 |
* Displays important messages to users |
| 4 |
*/ |
| 5 |
|
| 6 |
import React from "react"; |
| 7 |
import { AlertCircle, CheckCircle, Info, XCircle, X } from "lucide-react"; |
| 8 |
|
| 9 |
interface AlertProps { |
| 10 |
variant?: "success" | "error" | "warning" | "info"; |
| 11 |
title?: string; |
| 12 |
children: React.ReactNode; |
| 13 |
onClose?: () => void; |
| 14 |
className?: string; |
| 15 |
} |
| 16 |
|
| 17 |
export const Alert: React.FC<AlertProps> = ({ |
| 18 |
variant = "info", |
| 19 |
title, |
| 20 |
children, |
| 21 |
onClose, |
| 22 |
className = "", |
| 23 |
}) => { |
| 24 |
const variantClasses = { |
| 25 |
success: |
| 26 |
"bg-green-50 text-green-800 border-green-200 dark:bg-green-900/20 dark:text-green-400 dark:border-green-800", |
| 27 |
error: |
| 28 |
"bg-red-50 text-red-800 border-red-200 dark:bg-red-900/20 dark:text-red-400 dark:border-red-800", |
| 29 |
warning: |
| 30 |
"bg-yellow-50 text-yellow-800 border-yellow-200 dark:bg-yellow-900/20 dark:text-yellow-400 dark:border-yellow-800", |
| 31 |
info: "bg-blue-50 text-blue-800 border-blue-200 dark:bg-blue-900/20 dark:text-blue-400 dark:border-blue-800", |
| 32 |
}; |
| 33 |
|
| 34 |
const icons = { |
| 35 |
success: CheckCircle, |
| 36 |
error: XCircle, |
| 37 |
warning: AlertCircle, |
| 38 |
info: Info, |
| 39 |
}; |
| 40 |
|
| 41 |
const Icon = icons[variant]; |
| 42 |
|
| 43 |
return ( |
| 44 |
<div |
| 45 |
className={`rounded-md border p-4 ${variantClasses[variant]} ${className}`} |
| 46 |
> |
| 47 |
<div className="flex items-start gap-3"> |
| 48 |
<Icon className="w-5 h-5 flex-shrink-0 mt-0.5" /> |
| 49 |
<div className="flex-1"> |
| 50 |
{title && <h4 className="font-medium mb-1">{title}</h4>} |
| 51 |
<div className="text-sm">{children}</div> |
| 52 |
</div> |
| 53 |
{onClose && ( |
| 54 |
<button |
| 55 |
onClick={onClose} |
| 56 |
className="flex-shrink-0 text-current opacity-70 hover:opacity-100 transition-opacity" |
| 57 |
aria-label="Close" |
| 58 |
> |
| 59 |
<X className="w-4 h-4" /> |
| 60 |
</button> |
| 61 |
)} |
| 62 |
</div> |
| 63 |
</div> |
| 64 |
); |
| 65 |
}; |
| 66 |
|