deeep-sec's picture
feat: institutional campus placement eligibility & interview scheduling engine
788eab4 verified
Raw History Blame Contribute Delete
2.3 kB
import React, { useEffect } from "react";
import { X } from "lucide-react";
interface ModalProps {
isOpen: boolean;
onClose: () => void;
title: string;
children: React.ReactNode;
maxWidth?: "sm" | "md" | "lg" | "xl" | "2xl" | "4xl";
footer?: React.ReactNode;
}
export const Modal: React.FC<ModalProps> = ({
isOpen,
onClose,
title,
children,
maxWidth = "lg",
footer,
}) => {
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") {
onClose();
}
};
if (isOpen) {
window.addEventListener("keydown", handleKeyDown);
document.body.style.overflow = "hidden";
}
return () => {
window.removeEventListener("keydown", handleKeyDown);
document.body.style.overflow = "unset";
};
}, [isOpen, onClose]);
if (!isOpen) return null;
const maxWidthStyles = {
sm: "max-w-sm",
md: "max-w-md",
lg: "max-w-lg",
xl: "max-w-xl",
"2xl": "max-w-2xl",
"4xl": "max-w-4xl",
};
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-[#040810]/80 backdrop-blur-md animate-in fade-in duration-200"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
<div
className={`bg-[#0d1527] w-full ${maxWidthStyles[maxWidth]} rounded-3xl shadow-2xl border border-[#1b2b4d] overflow-hidden flex flex-col max-h-[90vh] text-slate-100`}
onClick={(e) => e.stopPropagation()}
>
<div className="flex items-center justify-between px-6 py-4 border-b border-[#1b2b4d]">
<h2 id="modal-title" className="text-lg font-bold text-white">
{title}
</h2>
<button
onClick={onClose}
className="p-1 rounded-lg text-slate-400 hover:text-white hover:bg-[#111d38] transition-colors cursor-pointer"
aria-label="Close modal"
>
<X className="w-5 h-5" />
</button>
</div>
<div className="p-6 overflow-y-auto flex-1">{children}</div>
{footer && (
<div className="px-6 py-4 bg-[#080e1c] border-t border-[#1b2b4d] flex items-center justify-end gap-3">
{footer}
</div>
)}
</div>
</div>
);
};