import React, { createContext, useContext, useState, useCallback, ReactNode, useEffect, useRef } from 'react'; import { X, ChevronLeft, Maximize2, Minimize2 } from 'lucide-react'; // Modal em PILHA (estilo navegação iOS): páginas deslizam da direita, com botão voltar. // Desktop abre pequeno + ícone maximizar (tela cheia). Mobile = tela cheia direto. // Cada página é um componente que carrega o PRÓPRIO mínimo (carregamento progressivo). export interface StackPage { title: string; render: () => ReactNode; } interface StackCtx { push: (p: StackPage) => void; pop: () => void; close: () => void; } const Ctx = createContext(null); export const useStackModal = (): StackCtx => { const c = useContext(Ctx); if (!c) throw new Error('useStackModal deve ser usado dentro de '); return c; }; export const StackModal: React.FC<{ isOpen: boolean; onClose: () => void; root: StackPage }> = ({ isOpen, onClose, root }) => { const [stack, setStack] = useState([root]); const [fullscreen, setFullscreen] = useState(false); const panelRef = useRef(null); // Reabriu → reinicia a pilha. (Use também key={...} no pai p/ forçar remount por entidade.) useEffect(() => { if (isOpen) setStack([root]); /* eslint-disable-line */ }, [isOpen]); // Não trancar: ESC fecha; clicar FORA do painel fecha (o overlay deixa o clique passar // pra agenda, então clicar em outro slot/evento fecha este e abre o novo). useEffect(() => { if (!isOpen) return; const onDown = (e: PointerEvent) => { if (panelRef.current && !panelRef.current.contains(e.target as Node)) onClose(); }; const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('pointerdown', onDown, true); window.addEventListener('keydown', onKey); return () => { document.removeEventListener('pointerdown', onDown, true); window.removeEventListener('keydown', onKey); }; }, [isOpen, onClose]); const push = useCallback((p: StackPage) => setStack(s => [...s, p]), []); const pop = useCallback(() => setStack(s => (s.length > 1 ? s.slice(0, -1) : s)), []); const close = useCallback(() => onClose(), [onClose]); if (!isOpen) return null; const current = stack[stack.length - 1]; const canBack = stack.length > 1; return (
{canBack ? ( ) : ( )}

{current.title}

{current.render()}
); };