Sets up the basic project structure for OmniSupport AI, including: - Vite build tool configuration. - React and necessary dependencies. - TypeScript configuration. - Basic HTML and root component setup. - Initial type definitions and mock data for core entities like tickets, agents, and queues. - A README with setup instructions. - A .gitignore file for common build artifacts and development files.
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
|
|
import React, { useEffect } from 'react';
|
|
import { X, CheckCircle, AlertCircle, Info } from 'lucide-react';
|
|
|
|
export type ToastType = 'success' | 'error' | 'info';
|
|
|
|
export interface ToastMessage {
|
|
id: string;
|
|
type: ToastType;
|
|
message: string;
|
|
}
|
|
|
|
interface ToastProps {
|
|
toasts: ToastMessage[];
|
|
removeToast: (id: string) => void;
|
|
}
|
|
|
|
export const ToastContainer: React.FC<ToastProps> = ({ toasts, removeToast }) => {
|
|
return (
|
|
<div className="fixed bottom-6 right-6 z-[100] flex flex-col gap-2 pointer-events-none">
|
|
{toasts.map((toast) => (
|
|
<ToastItem key={toast.id} toast={toast} removeToast={removeToast} />
|
|
))}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const ToastItem: React.FC<{ toast: ToastMessage; removeToast: (id: string) => void }> = ({ toast, removeToast }) => {
|
|
useEffect(() => {
|
|
const timer = setTimeout(() => {
|
|
removeToast(toast.id);
|
|
}, 4000);
|
|
return () => clearTimeout(timer);
|
|
}, [toast.id, removeToast]);
|
|
|
|
const styles = {
|
|
success: 'bg-green-600 text-white',
|
|
error: 'bg-red-600 text-white',
|
|
info: 'bg-blue-600 text-white',
|
|
};
|
|
|
|
const icons = {
|
|
success: <CheckCircle className="w-5 h-5" />,
|
|
error: <AlertCircle className="w-5 h-5" />,
|
|
info: <Info className="w-5 h-5" />,
|
|
};
|
|
|
|
return (
|
|
<div className={`${styles[toast.type]} pointer-events-auto flex items-center p-4 rounded-lg shadow-lg min-w-[300px] animate-slide-up transition-all transform hover:scale-105`}>
|
|
<div className="mr-3">{icons[toast.type]}</div>
|
|
<div className="flex-1 text-sm font-medium">{toast.message}</div>
|
|
<button onClick={() => removeToast(toast.id)} className="ml-4 opacity-70 hover:opacity-100">
|
|
<X className="w-4 h-4" />
|
|
</button>
|
|
</div>
|
|
);
|
|
};
|