import React, { useEffect, useState } from 'react'; import type { SlideLayout } from '../../types/theme.ts'; import { sanitizeSlideTemplate } from '../../utils/htmlSanitizer.ts'; import './SlidePreviewModal.css'; interface SlidePreviewModalProps { isOpen: boolean; onClose: () => void; layout: SlideLayout; content: Record; aspectRatio: string; themeName: string; } export const SlidePreviewModal: React.FC = ({ isOpen, onClose, layout, content, aspectRatio, themeName }) => { const [showHint, setShowHint] = useState(true); // Handle ESC key press useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape' && isOpen) { onClose(); } }; if (isOpen) { document.addEventListener('keydown', handleKeyDown); document.body.style.overflow = 'hidden'; // Prevent scrolling // Hide hint after 3 seconds const hintTimer = setTimeout(() => { setShowHint(false); }, 3000); return () => { document.removeEventListener('keydown', handleKeyDown); document.body.style.overflow = 'unset'; clearTimeout(hintTimer); }; } }, [isOpen, onClose]); // Reset hint when modal opens useEffect(() => { if (isOpen) { setShowHint(true); } }, [isOpen]); // Render template with actual content const renderTemplateWithContent = (layout: SlideLayout, content: Record): string => { let rendered = layout.htmlTemplate; // Replace content placeholders Object.entries(content).forEach(([slotId, value]) => { const placeholder = new RegExp(`\\{\\{${slotId}\\}\\}`, 'g'); rendered = rendered.replace(placeholder, value || ''); }); // Clean up any remaining placeholders rendered = rendered.replace(/\{\{[^}]+\}\}/g, ''); return rendered; }; if (!isOpen) return null; const handleOverlayClick = (event: React.MouseEvent) => { if (event.target === event.currentTarget) { onClose(); } }; return (
{/* ESC hint */} {showHint && (
Press ESC to exit preview
)} {/* Close button */} {/* Theme info */}
{themeName} {layout.name} {aspectRatio}
{/* Slide content */}
); };