From a3eab60fcd011a13745c3fc394c86564e973350c Mon Sep 17 00:00:00 2001 From: deyvisonwanderley Date: Sun, 23 Nov 2025 16:24:58 -0300 Subject: [PATCH] feat: enhance modal positioning and styling across components - Implemented dynamic positioning for modals in ErrorModal, ComprovantePonto, and RegistroPonto components to ensure they are centered based on the viewport and container dimensions. - Updated modal styles to improve visual consistency, including backdrop opacity adjustments and enhanced animations. - Refactored modal handling logic to include scroll and resize event listeners for better responsiveness during user interactions. --- apps/web/src/lib/components/ErrorModal.svelte | 96 +++++- .../components/ponto/ComprovantePonto.svelte | 291 ++++++++++++++---- .../lib/components/ponto/RegistroPonto.svelte | 118 ++++++- 3 files changed, 423 insertions(+), 82 deletions(-) diff --git a/apps/web/src/lib/components/ErrorModal.svelte b/apps/web/src/lib/components/ErrorModal.svelte index 8367d76..bbefe71 100644 --- a/apps/web/src/lib/components/ErrorModal.svelte +++ b/apps/web/src/lib/components/ErrorModal.svelte @@ -11,6 +11,92 @@ let { open = $bindable(false), title = 'Erro', message, details, onClose }: Props = $props(); + let modalPosition = $state<{ top: number; left: number } | null>(null); + + // Função para calcular a posição baseada no container central da página + function calcularPosicaoModal() { + // Procurar pelo elemento container-central + const containerCentral = document.getElementById('container-central'); + + if (containerCentral) { + const rect = containerCentral.getBoundingClientRect(); + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + + // Centralizar baseado na largura do container central + const containerCenterX = rect.left + (rect.width / 2); + const containerTop = rect.top; + + // Posicionar o modal centralizado verticalmente na viewport, mas respeitando o container + const top = Math.max(50, Math.min(containerTop + 100, viewportHeight / 2)); + + return { + top: top, + left: containerCenterX + }; + } + + // Se não encontrar, usar posição padrão (centro da tela) + return null; + } + + $effect(() => { + if (open) { + // Aguardar um pouco para garantir que o DOM está atualizado + setTimeout(() => { + modalPosition = calcularPosicaoModal(); + }, 10); + + // Adicionar listener de scroll para atualizar posição + const handleScroll = () => { + modalPosition = calcularPosicaoModal(); + }; + + window.addEventListener('scroll', handleScroll, true); + window.addEventListener('resize', handleScroll); + + return () => { + window.removeEventListener('scroll', handleScroll, true); + window.removeEventListener('resize', handleScroll); + }; + } + }); + + // Função para obter estilo do modal baseado na posição calculada + function getModalStyle() { + if (modalPosition) { + // Garantir que o modal não saia da viewport + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + const modalWidth = 700; // Aproximadamente max-w-2xl + const modalHeight = Math.min(viewportHeight * 0.9, 600); + + let left = modalPosition.left; + let top = modalPosition.top; + + // Ajustar se o modal sair da viewport à direita + if (left + (modalWidth / 2) > viewportWidth) { + left = viewportWidth - (modalWidth / 2) - 20; + } + // Ajustar se o modal sair da viewport à esquerda + if (left - (modalWidth / 2) < 20) { + left = (modalWidth / 2) + 20; + } + // Ajustar se o modal sair da viewport abaixo + if (top + modalHeight > viewportHeight) { + top = viewportHeight - modalHeight - 20; + } + // Ajustar se o modal sair da viewport acima + if (top < 20) { + top = 20; + } + + return `position: fixed; top: ${top}px; left: ${left}px; transform: translate(-50%, 0); max-width: ${Math.min(modalWidth, viewportWidth - 40)}px;`; + } + // Se não houver posição calculada, centralizar na tela + return 'position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);'; + } + // Verificar se details contém instruções ou apenas detalhes técnicos const temInstrucoes = $derived.by(() => { if (!details) return false; @@ -31,22 +117,22 @@ {#if open}