Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | 4x 24x 24x 10x 4x 4x 5x 1x 4x 24x 24x 10x 4x 4x 5x 1x 4x 37x 37x 18x 24x 1x | import { X, CheckCircle, XCircle, AlertTriangle, Info } from 'lucide-react';
import { useUIStore } from '@/store/ui-store';
import { Text } from '@/components/text';
const ToastIcon = ({
type,
}: {
type: 'success' | 'error' | 'warning' | 'info';
}) => {
const iconProps = { size: 20 };
switch (type) {
case 'success':
return <CheckCircle {...iconProps} className="text-green-600" />;
case 'error':
return <XCircle {...iconProps} className="text-red-600" />;
case 'warning':
return <AlertTriangle {...iconProps} className="text-yellow-600" />;
case 'info':
return <Info {...iconProps} className="text-blue-600" />;
default:
return <Info {...iconProps} className="text-gray-600" />;
}
};
const getToastStyles = (type: 'success' | 'error' | 'warning' | 'info') => {
const baseStyles =
'flex items-center gap-3 p-4 rounded-lg shadow-lg border max-w-md';
switch (type) {
case 'success':
return `${baseStyles} bg-green-50 border-green-200 text-green-800`;
case 'error':
return `${baseStyles} bg-red-50 border-red-200 text-red-800`;
case 'warning':
return `${baseStyles} bg-yellow-50 border-yellow-200 text-yellow-800`;
case 'info':
return `${baseStyles} bg-blue-50 border-blue-200 text-blue-800`;
default:
return `${baseStyles} bg-gray-50 border-gray-200 text-gray-800`;
}
};
export const ToastContainer = () => {
const { toasts, removeToast } = useUIStore();
if (toasts.length === 0) return null;
return (
<div className="fixed top-4 right-4 z-50 space-y-2">
{toasts.map(toast => (
<div
key={toast.id}
className={`${getToastStyles(toast.type)} animate-in slide-in-from-right-full duration-300`}
>
<ToastIcon type={toast.type} />
<div className="flex-1">
<Text size="sm" weight="medium">
{toast.message}
</Text>
</div>
<button
onClick={() => removeToast(toast.id)}
className="flex-shrink-0 p-1 rounded-full hover:bg-black/10 transition-colors"
aria-label="Close notification"
>
<X size={16} />
</button>
</div>
))}
</div>
);
};
|