Trae Assistant
Initial commit
69a3dd3
import React, { useEffect, useRef } from 'react';
import { X } from 'lucide-react';
interface ModalProps {
isOpen: boolean;
onClose: () => void;
title: string;
children: React.ReactNode;
primaryAction?: {
label: string;
onClick: () => void;
danger?: boolean;
};
secondaryAction?: {
label: string;
onClick: () => void;
};
}
export default function Modal({
isOpen,
onClose,
title,
children,
primaryAction,
secondaryAction
}: ModalProps) {
const modalRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
if (isOpen) {
document.addEventListener('keydown', handleEscape);
document.body.style.overflow = 'hidden';
}
return () => {
document.removeEventListener('keydown', handleEscape);
document.body.style.overflow = 'unset';
};
}, [isOpen, onClose]);
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-[200] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm transition-opacity duration-200">
<div
ref={modalRef}
className="bg-white dark:bg-gray-900 rounded-xl shadow-2xl w-full max-w-md border border-gray-200 dark:border-gray-800 transform transition-all duration-200 scale-100"
onClick={(e) => e.stopPropagation()}
>
<div className="flex items-center justify-between p-4 border-b border-gray-100 dark:border-gray-800">
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100">{title}</h3>
<button
onClick={onClose}
className="p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
>
<X size={20} />
</button>
</div>
<div className="p-6">
{children}
</div>
<div className="flex items-center justify-end gap-3 p-4 border-t border-gray-100 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-900/50 rounded-b-xl">
{secondaryAction && (
<button
onClick={secondaryAction.onClick}
className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
>
{secondaryAction.label}
</button>
)}
{primaryAction && (
<button
onClick={primaryAction.onClick}
className={`px-4 py-2 text-sm font-medium text-white rounded-lg shadow-sm transition-colors ${
primaryAction.danger
? 'bg-red-500 hover:bg-red-600'
: 'bg-blue-600 hover:bg-blue-700'
}`}
>
{primaryAction.label}
</button>
)}
</div>
</div>
</div>
);
}