diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..a6e66ff --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,23 @@ +You are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively: + +## Available MCP Tools: + +### 1. list-sections + +Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths. +When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections. + +### 2. get-documentation + +Retrieves full documentation content for specific sections. Accepts single or multiple sections. +After calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task. + +### 3. svelte-autofixer + +Analyzes Svelte code and returns issues and suggestions. +You MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned. + +### 4. playground-link + +Generates a Svelte Playground link with the provided code. +After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project. diff --git a/apps/web/src/lib/components/FileUpload.svelte b/apps/web/src/lib/components/FileUpload.svelte index 442fdbc..f02260a 100644 --- a/apps/web/src/lib/components/FileUpload.svelte +++ b/apps/web/src/lib/components/FileUpload.svelte @@ -3,7 +3,7 @@ import { ExternalLink, FileText, - File, + File as FileIcon, Upload, Trash2, Eye, @@ -16,7 +16,7 @@ value?: string; // storageId disabled?: boolean; required?: boolean; - onUpload: (file: File) => Promise; + onUpload: (file: globalThis.File) => Promise; onRemove: () => Promise; } @@ -48,38 +48,33 @@ "image/png", ]; - // Buscar URL do arquivo quando houver um storageId - $effect(() => { - if (value && !fileName) { - // Tem storageId mas não é um upload recente - loadExistingFile(value); - } - }); - - async function loadExistingFile(storageId: string) { - try { - const url = await client.storage.getUrl(storageId as any); - if (url) { - fileUrl = url; - fileName = "Documento anexado"; - // Detectar tipo pelo URL ou assumir PDF - if (url.includes(".pdf") || url.includes("application/pdf")) { - fileType = "application/pdf"; - } else { - fileType = "image/jpeg"; - previewUrl = url; // Para imagens, a URL serve como preview - } - } - } catch (err) { - console.error("Erro ao carregar arquivo existente:", err); - } - } + // Buscar URL do arquivo quando houver um storageId + $effect(() => { + if (value && !fileName) { + // Tem storageId mas não é um upload recente + loadExistingFile(value); + } + }); + async function loadExistingFile(storageId: string) { + try { + const url = await client.storage.getUrl(storageId as any); + if (url) { async function handleFileSelect(event: Event) { const target = event.target as HTMLInputElement; const file = target.files?.[0]; - - if (!file) return; + // Detectar tipo pelo URL ou assumir PDF + if (url.includes('.pdf') || url.includes('application/pdf')) { + fileType = 'application/pdf'; + } else { + fileType = 'image/jpeg'; + previewUrl = url; // Para imagens, a URL serve como preview + } + } + } catch (err) { + console.error('Erro ao carregar arquivo existente:', err); + } + } error = null; @@ -187,32 +182,22 @@ {disabled} /> - {#if value || fileName} -
- -
- {#if previewUrl} - Preview - {:else if fileType === "application/pdf" || fileName.endsWith(".pdf")} -
- -
- {:else} -
- -
- {/if} -
+ {#if value || fileName} +
+ +
+ {#if previewUrl} + Preview + {:else if fileType === 'application/pdf' || fileName.endsWith('.pdf')} +
+ +
+ {:else} +
+ +
+ {/if} +
diff --git a/apps/web/src/lib/components/Sidebar.svelte b/apps/web/src/lib/components/Sidebar.svelte index 282c574..1d1e1cc 100644 --- a/apps/web/src/lib/components/Sidebar.svelte +++ b/apps/web/src/lib/components/Sidebar.svelte @@ -366,7 +366,7 @@ {@const isActive = currentPath.startsWith(s.link)}
  • diff --git a/apps/web/src/routes/(dashboard)/+page.svelte b/apps/web/src/routes/(dashboard)/+page.svelte index 750841a..0c7070b 100644 --- a/apps/web/src/routes/(dashboard)/+page.svelte +++ b/apps/web/src/routes/(dashboard)/+page.svelte @@ -4,6 +4,7 @@ import { onMount } from "svelte"; import { page } from "$app/stores"; import { goto } from "$app/navigation"; + import { resolve } from "$app/paths"; import { UserPlus, Mail } from "lucide-svelte"; import { useAuth } from "@mmailaender/convex-better-auth-svelte/svelte"; @@ -145,7 +146,7 @@

    {alertData.message}

    {#if alertType === "access_denied"}
    - + Solicitar Acesso - + Contatar TI @@ -781,19 +782,19 @@

    Acesso Rápido

    Novo Funcionário Novo Símbolo Painel Admin diff --git a/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte b/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte index 11ca82d..a2a96d1 100644 --- a/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte +++ b/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte @@ -3,6 +3,7 @@ import { api } from '@sgse-app/backend/convex/_generated/api'; import { authStore } from '$lib/stores/auth.svelte'; import { goto } from '$app/navigation'; + import { resolve } from '$app/paths'; import { onMount } from 'svelte'; const convex = useConvexClient(); @@ -19,7 +20,7 @@ onMount(() => { if (!currentUser?.data) { - goto('/'); + goto(resolve('/')); } }); @@ -112,7 +113,7 @@ // Redirecionar após 2 segundos setTimeout(() => { - goto('/'); + goto(resolve('/')); }, 2000); } else { notice = { @@ -131,7 +132,7 @@ } function cancelar() { - goto('/'); + goto(resolve('/')); } @@ -161,7 +162,7 @@ diff --git a/apps/web/src/routes/(dashboard)/compras/+page.svelte b/apps/web/src/routes/(dashboard)/compras/+page.svelte index 619c5c0..e6497f9 100644 --- a/apps/web/src/routes/(dashboard)/compras/+page.svelte +++ b/apps/web/src/routes/(dashboard)/compras/+page.svelte @@ -1,11 +1,12 @@
    diff --git a/apps/web/src/routes/(dashboard)/comunicacao/+page.svelte b/apps/web/src/routes/(dashboard)/comunicacao/+page.svelte index 9caada5..2166880 100644 --- a/apps/web/src/routes/(dashboard)/comunicacao/+page.svelte +++ b/apps/web/src/routes/(dashboard)/comunicacao/+page.svelte @@ -1,11 +1,12 @@
    diff --git a/apps/web/src/routes/(dashboard)/controladoria/+page.svelte b/apps/web/src/routes/(dashboard)/controladoria/+page.svelte index 440da96..74917ac 100644 --- a/apps/web/src/routes/(dashboard)/controladoria/+page.svelte +++ b/apps/web/src/routes/(dashboard)/controladoria/+page.svelte @@ -1,12 +1,13 @@
    diff --git a/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte b/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte index 9d85216..989b244 100644 --- a/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte +++ b/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte @@ -2,6 +2,7 @@ import { useConvexClient } from 'convex-svelte'; import { api } from '@sgse-app/backend/convex/_generated/api'; + import { resolve } from '$app/paths'; const convex = useConvexClient(); let matricula = $state(''); @@ -88,7 +89,7 @@ @@ -204,7 +205,7 @@
    - +
    - + import { DollarSign, Building2, Plus, Calculator, TrendingUp, FileText } from "lucide-svelte"; + import { resolve } from "$app/paths";
    diff --git a/apps/web/src/routes/(dashboard)/gestao-pessoas/+page.svelte b/apps/web/src/routes/(dashboard)/gestao-pessoas/+page.svelte index acc3a39..74d5f63 100644 --- a/apps/web/src/routes/(dashboard)/gestao-pessoas/+page.svelte +++ b/apps/web/src/routes/(dashboard)/gestao-pessoas/+page.svelte @@ -1,4 +1,5 @@
    diff --git a/apps/web/src/routes/(dashboard)/licitacoes/+page.svelte b/apps/web/src/routes/(dashboard)/licitacoes/+page.svelte index 6075af1..65b2844 100644 --- a/apps/web/src/routes/(dashboard)/licitacoes/+page.svelte +++ b/apps/web/src/routes/(dashboard)/licitacoes/+page.svelte @@ -1,12 +1,13 @@
    diff --git a/apps/web/src/routes/(dashboard)/programas-esportivos/+page.svelte b/apps/web/src/routes/(dashboard)/programas-esportivos/+page.svelte index 47809cc..60340ef 100644 --- a/apps/web/src/routes/(dashboard)/programas-esportivos/+page.svelte +++ b/apps/web/src/routes/(dashboard)/programas-esportivos/+page.svelte @@ -1,11 +1,12 @@
    diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/atestados-licencas/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/atestados-licencas/+page.svelte index 028d93f..25b58ae 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/atestados-licencas/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/atestados-licencas/+page.svelte @@ -1,5 +1,6 @@ diff --git a/apps/web/src/routes/(dashboard)/ti/auditoria/+page.svelte b/apps/web/src/routes/(dashboard)/ti/auditoria/+page.svelte index 85ccaa2..85e4d2e 100644 --- a/apps/web/src/routes/(dashboard)/ti/auditoria/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/auditoria/+page.svelte @@ -2,9 +2,11 @@ import { useQuery } from "convex-svelte"; import { api } from "@sgse-app/backend/convex/_generated/api"; + + import { resolve } from "$app/paths"; let abaAtiva = $state<"atividades" | "logins">("atividades"); let limite = $state(50); - + // Queries com $derived para garantir reatividade const atividades = $derived(useQuery(api.logsAtividades.listarAtividades, { limite })); const logins = $derived(useQuery(api.logsLogin.listarTodosLogins, { limite })); @@ -55,7 +57,7 @@ @@ -124,7 +126,7 @@
    - -
    - +
    - + {#if !atividades?.data}
    @@ -279,7 +281,7 @@
    {logins.data.length} registro{logins.data.length !== 1 ? 's' : ''}
    {/if}
    - + {#if !logins?.data}
    diff --git a/apps/web/src/routes/(dashboard)/ti/painel-administrativo/+page.svelte b/apps/web/src/routes/(dashboard)/ti/painel-administrativo/+page.svelte index d005651..c8a798b 100644 --- a/apps/web/src/routes/(dashboard)/ti/painel-administrativo/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/painel-administrativo/+page.svelte @@ -4,20 +4,21 @@ import StatsCard from "$lib/components/ti/StatsCard.svelte"; import { BarChart3, Users, CheckCircle2, Ban, Clock, Plus, Layers, FileText, Info } from "lucide-svelte"; + import { resolve } from "$app/paths"; const client = useConvexClient(); const usuariosQuery = useQuery(api.usuarios.listar, {}); - + // Verificar se está carregando const carregando = $derived(usuariosQuery === undefined); - + // Extrair dados dos usuários const usuarios = $derived(usuariosQuery?.data ?? []); - + // Estatísticas derivadas const stats = $derived.by(() => { // Se ainda está carregando, retorna null para mostrar loading if (carregando) return null; - + // Se não há usuários, retorna stats zeradas (mas não null para não mostrar loading) if (!Array.isArray(usuarios) || usuarios.length === 0) { return { @@ -27,11 +28,11 @@ inativos: 0 }; } - + const ativos = usuarios.filter(u => u.ativo && !u.bloqueado).length; const bloqueados = usuarios.filter(u => u.bloqueado === true).length; const inativos = usuarios.filter(u => !u.ativo).length; - + return { total: usuarios.length, ativos, @@ -58,32 +59,32 @@ {#if stats}
    - - - - - - -

    Ações Rápidas

    - + Criar Usuário - - + + Gerenciar Perfis - - + + Ver Logs diff --git a/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte b/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte index 7d3ab7d..c3017c3 100644 --- a/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte @@ -1,4 +1,5 @@ @@ -8,7 +9,7 @@ -
    diff --git a/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte b/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte index f93c768..f2dc39f 100644 --- a/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte @@ -1,4 +1,5 @@