616 lines
24 KiB
Svelte
616 lines
24 KiB
Svelte
<script lang="ts">
|
|
import { page } from "$app/state";
|
|
import { goto } from "$app/navigation";
|
|
import logo from "$lib/assets/logo_governo_PE.png";
|
|
import type { Snippet } from "svelte";
|
|
import { authStore } from "$lib/stores/auth.svelte";
|
|
import { loginModalStore } from "$lib/stores/loginModal.svelte";
|
|
import { useConvexClient } from "convex-svelte";
|
|
import { api } from "@sgse-app/backend/convex/_generated/api";
|
|
import NotificationBell from "$lib/components/chat/NotificationBell.svelte";
|
|
import ChatWidget from "$lib/components/chat/ChatWidget.svelte";
|
|
import PresenceManager from "$lib/components/chat/PresenceManager.svelte";
|
|
|
|
let { children }: { children: Snippet } = $props();
|
|
|
|
const convex = useConvexClient();
|
|
|
|
// Caminho atual da página
|
|
const currentPath = $derived(page.url.pathname);
|
|
|
|
// Função para gerar classes do menu ativo
|
|
function getMenuClasses(isActive: boolean) {
|
|
const baseClasses = "group font-semibold flex items-center justify-center gap-2 text-center p-3.5 rounded-xl border-2 transition-all duration-300 shadow-md hover:shadow-lg hover:scale-105";
|
|
|
|
if (isActive) {
|
|
return `${baseClasses} border-primary bg-primary text-white shadow-lg scale-105`;
|
|
}
|
|
|
|
return `${baseClasses} border-primary/30 bg-gradient-to-br from-base-100 to-base-200 text-base-content hover:from-primary hover:to-primary/80 hover:text-white`;
|
|
}
|
|
|
|
// Função para gerar classes do botão "Solicitar Acesso"
|
|
function getSolicitarClasses(isActive: boolean) {
|
|
const baseClasses = "group font-semibold flex items-center justify-center gap-2 text-center p-3.5 rounded-xl border-2 transition-all duration-300 shadow-md hover:shadow-lg hover:scale-105";
|
|
|
|
if (isActive) {
|
|
return `${baseClasses} border-success bg-success text-white shadow-lg scale-105`;
|
|
}
|
|
|
|
return `${baseClasses} border-success/30 bg-gradient-to-br from-success/10 to-success/20 text-base-content hover:from-success hover:to-success/80 hover:text-white`;
|
|
}
|
|
|
|
const setores = [
|
|
{ nome: "Recursos Humanos", link: "/recursos-humanos" },
|
|
{ nome: "Financeiro", link: "/financeiro" },
|
|
{ nome: "Controladoria", link: "/controladoria" },
|
|
{ nome: "Licitações", link: "/licitacoes" },
|
|
{ nome: "Compras", link: "/compras" },
|
|
{ nome: "Jurídico", link: "/juridico" },
|
|
{ nome: "Comunicação", link: "/comunicacao" },
|
|
{ nome: "Programas Esportivos", link: "/programas-esportivos" },
|
|
{ nome: "Secretaria Executiva", link: "/secretaria-executiva" },
|
|
{
|
|
nome: "Secretaria de Gestão de Pessoas",
|
|
link: "/gestao-pessoas",
|
|
},
|
|
{ nome: "Tecnologia da Informação", link: "/ti" },
|
|
];
|
|
|
|
let showAboutModal = $state(false);
|
|
let matricula = $state("");
|
|
let senha = $state("");
|
|
let erroLogin = $state("");
|
|
let carregandoLogin = $state(false);
|
|
|
|
// Sincronizar com o store global
|
|
$effect(() => {
|
|
if (loginModalStore.showModal && !matricula && !senha) {
|
|
matricula = "";
|
|
senha = "";
|
|
erroLogin = "";
|
|
}
|
|
});
|
|
|
|
function openLoginModal() {
|
|
loginModalStore.open();
|
|
matricula = "";
|
|
senha = "";
|
|
erroLogin = "";
|
|
}
|
|
|
|
function closeLoginModal() {
|
|
loginModalStore.close();
|
|
matricula = "";
|
|
senha = "";
|
|
erroLogin = "";
|
|
}
|
|
|
|
function openAboutModal() {
|
|
showAboutModal = true;
|
|
}
|
|
|
|
function closeAboutModal() {
|
|
showAboutModal = false;
|
|
}
|
|
|
|
async function handleLogin(e: Event) {
|
|
e.preventDefault();
|
|
erroLogin = "";
|
|
carregandoLogin = true;
|
|
|
|
try {
|
|
const resultado = await convex.mutation(api.autenticacao.login, {
|
|
matriculaOuEmail: matricula.trim(),
|
|
senha: senha,
|
|
});
|
|
|
|
if (resultado.sucesso) {
|
|
authStore.login(resultado.usuario, resultado.token);
|
|
closeLoginModal();
|
|
|
|
// Redirecionar baseado no role
|
|
if (resultado.usuario.role.nome === "ti" || resultado.usuario.role.nivel === 0) {
|
|
goto("/ti/painel-administrativo");
|
|
} else if (resultado.usuario.role.nome === "rh") {
|
|
goto("/recursos-humanos");
|
|
} else {
|
|
goto("/");
|
|
}
|
|
} else {
|
|
erroLogin = resultado.erro || "Erro ao fazer login";
|
|
}
|
|
} catch (error) {
|
|
console.error("Erro ao fazer login:", error);
|
|
erroLogin = "Erro ao conectar com o servidor. Tente novamente.";
|
|
} finally {
|
|
carregandoLogin = false;
|
|
}
|
|
}
|
|
|
|
async function handleLogout() {
|
|
if (authStore.token) {
|
|
try {
|
|
await convex.mutation(api.autenticacao.logout, {
|
|
token: authStore.token,
|
|
});
|
|
} catch (error) {
|
|
console.error("Erro ao fazer logout:", error);
|
|
}
|
|
}
|
|
authStore.logout();
|
|
goto("/");
|
|
}
|
|
</script>
|
|
|
|
<!-- Header Fixo acima de tudo -->
|
|
<div class="navbar bg-gradient-to-r from-primary/30 via-primary/20 to-primary/30 backdrop-blur-sm shadow-lg border-b border-primary/10 px-6 lg:px-8 fixed top-0 left-0 right-0 z-50 min-h-24">
|
|
<div class="flex-none lg:hidden">
|
|
<label
|
|
for="my-drawer-3"
|
|
class="relative flex items-center justify-center w-14 h-14 rounded-2xl overflow-hidden cursor-pointer group transition-all duration-300 hover:scale-105"
|
|
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); box-shadow: 0 8px 24px -4px rgba(102, 126, 234, 0.4);"
|
|
aria-label="Abrir menu"
|
|
>
|
|
<!-- Efeito de brilho no hover -->
|
|
<div class="absolute inset-0 bg-gradient-to-br from-white/0 to-white/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
|
|
<!-- Ícone de menu hambúrguer -->
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
class="w-7 h-7 text-white relative z-10 group-hover:scale-110 transition-transform duration-300"
|
|
style="filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3));"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2.5"
|
|
d="M4 6h16M4 12h16M4 18h16"
|
|
stroke="currentColor"
|
|
></path>
|
|
</svg>
|
|
</label>
|
|
</div>
|
|
<div class="flex-1 flex items-center gap-4 lg:gap-6">
|
|
<!-- Logo MODERNO do Governo -->
|
|
<div class="avatar">
|
|
<div
|
|
class="w-16 lg:w-20 rounded-2xl shadow-xl p-2 relative overflow-hidden group transition-all duration-300 hover:scale-105"
|
|
style="background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); border: 2px solid rgba(102, 126, 234, 0.1);"
|
|
>
|
|
<!-- Efeito de brilho no hover -->
|
|
<div class="absolute inset-0 bg-gradient-to-br from-primary/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
|
|
<!-- Logo -->
|
|
<img
|
|
src={logo}
|
|
alt="Logo do Governo de PE"
|
|
class="w-full h-full object-contain relative z-10 transition-transform duration-300 group-hover:scale-105"
|
|
style="filter: drop-shadow(0 2px 4px rgba(0,0,0,0.08));"
|
|
/>
|
|
|
|
<!-- Brilho sutil no canto -->
|
|
<div class="absolute top-0 right-0 w-8 h-8 bg-gradient-to-br from-white/40 to-transparent rounded-bl-full opacity-70"></div>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col">
|
|
<h1 class="text-xl lg:text-3xl font-bold text-primary tracking-tight">SGSE</h1>
|
|
<p class="text-xs lg:text-base text-base-content/80 hidden sm:block font-medium leading-tight">
|
|
Sistema de Gerenciamento da<br class="lg:hidden" /> Secretaria de Esportes
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex-none flex items-center gap-4">
|
|
{#if authStore.autenticado}
|
|
<!-- Sino de notificações -->
|
|
<NotificationBell />
|
|
|
|
<div class="hidden lg:flex flex-col items-end">
|
|
<span class="text-sm font-semibold text-primary">{authStore.usuario?.nome}</span>
|
|
<span class="text-xs text-base-content/60">{authStore.usuario?.role.nome}</span>
|
|
</div>
|
|
<div class="dropdown dropdown-end">
|
|
<!-- Botão de Perfil ULTRA MODERNO -->
|
|
<button
|
|
type="button"
|
|
tabindex="0"
|
|
class="relative flex items-center justify-center w-14 h-14 rounded-2xl overflow-hidden group transition-all duration-300 hover:scale-105"
|
|
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); box-shadow: 0 8px 24px -4px rgba(102, 126, 234, 0.4);"
|
|
aria-label="Menu do usuário"
|
|
>
|
|
<!-- Efeito de brilho no hover -->
|
|
<div class="absolute inset-0 bg-gradient-to-br from-white/0 to-white/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
|
|
<!-- Anel de pulso sutil -->
|
|
<div class="absolute inset-0 rounded-2xl" style="animation: pulse-ring-subtle 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;"></div>
|
|
|
|
<!-- Ícone de usuário moderno -->
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 24 24"
|
|
fill="currentColor"
|
|
class="w-7 h-7 text-white relative z-10 group-hover:scale-110 transition-transform duration-300"
|
|
style="filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3));"
|
|
>
|
|
<path fill-rule="evenodd" d="M18.685 19.097A9.723 9.723 0 0021.75 12c0-5.385-4.365-9.75-9.75-9.75S2.25 6.615 2.25 12a9.723 9.723 0 003.065 7.097A9.716 9.716 0 0012 21.75a9.716 9.716 0 006.685-2.653zm-12.54-1.285A7.486 7.486 0 0112 15a7.486 7.486 0 015.855 2.812A8.224 8.224 0 0112 20.25a8.224 8.224 0 01-5.855-2.438zM15.75 9a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" clip-rule="evenodd" />
|
|
</svg>
|
|
|
|
<!-- Badge de status online -->
|
|
<div class="absolute top-1 right-1 w-3 h-3 bg-success rounded-full border-2 border-white shadow-lg" style="animation: pulse-dot 2s ease-in-out infinite;"></div>
|
|
</button>
|
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow-xl bg-base-100 rounded-box w-52 mt-4 border border-primary/20">
|
|
<li class="menu-title">
|
|
<span class="text-primary font-bold">{authStore.usuario?.nome}</span>
|
|
</li>
|
|
<li><a href="/perfil">Meu Perfil</a></li>
|
|
<li><a href="/alterar-senha">Alterar Senha</a></li>
|
|
<div class="divider my-0"></div>
|
|
<li><button type="button" onclick={handleLogout} class="text-error">Sair</button></li>
|
|
</ul>
|
|
</div>
|
|
{:else}
|
|
<button
|
|
type="button"
|
|
class="btn btn-lg shadow-2xl hover:shadow-primary/30 transition-all duration-500 hover:scale-110 group relative overflow-hidden border-0 bg-gradient-to-br from-primary via-primary to-primary/80 hover:from-primary/90 hover:via-primary/80 hover:to-primary/70"
|
|
style="width: 4rem; height: 4rem; border-radius: 9999px;"
|
|
onclick={() => openLoginModal()}
|
|
aria-label="Login"
|
|
>
|
|
<!-- Efeito de brilho animado -->
|
|
<div class="absolute inset-0 bg-gradient-to-r from-transparent via-white/30 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000"></div>
|
|
|
|
<!-- Anel pulsante de fundo -->
|
|
<div class="absolute inset-0 rounded-full bg-white/10 group-hover:animate-ping"></div>
|
|
|
|
<!-- Ícone de login premium -->
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-8 w-8 relative z-10 text-white group-hover:scale-110 transition-all duration-500"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
stroke-width="2.5"
|
|
style="filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3));"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer lg:drawer-open" style="margin-top: 96px;">
|
|
<input id="my-drawer-3" type="checkbox" class="drawer-toggle" />
|
|
<div class="drawer-content flex flex-col lg:ml-72" style="min-height: calc(100vh - 96px);">
|
|
<!-- Page content -->
|
|
<div class="flex-1 overflow-y-auto">
|
|
{@render children?.()}
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<footer class="footer footer-center bg-gradient-to-r from-primary/30 via-primary/20 to-primary/30 backdrop-blur-sm text-base-content p-6 border-t-2 border-primary/20 shadow-inner mt-auto">
|
|
<div class="grid grid-flow-col gap-6 text-sm font-medium">
|
|
<button type="button" class="link link-hover hover:text-primary transition-colors" onclick={() => openAboutModal()}>Sobre</button>
|
|
<span class="text-base-content/30">•</span>
|
|
<a href="/" class="link link-hover hover:text-primary transition-colors">Contato</a>
|
|
<span class="text-base-content/30">•</span>
|
|
<a href="/" class="link link-hover hover:text-primary transition-colors">Suporte</a>
|
|
<span class="text-base-content/30">•</span>
|
|
<a href="/" class="link link-hover hover:text-primary transition-colors">Privacidade</a>
|
|
</div>
|
|
<div class="flex items-center gap-3 mt-2">
|
|
<div class="avatar">
|
|
<div class="w-10 rounded-lg bg-white p-1.5 shadow-md">
|
|
<img src={logo} alt="Logo" class="w-full h-full object-contain" />
|
|
</div>
|
|
</div>
|
|
<div class="text-left">
|
|
<p class="text-xs font-bold text-primary">Governo do Estado de Pernambuco</p>
|
|
<p class="text-xs text-base-content/70">Secretaria de Esportes</p>
|
|
</div>
|
|
</div>
|
|
<p class="text-xs text-base-content/60 mt-2">© {new Date().getFullYear()} - Todos os direitos reservados</p>
|
|
</footer>
|
|
</div>
|
|
<div class="drawer-side z-40 fixed" style="margin-top: 96px;">
|
|
<label for="my-drawer-3" aria-label="close sidebar" class="drawer-overlay"
|
|
></label>
|
|
<div class="menu bg-gradient-to-b from-primary/25 to-primary/15 backdrop-blur-sm w-72 p-4 flex flex-col gap-2 h-[calc(100vh-96px)] overflow-y-auto border-r-2 border-primary/20 shadow-xl">
|
|
<!-- Sidebar menu items -->
|
|
<ul class="flex flex-col gap-2">
|
|
<li class="rounded-xl">
|
|
<a
|
|
href="/"
|
|
class={getMenuClasses(currentPath === "/")}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5 group-hover:scale-110 transition-transform"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
|
|
/>
|
|
</svg>
|
|
<span>Dashboard</span>
|
|
</a>
|
|
</li>
|
|
{#each setores as s}
|
|
{@const isActive = currentPath.startsWith(s.link)}
|
|
<li class="rounded-xl">
|
|
<a
|
|
href={s.link}
|
|
aria-current={isActive ? "page" : undefined}
|
|
class={getMenuClasses(isActive)}
|
|
>
|
|
<span>{s.nome}</span>
|
|
</a>
|
|
</li>
|
|
{/each}
|
|
<li class="rounded-xl mt-auto">
|
|
<a
|
|
href="/solicitar-acesso"
|
|
class={getSolicitarClasses(currentPath === "/solicitar-acesso")}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"
|
|
/>
|
|
</svg>
|
|
<span>Solicitar acesso</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal de Login -->
|
|
{#if loginModalStore.showModal}
|
|
<dialog class="modal modal-open">
|
|
<div class="modal-box relative overflow-hidden bg-base-100 max-w-md">
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
|
|
onclick={closeLoginModal}
|
|
>
|
|
✕
|
|
</button>
|
|
|
|
<div class="p-4">
|
|
<div class="text-center mb-6">
|
|
<div class="avatar mb-4">
|
|
<div class="w-20 rounded-lg bg-primary/10 p-3">
|
|
<img src={logo} alt="Logo" class="w-full h-full object-contain" />
|
|
</div>
|
|
</div>
|
|
<h3 class="font-bold text-3xl text-primary">Login</h3>
|
|
<p class="text-sm text-base-content/60 mt-2">Acesse o sistema com suas credenciais</p>
|
|
</div>
|
|
|
|
{#if erroLogin}
|
|
<div class="alert alert-error mb-4">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<span>{erroLogin}</span>
|
|
</div>
|
|
{/if}
|
|
|
|
<form class="space-y-4" onsubmit={handleLogin}>
|
|
<div class="form-control">
|
|
<label class="label" for="login-matricula">
|
|
<span class="label-text font-semibold">Matrícula ou E-mail</span>
|
|
</label>
|
|
<input
|
|
id="login-matricula"
|
|
type="text"
|
|
placeholder="Digite sua matrícula ou e-mail"
|
|
class="input input-bordered input-primary w-full"
|
|
bind:value={matricula}
|
|
required
|
|
disabled={carregandoLogin}
|
|
/>
|
|
</div>
|
|
<div class="form-control">
|
|
<label class="label" for="login-password">
|
|
<span class="label-text font-semibold">Senha</span>
|
|
</label>
|
|
<input
|
|
id="login-password"
|
|
type="password"
|
|
placeholder="Digite sua senha"
|
|
class="input input-bordered input-primary w-full"
|
|
bind:value={senha}
|
|
required
|
|
disabled={carregandoLogin}
|
|
/>
|
|
</div>
|
|
<div class="form-control mt-6">
|
|
<button
|
|
type="submit"
|
|
class="btn btn-primary w-full"
|
|
disabled={carregandoLogin}
|
|
>
|
|
{#if carregandoLogin}
|
|
<span class="loading loading-spinner loading-sm"></span>
|
|
Entrando...
|
|
{:else}
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
|
|
</svg>
|
|
Entrar
|
|
{/if}
|
|
</button>
|
|
</div>
|
|
<div class="text-center mt-4 space-y-2">
|
|
<a href="/solicitar-acesso" class="link link-primary text-sm block" onclick={closeLoginModal}>
|
|
Não tem acesso? Solicite aqui
|
|
</a>
|
|
<a href="/esqueci-senha" class="link link-secondary text-sm block" onclick={closeLoginModal}>
|
|
Esqueceu sua senha?
|
|
</a>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="divider text-xs text-base-content/40">Credenciais de teste</div>
|
|
<div class="bg-base-200 p-3 rounded-lg text-xs">
|
|
<p class="font-semibold mb-1">Admin:</p>
|
|
<p>Matrícula: <code class="bg-base-300 px-2 py-1 rounded">0000</code></p>
|
|
<p>Senha: <code class="bg-base-300 px-2 py-1 rounded">Admin@123</code></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
<form method="dialog" class="modal-backdrop" onclick={closeLoginModal}>
|
|
<button type="button">close</button>
|
|
</form>
|
|
</dialog>
|
|
{/if}
|
|
|
|
<!-- Modal Sobre -->
|
|
{#if showAboutModal}
|
|
<dialog class="modal modal-open">
|
|
<div class="modal-box max-w-2xl relative overflow-hidden bg-gradient-to-br from-base-100 to-base-200">
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
|
|
onclick={closeAboutModal}
|
|
>
|
|
✕
|
|
</button>
|
|
|
|
<div class="text-center space-y-6 py-4">
|
|
<!-- Logo e Título -->
|
|
<div class="flex flex-col items-center gap-4">
|
|
<div class="avatar">
|
|
<div class="w-24 rounded-xl bg-white p-3 shadow-lg">
|
|
<img src={logo} alt="Logo SGSE" class="w-full h-full object-contain" />
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-3xl font-bold text-primary mb-2">SGSE</h3>
|
|
<p class="text-lg font-semibold text-base-content/80">
|
|
Sistema de Gerenciamento da<br />Secretaria de Esportes
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Divider -->
|
|
<div class="divider"></div>
|
|
|
|
<!-- Informações de Versão -->
|
|
<div class="bg-primary/10 rounded-xl p-6 space-y-3">
|
|
<div class="flex items-center justify-center gap-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
|
|
</svg>
|
|
<p class="text-sm font-medium text-base-content/70">Versão</p>
|
|
</div>
|
|
<p class="text-2xl font-bold text-primary">1.0 26_2025</p>
|
|
<div class="badge badge-warning badge-lg gap-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
|
</svg>
|
|
Em Desenvolvimento
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Desenvolvido por -->
|
|
<div class="space-y-2">
|
|
<p class="text-sm font-medium text-base-content/60">Desenvolvido por</p>
|
|
<p class="text-lg font-bold text-primary">
|
|
Secretaria de Esportes de Pernambuco
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Divider -->
|
|
<div class="divider"></div>
|
|
|
|
<!-- Informações Adicionais -->
|
|
<div class="grid grid-cols-2 gap-4 text-sm">
|
|
<div class="bg-base-200 rounded-lg p-3">
|
|
<p class="font-semibold text-primary">Governo</p>
|
|
<p class="text-xs text-base-content/70">Estado de Pernambuco</p>
|
|
</div>
|
|
<div class="bg-base-200 rounded-lg p-3">
|
|
<p class="font-semibold text-primary">Ano</p>
|
|
<p class="text-xs text-base-content/70">2025</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Botão OK -->
|
|
<div class="pt-4">
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary btn-lg w-full max-w-xs mx-auto shadow-lg hover:shadow-xl transition-all duration-300"
|
|
onclick={closeAboutModal}
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
</svg>
|
|
OK
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-backdrop" onclick={closeAboutModal} role="button" tabindex="0" onkeydown={(e) => e.key === 'Escape' && closeAboutModal()}>
|
|
</div>
|
|
</dialog>
|
|
{/if}
|
|
|
|
<!-- Componentes de Chat (apenas se autenticado) -->
|
|
{#if authStore.autenticado}
|
|
<PresenceManager />
|
|
<ChatWidget />
|
|
{/if}
|
|
|
|
<style>
|
|
/* Animação de pulso sutil para o anel do botão de perfil */
|
|
@keyframes pulse-ring-subtle {
|
|
0%, 100% {
|
|
opacity: 0.1;
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
opacity: 0.3;
|
|
transform: scale(1.05);
|
|
}
|
|
}
|
|
|
|
/* Animação de pulso para o badge de status online */
|
|
@keyframes pulse-dot {
|
|
0%, 100% {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
opacity: 0.8;
|
|
transform: scale(1.1);
|
|
}
|
|
}
|
|
</style>
|
|
|