refactor: update components to use lucide icons and improve structure

- Replaced SVG icons with lucide-svelte components across various files for consistency and improved performance.
- Refactored ActionGuard, ErrorModal, FileUpload, and other components to enhance readability and maintainability.
- Updated the dashboard pages to include new icons and improved layout for better user experience.
- Enhanced StatsCard component to support dynamic icon rendering, allowing for more flexible usage.
- Improved overall styling and structure in multiple components to align with design standards.
This commit is contained in:
2025-11-05 12:09:41 -03:00
parent 6cb7414dcc
commit c459297968
22 changed files with 2085 additions and 2423 deletions

View File

@@ -2,6 +2,7 @@
import { useQuery, useConvexClient } from "convex-svelte";
import { api } from "@sgse-app/backend/convex/_generated/api";
import StatsCard from "$lib/components/ti/StatsCard.svelte";
import { BarChart3, Users, CheckCircle2, Ban, Clock, Plus, Layers, FileText, Info } from "lucide-svelte";
const client = useConvexClient();
const usuariosQuery = useQuery(api.usuarios.listar, {});
@@ -45,9 +46,7 @@
<div class="flex items-center justify-between mb-8">
<div class="flex items-center gap-4">
<div class="p-3 bg-primary/10 rounded-xl">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
</svg>
<BarChart3 class="h-8 w-8 text-primary" strokeWidth={2} />
</div>
<div>
<h1 class="text-3xl font-bold text-base-content">Dashboard Administrativo TI</h1>
@@ -62,7 +61,7 @@
<StatsCard
title="Total de Usuários"
value={stats.total}
icon='<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" />'
Icon={Users}
color="primary"
/>
@@ -70,7 +69,7 @@
title="Usuários Ativos"
value={stats.ativos}
description="{stats.total > 0 ? ((stats.ativos / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />'
Icon={CheckCircle2}
color="success"
/>
@@ -78,7 +77,7 @@
title="Usuários Bloqueados"
value={stats.bloqueados}
description="Requerem atenção"
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />'
Icon={Ban}
color="error"
/>
@@ -86,7 +85,7 @@
title="Usuários Inativos"
value={stats.inativos}
description="Desativados"
icon='<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" />'
Icon={Clock}
color="warning"
/>
</div>
@@ -102,23 +101,17 @@
<h2 class="card-title text-2xl mb-4">Ações Rápidas</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<a href="/ti/usuarios" class="btn btn-primary">
<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="M12 4v16m8-8H4" />
</svg>
<Plus class="h-5 w-5" strokeWidth={2} />
Criar Usuário
</a>
<a href="/ti/perfis" class="btn btn-secondary">
<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="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
<Layers class="h-5 w-5" strokeWidth={2} />
Gerenciar Perfis
</a>
<a href="/ti/auditoria" class="btn btn-accent">
<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="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<FileText class="h-5 w-5" strokeWidth={2} />
Ver Logs
</a>
</div>
@@ -127,9 +120,7 @@
<!-- Informação Sistema -->
<div class="alert alert-info">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<Info class="stroke-current shrink-0 w-6 h-6" strokeWidth={2} />
<span>Sistema de Gestão da Secretaria de Esportes - Versão 2.0 com controle avançado de acesso</span>
</div>
</div>

View File

@@ -6,6 +6,7 @@
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
import { format } from "date-fns";
import { ptBR } from "date-fns/locale";
import { Users, Shield, AlertTriangle, Info, Building2 } from "lucide-svelte";
type Role = {
_id: Id<"roles">;
@@ -174,35 +175,35 @@
<StatsCard
title="Total de Perfis"
value={stats.total}
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />'
Icon={Users}
color="primary"
/>
<StatsCard
title="Nível Máximo"
value={stats.nivelMaximo}
description="Acesso total"
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />'
Icon={Shield}
color="error"
/>
<StatsCard
title="Nível Alto"
value={stats.nivelAlto}
description="Acesso elevado"
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />'
Icon={AlertTriangle}
color="warning"
/>
<StatsCard
title="Nível Médio"
value={stats.nivelMedio}
description="Acesso padrão"
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />'
Icon={Info}
color="info"
/>
<StatsCard
title="Com Setor"
value={stats.comSetor}
description="{stats.total > 0 ? ((stats.comSetor / stats.total) * 100).toFixed(0) + '% do total' : '0%'}"
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />'
Icon={Building2}
color="secondary"
/>
</div>

View File

@@ -6,6 +6,7 @@
import StatsCard from "$lib/components/ti/StatsCard.svelte";
import { format } from "date-fns";
import { ptBR } from "date-fns/locale";
import { FileText, Clock, CheckCircle2, XCircle } from "lucide-svelte";
type StatusSolicitacao = "pendente" | "aprovado" | "rejeitado";
@@ -294,7 +295,7 @@
<StatsCard
title="Total de Solicitações"
value={stats.total}
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />'
Icon={FileText}
color="primary"
/>
@@ -302,7 +303,7 @@
title="Pendentes"
value={stats.pendentes}
description="{stats.total > 0 ? ((stats.pendentes / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
icon='<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" />'
Icon={Clock}
color="warning"
/>
@@ -310,7 +311,7 @@
title="Aprovadas"
value={stats.aprovadas}
description="{stats.total > 0 ? ((stats.aprovadas / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />'
Icon={CheckCircle2}
color="success"
/>
@@ -318,7 +319,7 @@
title="Rejeitadas"
value={stats.rejeitadas}
description="{stats.total > 0 ? ((stats.rejeitadas / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
icon='<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" />'
Icon={XCircle}
color="error"
/>
</div>