Spaces:
Sleeping
Sleeping
| 'use client'; | |
| import { useEffect, useRef } from 'react'; | |
| interface InfoModalProps { | |
| open: boolean; | |
| title: string; | |
| content: string | React.ReactNode; | |
| onClose: () => void; | |
| } | |
| export default function InfoModal({ open, title, content, onClose: handleClose }: InfoModalProps) { | |
| const modalRef = useRef<HTMLDivElement>(null); | |
| useEffect(() => { | |
| const handleEscKey = (event: KeyboardEvent) => { | |
| if (event.key === 'Escape' && open) { | |
| handleClose(); | |
| } | |
| }; | |
| document.addEventListener('keydown', handleEscKey); | |
| return () => { | |
| document.removeEventListener('keydown', handleEscKey); | |
| }; | |
| }, [open, handleClose]); | |
| const handleBackdropClick = (e: React.MouseEvent) => { | |
| if (modalRef.current && !modalRef.current.contains(e.target as Node)) { | |
| handleClose(); | |
| } | |
| }; | |
| if (!open) return null; | |
| return ( | |
| <div | |
| className="fixed inset-0 bg-black/30 backdrop-blur-[2px] flex items-center justify-center p-4 z-50" | |
| onClick={handleBackdropClick} | |
| > | |
| <div | |
| ref={modalRef} | |
| className="bg-white rounded-xl p-6 max-w-lg w-full shadow-lg border border-gray-100" | |
| > | |
| <div className="flex justify-between items-start mb-4"> | |
| <h3 className="text-xl font-semibold tracking-tight text-gray-900">{title}</h3> | |
| <button | |
| className="p-1.5 rounded-full text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors" | |
| onClick={handleClose} | |
| > | |
| <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path | |
| d="M6 18L18 6M6 6l12 12" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| strokeWidth="2" | |
| /> | |
| </svg> | |
| </button> | |
| </div> | |
| <div className="prose prose-gray prose-sm max-w-none"> | |
| {typeof content === 'string' ? ( | |
| <p className="text-gray-600 leading-relaxed">{content}</p> | |
| ) : ( | |
| content | |
| )} | |
| </div> | |
| <div className="mt-6 flex justify-end"> | |
| <button | |
| className="px-4 py-2 text-sm font-medium bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors" | |
| onClick={handleClose} | |
| > | |
| Got it | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |