Merge remote-tracking branch 'origin' into feat-pedidos

This commit is contained in:
2025-12-11 10:08:12 -03:00
194 changed files with 30374 additions and 10247 deletions

View File

@@ -1,10 +1,10 @@
<script lang="ts">
import { api } from '@sgse-app/backend/convex/_generated/api';
import { useQuery } from 'convex-svelte';
import { Mail, UserPlus } from 'lucide-svelte';
import { onMount } from 'svelte';
import { afterNavigate, goto, replaceState } from '$app/navigation';
import { resolve } from '$app/paths';
import { UserPlus, Mail, Clock, Award, TrendingUp, Zap, Users, Database } from 'lucide-svelte';
import ProtectedRoute from '$lib/components/ProtectedRoute.svelte';
import { loginModalStore } from '$lib/stores/loginModal.svelte';
@@ -46,10 +46,7 @@
} catch {
// Se ainda não estiver pronto, usar goto com replaceState
// eslint-disable-next-line @typescript-eslint/no-explicit-any
goto(resolve(to.url.pathname as any), {
replaceState: true,
noScroll: true
});
goto(resolve(to.url.pathname as any), { replaceState: true, noScroll: true });
}
// Auto-fechar após 10 segundos
@@ -250,20 +247,7 @@
<p class="text-base-content/60 mt-1 text-xs">de 5 total</p>
</div>
<div class="bg-warning/20 rounded-full p-4">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-warning h-8 w-8"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<Clock class="text-warning h-8 w-8" strokeWidth={2} />
</div>
</div>
</div>
@@ -285,20 +269,7 @@
</p>
</div>
<div class="bg-success/20 rounded-full p-4">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-success h-8 w-8"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"
/>
</svg>
<Award class="text-success h-8 w-8" strokeWidth={2} />
</div>
</div>
</div>
@@ -318,20 +289,7 @@
</p>
</div>
<div class="bg-secondary/20 rounded-full p-4">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-secondary h-8 w-8"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"
/>
</svg>
<TrendingUp class="text-secondary h-8 w-8" strokeWidth={2} />
</div>
</div>
</div>
@@ -340,39 +298,29 @@
</div>
<!-- Monitoramento em Tempo Real -->
{#if statusSistemaQuery.data}
{#if statusSistemaQuery?.data}
{@const status = statusSistemaQuery.data}
{@const atividade = atividadeBDQuery.data || {
{@const atividade = atividadeBDQuery?.data || {
historico: Array.from({ length: 30 }, () => ({ entradas: 0, saidas: 0 }))
}}
{@const distribuicao = distribuicaoQuery.data || {
{@const distribuicao = distribuicaoQuery?.data || {
queries: 0,
mutations: 0,
leituras: 0,
escritas: 0
}}
{@const maxAtividade = Math.max(
1,
...atividade.historico.map((p) => Math.max(p.entradas, p.saidas))
)}
{@const maxAtividade =
atividade.historico && atividade.historico.length > 0
? Math.max(
1,
...atividade.historico.map((p) => Math.max(p.entradas || 0, p.saidas || 0))
)
: 1}
<div class="mb-6">
<div class="mb-4 flex items-center gap-3">
<div class="bg-error/10 animate-pulse rounded-lg p-2">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-error h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 10V3L4 14h7v7l9-11h-7z"
/>
</svg>
<Zap class="text-error h-6 w-6" strokeWidth={2} />
</div>
<div>
<h2 class="text-base-content text-2xl font-bold">Monitoramento em Tempo Real</h2>
@@ -409,20 +357,7 @@
<p class="text-base-content/60 mt-1 text-xs">sessões ativas</p>
</div>
<div class="bg-primary/20 rounded-full p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-primary h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
/>
</svg>
<Users class="text-primary h-6 w-6" strokeWidth={2} />
</div>
</div>
</div>
@@ -444,20 +379,7 @@
<p class="text-base-content/60 mt-1 text-xs">no banco de dados</p>
</div>
<div class="bg-success/20 rounded-full p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-success h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"
/>
</svg>
<Database class="text-success h-6 w-6" strokeWidth={2} />
</div>
</div>
</div>
@@ -574,27 +496,29 @@
<!-- Barras de atividade -->
<div class="flex h-full items-end justify-around gap-1">
{#each atividade.historico as ponto, idx (idx)}
{#each atividade.historico || [] as ponto, idx (idx)}
{@const entradas = ponto?.entradas || 0}
{@const saidas = ponto?.saidas || 0}
<div class="group relative flex h-full flex-1 items-end gap-0.5">
<!-- Entradas (verde) -->
<div
class="from-success to-success/70 flex-1 rounded-t bg-linear-to-t transition-all duration-300 hover:scale-110"
style="height: {(ponto.entradas / maxAtividade) * 100}%; min-height: 2px;"
title="Entradas: {ponto.entradas}"
style="height: {(entradas / maxAtividade) * 100}%; min-height: 2px;"
title="Entradas: {entradas}"
></div>
<!-- Saídas (vermelho) -->
<div
class="from-error to-error/70 flex-1 rounded-t bg-linear-to-t transition-all duration-300 hover:scale-110"
style="height: {(ponto.saidas / maxAtividade) * 100}%; min-height: 2px;"
title="Saídas: {ponto.saidas}"
style="height: {(saidas / maxAtividade) * 100}%; min-height: 2px;"
title="Saídas: {saidas}"
></div>
<!-- Tooltip no hover -->
<div
class="bg-base-300 text-base-content absolute bottom-full left-1/2 z-10 mb-2 -translate-x-1/2 rounded px-2 py-1 text-xs whitespace-nowrap opacity-0 shadow-lg transition-opacity group-hover:opacity-100"
>
<div>{ponto.entradas} entradas</div>
<div>{ponto.saidas} saídas</div>
<div>{entradas} entradas</div>
<div>{saidas} saídas</div>
</div>
</div>
{/each}
@@ -639,23 +563,29 @@
<div>
<div class="mb-1 flex justify-between text-sm">
<span>Queries (Leituras)</span>
<span class="text-primary font-bold">{distribuicao.queries}</span>
<span class="text-primary font-bold">{distribuicao?.queries ?? 0}</span>
</div>
<progress
class="progress progress-primary w-full"
value={distribuicao.queries}
max={Math.max(distribuicao.queries + distribuicao.mutations, 1)}
value={distribuicao?.queries ?? 0}
max={Math.max(
(distribuicao?.queries ?? 0) + (distribuicao?.mutations ?? 0),
1
)}
></progress>
</div>
<div>
<div class="mb-1 flex justify-between text-sm">
<span>Mutations (Escritas)</span>
<span class="text-secondary font-bold">{distribuicao.mutations}</span>
<span class="text-secondary font-bold">{distribuicao?.mutations ?? 0}</span>
</div>
<progress
class="progress progress-secondary w-full"
value={distribuicao.mutations}
max={Math.max(distribuicao.queries + distribuicao.mutations, 1)}
value={distribuicao?.mutations ?? 0}
max={Math.max(
(distribuicao?.queries ?? 0) + (distribuicao?.mutations ?? 0),
1
)}
></progress>
</div>
</div>
@@ -669,23 +599,29 @@
<div>
<div class="mb-1 flex justify-between text-sm">
<span>Leituras</span>
<span class="text-info font-bold">{distribuicao.leituras}</span>
<span class="text-info font-bold">{distribuicao?.leituras ?? 0}</span>
</div>
<progress
class="progress progress-info w-full"
value={distribuicao.leituras}
max={Math.max(distribuicao.leituras + distribuicao.escritas, 1)}
value={distribuicao?.leituras ?? 0}
max={Math.max(
(distribuicao?.leituras ?? 0) + (distribuicao?.escritas ?? 0),
1
)}
></progress>
</div>
<div>
<div class="mb-1 flex justify-between text-sm">
<span>Escritas</span>
<span class="text-warning font-bold">{distribuicao.escritas}</span>
<span class="text-warning font-bold">{distribuicao?.escritas ?? 0}</span>
</div>
<progress
class="progress progress-warning w-full"
value={distribuicao.escritas}
max={Math.max(distribuicao.leituras + distribuicao.escritas, 1)}
value={distribuicao?.escritas ?? 0}
max={Math.max(
(distribuicao?.leituras ?? 0) + (distribuicao?.escritas ?? 0),
1
)}
></progress>
</div>
</div>