diff --git a/apps/web/src/lib/components/ErrorModal.svelte b/apps/web/src/lib/components/ErrorModal.svelte index bbefe71..a0a2bb4 100644 --- a/apps/web/src/lib/components/ErrorModal.svelte +++ b/apps/web/src/lib/components/ErrorModal.svelte @@ -13,26 +13,25 @@ let modalPosition = $state<{ top: number; left: number } | null>(null); - // Função para calcular a posição baseada no container central da página + // Função para calcular a posição baseada no relógio sincronizado function calcularPosicaoModal() { - // Procurar pelo elemento container-central - const containerCentral = document.getElementById('container-central'); + // Procurar pelo elemento do relógio sincronizado + const relogioRef = document.getElementById('relogio-sincronizado-ref'); - if (containerCentral) { - const rect = containerCentral.getBoundingClientRect(); + if (relogioRef) { + const rect = relogioRef.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)); + // Posicionar o modal na mesma posição do relógio sincronizado + // Centralizado horizontalmente no card do relógio + const left = rect.left + (rect.width / 2); + // Posicionar abaixo do card do relógio com um pequeno espaçamento + const top = rect.bottom + 20; return { top: top, - left: containerCenterX + left: left }; } @@ -42,14 +41,22 @@ $effect(() => { if (open) { - // Aguardar um pouco para garantir que o DOM está atualizado - setTimeout(() => { - modalPosition = calcularPosicaoModal(); - }, 10); + // Usar requestAnimationFrame para garantir que o DOM está completamente renderizado + const updatePosition = () => { + requestAnimationFrame(() => { + const pos = calcularPosicaoModal(); + if (pos) { + modalPosition = pos; + } + }); + }; + + // Aguardar um pouco mais para garantir que o DOM está atualizado + setTimeout(updatePosition, 50); // Adicionar listener de scroll para atualizar posição const handleScroll = () => { - modalPosition = calcularPosicaoModal(); + updatePosition(); }; window.addEventListener('scroll', handleScroll, true); @@ -59,6 +66,9 @@ window.removeEventListener('scroll', handleScroll, true); window.removeEventListener('resize', handleScroll); }; + } else { + // Limpar posição quando o modal for fechado + modalPosition = null; } }); @@ -75,7 +85,7 @@ let top = modalPosition.top; // Ajustar se o modal sair da viewport à direita - if (left + (modalWidth / 2) > viewportWidth) { + if (left + (modalWidth / 2) > viewportWidth - 20) { left = viewportWidth - (modalWidth / 2) - 20; } // Ajustar se o modal sair da viewport à esquerda @@ -83,7 +93,7 @@ left = (modalWidth / 2) + 20; } // Ajustar se o modal sair da viewport abaixo - if (top + modalHeight > viewportHeight) { + if (top + modalHeight > viewportHeight - 20) { top = viewportHeight - modalHeight - 20; } // Ajustar se o modal sair da viewport acima @@ -91,7 +101,8 @@ top = 20; } - return `position: fixed; top: ${top}px; left: ${left}px; transform: translate(-50%, 0); max-width: ${Math.min(modalWidth, viewportWidth - 40)}px;`; + // Usar transform para centralizar horizontalmente baseado no left calculado + return `position: fixed; top: ${top}px; left: ${left}px; transform: translateX(-50%); 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%);'; diff --git a/apps/web/src/lib/components/ponto/ComprovantePonto.svelte b/apps/web/src/lib/components/ponto/ComprovantePonto.svelte index 71873d0..c93b0ed 100644 --- a/apps/web/src/lib/components/ponto/ComprovantePonto.svelte +++ b/apps/web/src/lib/components/ponto/ComprovantePonto.svelte @@ -21,26 +21,25 @@ let gerando = $state(false); let modalPosition = $state<{ top: number; left: number } | null>(null); - // Função para calcular a posição baseada no container central da página + // Função para calcular a posição baseada no relógio sincronizado function calcularPosicaoModal() { - // Procurar pelo elemento container-central - const containerCentral = document.getElementById('container-central'); + // Procurar pelo elemento do relógio sincronizado + const relogioRef = document.getElementById('relogio-sincronizado-ref'); - if (containerCentral) { - const rect = containerCentral.getBoundingClientRect(); + if (relogioRef) { + const rect = relogioRef.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)); + // Posicionar o modal na mesma posição do relógio sincronizado + // Centralizado horizontalmente no card do relógio + const left = rect.left + (rect.width / 2); + // Posicionar abaixo do card do relógio com um pequeno espaçamento + const top = rect.bottom + 20; return { top: top, - left: containerCenterX + left: left }; } @@ -49,14 +48,22 @@ } onMount(() => { - // Aguardar um pouco para garantir que o DOM está atualizado - setTimeout(() => { - modalPosition = calcularPosicaoModal(); - }, 10); + // Usar requestAnimationFrame para garantir que o DOM está completamente renderizado + const updatePosition = () => { + requestAnimationFrame(() => { + const pos = calcularPosicaoModal(); + if (pos) { + modalPosition = pos; + } + }); + }; + + // Aguardar um pouco mais para garantir que o DOM está atualizado + setTimeout(updatePosition, 50); // Adicionar listener de scroll para atualizar posição const handleScroll = () => { - modalPosition = calcularPosicaoModal(); + updatePosition(); }; window.addEventListener('scroll', handleScroll, true); @@ -81,7 +88,7 @@ let top = modalPosition.top; // Ajustar se o modal sair da viewport à direita - if (left + (modalWidth / 2) > viewportWidth) { + if (left + (modalWidth / 2) > viewportWidth - 20) { left = viewportWidth - (modalWidth / 2) - 20; } // Ajustar se o modal sair da viewport à esquerda @@ -89,7 +96,7 @@ left = (modalWidth / 2) + 20; } // Ajustar se o modal sair da viewport abaixo - if (top + modalHeight > viewportHeight) { + if (top + modalHeight > viewportHeight - 20) { top = viewportHeight - modalHeight - 20; } // Ajustar se o modal sair da viewport acima @@ -97,7 +104,8 @@ top = 20; } - return `position: fixed; top: ${top}px; left: ${left}px; transform: translate(-50%, 0); max-width: ${Math.min(modalWidth, viewportWidth - 40)}px;`; + // Usar transform para centralizar horizontalmente baseado no left calculado + return `position: fixed; top: ${top}px; left: ${left}px; transform: translateX(-50%); 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%);'; diff --git a/apps/web/src/lib/components/ponto/RegistroPonto.svelte b/apps/web/src/lib/components/ponto/RegistroPonto.svelte index d98e80c..0376321 100644 --- a/apps/web/src/lib/components/ponto/RegistroPonto.svelte +++ b/apps/web/src/lib/components/ponto/RegistroPonto.svelte @@ -855,26 +855,25 @@ // Posicionamento dos modais let modalPosition = $state<{ top: number; left: number } | null>(null); - // Função para calcular a posição baseada no container central da página + // Função para calcular a posição baseada no relógio sincronizado function calcularPosicaoModal() { - // Procurar pelo elemento container-central - const containerCentral = document.getElementById('container-central'); + // Procurar pelo elemento do relógio sincronizado + const relogioRef = document.getElementById('relogio-sincronizado-ref'); - if (containerCentral) { - const rect = containerCentral.getBoundingClientRect(); + if (relogioRef) { + const rect = relogioRef.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)); + // Posicionar o modal na mesma posição do relógio sincronizado + // Centralizado horizontalmente no card do relógio + const left = rect.left + (rect.width / 2); + // Posicionar abaixo do card do relógio com um pequeno espaçamento + const top = rect.bottom + 20; return { top: top, - left: containerCenterX + left: left }; } @@ -885,14 +884,22 @@ // Atualizar posição quando os modais forem abertos ou quando a página rolar $effect(() => { if (mostrandoWebcam || mostrandoModalConfirmacao || aguardandoProcessamento || mostrarModalErro) { - // Aguardar um pouco para garantir que o DOM está atualizado - setTimeout(() => { - modalPosition = calcularPosicaoModal(); - }, 10); + // Usar requestAnimationFrame para garantir que o DOM está completamente renderizado + const updatePosition = () => { + requestAnimationFrame(() => { + const pos = calcularPosicaoModal(); + if (pos) { + modalPosition = pos; + } + }); + }; + + // Aguardar um pouco mais para garantir que o DOM está atualizado + setTimeout(updatePosition, 50); // Adicionar listener de scroll para atualizar posição const handleScroll = () => { - modalPosition = calcularPosicaoModal(); + updatePosition(); }; window.addEventListener('scroll', handleScroll, true); @@ -902,6 +909,9 @@ window.removeEventListener('scroll', handleScroll, true); window.removeEventListener('resize', handleScroll); }; + } else { + // Limpar posição quando os modais forem fechados + modalPosition = null; } }); @@ -918,7 +928,7 @@ let top = modalPosition.top; // Ajustar se o modal sair da viewport à direita - if (left + (modalWidth / 2) > viewportWidth) { + if (left + (modalWidth / 2) > viewportWidth - 20) { left = viewportWidth - (modalWidth / 2) - 20; } // Ajustar se o modal sair da viewport à esquerda @@ -926,7 +936,7 @@ left = (modalWidth / 2) + 20; } // Ajustar se o modal sair da viewport abaixo - if (top + modalHeight > viewportHeight) { + if (top + modalHeight > viewportHeight - 20) { top = viewportHeight - modalHeight - 20; } // Ajustar se o modal sair da viewport acima @@ -934,7 +944,8 @@ top = 20; } - return `position: fixed; top: ${top}px; left: ${left}px; transform: translate(-50%, 0); max-width: ${Math.min(modalWidth, viewportWidth - 40)}px;`; + // Usar transform para centralizar horizontalmente baseado no left calculado + return `position: fixed; top: ${top}px; left: ${left}px; transform: translateX(-50%); 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%);'; @@ -1009,7 +1020,7 @@
-
+