Ajuste chat #9
@@ -1,83 +1,71 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useQuery } from "convex-svelte";
|
import { useQuery } from "convex-svelte";
|
||||||
import { api } from "@sgse-app/backend/convex/_generated/api";
|
import { api } from "@sgse-app/backend/convex/_generated/api";
|
||||||
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
||||||
import { authStore } from "$lib/stores/auth.svelte";
|
import { authStore } from "$lib/stores/auth.svelte";
|
||||||
import { loginModalStore } from "$lib/stores/loginModal.svelte";
|
import { loginModalStore } from "$lib/stores/loginModal.svelte";
|
||||||
|
import { AlertTriangle } from "lucide-svelte";
|
||||||
interface Props {
|
|
||||||
recurso: string;
|
interface Props {
|
||||||
acao: string;
|
recurso: string;
|
||||||
children?: any;
|
acao: string;
|
||||||
}
|
children?: any;
|
||||||
|
}
|
||||||
let { recurso, acao, children }: Props = $props();
|
|
||||||
|
let { recurso, acao, children }: Props = $props();
|
||||||
let verificando = $state(true);
|
|
||||||
let permitido = $state(false);
|
let verificando = $state(true);
|
||||||
|
let permitido = $state(false);
|
||||||
const permissaoQuery = $derived(
|
|
||||||
authStore.usuario
|
const permissaoQuery = $derived(
|
||||||
? useQuery(api.permissoesAcoes.verificarAcao, {
|
authStore.usuario
|
||||||
usuarioId: authStore.usuario._id as Id<"usuarios">,
|
? useQuery(api.permissoesAcoes.verificarAcao, {
|
||||||
recurso,
|
usuarioId: authStore.usuario._id as Id<"usuarios">,
|
||||||
acao,
|
recurso,
|
||||||
})
|
acao,
|
||||||
: null
|
})
|
||||||
);
|
: null
|
||||||
|
);
|
||||||
$effect(() => {
|
|
||||||
if (!authStore.autenticado) {
|
$effect(() => {
|
||||||
verificando = false;
|
if (!authStore.autenticado) {
|
||||||
permitido = false;
|
verificando = false;
|
||||||
const currentPath = window.location.pathname;
|
permitido = false;
|
||||||
loginModalStore.open(currentPath);
|
const currentPath = window.location.pathname;
|
||||||
return;
|
loginModalStore.open(currentPath);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
if (permissaoQuery?.error) {
|
|
||||||
verificando = false;
|
if (permissaoQuery?.error) {
|
||||||
permitido = false;
|
verificando = false;
|
||||||
} else if (permissaoQuery && !permissaoQuery.isLoading) {
|
permitido = false;
|
||||||
// Backend retorna null quando permitido
|
} else if (permissaoQuery && !permissaoQuery.isLoading) {
|
||||||
verificando = false;
|
// Backend retorna null quando permitido
|
||||||
permitido = true;
|
verificando = false;
|
||||||
}
|
permitido = true;
|
||||||
});
|
}
|
||||||
</script>
|
});
|
||||||
|
</script>
|
||||||
{#if verificando}
|
|
||||||
<div class="flex items-center justify-center min-h-screen">
|
{#if verificando}
|
||||||
<div class="text-center">
|
<div class="flex items-center justify-center min-h-screen">
|
||||||
<span class="loading loading-spinner loading-lg text-primary"></span>
|
<div class="text-center">
|
||||||
<p class="mt-4 text-base-content/70">Verificando permissões...</p>
|
<span class="loading loading-spinner loading-lg text-primary"></span>
|
||||||
</div>
|
<p class="mt-4 text-base-content/70">Verificando permissões...</p>
|
||||||
</div>
|
</div>
|
||||||
{:else if permitido}
|
</div>
|
||||||
{@render children?.()}
|
{:else if permitido}
|
||||||
{:else}
|
{@render children?.()}
|
||||||
<div class="flex items-center justify-center min-h-screen">
|
{:else}
|
||||||
<div class="text-center">
|
<div class="flex items-center justify-center min-h-screen">
|
||||||
<div class="p-4 bg-error/10 rounded-full inline-block mb-4">
|
<div class="text-center">
|
||||||
<svg
|
<div class="p-4 bg-error/10 rounded-full inline-block mb-4">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<AlertTriangle class="h-16 w-16 text-error" strokeWidth={2} />
|
||||||
class="h-16 w-16 text-error"
|
</div>
|
||||||
fill="none"
|
<h2 class="text-2xl font-bold text-base-content mb-2">Acesso Negado</h2>
|
||||||
viewBox="0 0 24 24"
|
<p class="text-base-content/70">
|
||||||
stroke="currentColor"
|
Você não tem permissão para acessar esta ação.
|
||||||
>
|
</p>
|
||||||
<path
|
</div>
|
||||||
stroke-linecap="round"
|
</div>
|
||||||
stroke-linejoin="round"
|
{/if}
|
||||||
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"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<h2 class="text-2xl font-bold text-base-content mb-2">Acesso Negado</h2>
|
|
||||||
<p class="text-base-content/70">
|
|
||||||
Você não tem permissão para acessar esta ação.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { AlertCircle } from "lucide-svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -20,20 +22,7 @@
|
|||||||
<div class="modal modal-open">
|
<div class="modal modal-open">
|
||||||
<div class="modal-box">
|
<div class="modal-box">
|
||||||
<h3 class="font-bold text-lg text-error mb-4 flex items-center gap-2">
|
<h3 class="font-bold text-lg text-error mb-4 flex items-center gap-2">
|
||||||
<svg
|
<AlertCircle class="h-6 w-6" strokeWidth={2} />
|
||||||
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="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{title}
|
{title}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="py-4 text-base-content">{message}</p>
|
<p class="py-4 text-base-content">{message}</p>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useConvexClient } from "convex-svelte";
|
import { useConvexClient } from "convex-svelte";
|
||||||
|
import { ExternalLink, FileText, File, Upload, Trash2, Eye, RefreshCw } from "lucide-svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -159,9 +160,7 @@
|
|||||||
class="text-primary hover:text-primary-focus transition-colors"
|
class="text-primary hover:text-primary-focus transition-colors"
|
||||||
aria-label="Acessar link"
|
aria-label="Acessar link"
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<ExternalLink class="h-4 w-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
|
||||||
</svg>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -186,15 +185,11 @@
|
|||||||
<img src={previewUrl} alt="Preview" class="w-12 h-12 object-cover rounded" />
|
<img src={previewUrl} alt="Preview" class="w-12 h-12 object-cover rounded" />
|
||||||
{:else if fileType === "application/pdf" || fileName.endsWith(".pdf")}
|
{:else if fileType === "application/pdf" || fileName.endsWith(".pdf")}
|
||||||
<div class="w-12 h-12 bg-error/10 rounded flex items-center justify-center">
|
<div class="w-12 h-12 bg-error/10 rounded flex items-center justify-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-error" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<FileText class="h-6 w-6 text-error" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="w-12 h-12 bg-success/10 rounded flex items-center justify-center">
|
<div class="w-12 h-12 bg-success/10 rounded flex items-center justify-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-success" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<File class="h-6 w-6 text-success" strokeWidth={2} />
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@@ -221,10 +216,7 @@
|
|||||||
disabled={uploading || disabled}
|
disabled={uploading || disabled}
|
||||||
title="Visualizar arquivo"
|
title="Visualizar arquivo"
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<Eye class="h-4 w-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
<button
|
<button
|
||||||
@@ -234,9 +226,7 @@
|
|||||||
disabled={uploading || disabled}
|
disabled={uploading || disabled}
|
||||||
title="Substituir arquivo"
|
title="Substituir arquivo"
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<RefreshCw class="h-4 w-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -245,9 +235,7 @@
|
|||||||
disabled={uploading || disabled}
|
disabled={uploading || disabled}
|
||||||
title="Remover arquivo"
|
title="Remover arquivo"
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<Trash2 class="h-4 w-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -262,9 +250,7 @@
|
|||||||
<span class="loading loading-spinner loading-sm"></span>
|
<span class="loading loading-spinner loading-sm"></span>
|
||||||
Carregando...
|
Carregando...
|
||||||
{:else}
|
{:else}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<Upload class="h-5 w-5" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
|
||||||
</svg>
|
|
||||||
Selecionar arquivo (PDF ou imagem, máx. 10MB)
|
Selecionar arquivo (PDF ou imagem, máx. 10MB)
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,162 +1,159 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { modelosDeclaracoes } from "$lib/utils/modelosDeclaracoes";
|
import { modelosDeclaracoes } from "$lib/utils/modelosDeclaracoes";
|
||||||
import {
|
import {
|
||||||
gerarDeclaracaoAcumulacaoCargo,
|
gerarDeclaracaoAcumulacaoCargo,
|
||||||
gerarDeclaracaoDependentesIR,
|
gerarDeclaracaoDependentesIR,
|
||||||
gerarDeclaracaoIdoneidade,
|
gerarDeclaracaoIdoneidade,
|
||||||
gerarTermoNepotismo,
|
gerarTermoNepotismo,
|
||||||
gerarTermoOpcaoRemuneracao,
|
gerarTermoOpcaoRemuneracao,
|
||||||
downloadBlob
|
downloadBlob
|
||||||
} from "$lib/utils/declaracoesGenerator";
|
} from "$lib/utils/declaracoesGenerator";
|
||||||
|
import { FileText, Info } from "lucide-svelte";
|
||||||
interface Props {
|
|
||||||
funcionario?: any;
|
interface Props {
|
||||||
showPreencherButton?: boolean;
|
funcionario?: any;
|
||||||
}
|
showPreencherButton?: boolean;
|
||||||
|
}
|
||||||
let { funcionario, showPreencherButton = false }: Props = $props();
|
|
||||||
let generating = $state(false);
|
let { funcionario, showPreencherButton = false }: Props = $props();
|
||||||
|
let generating = $state(false);
|
||||||
function baixarModelo(arquivoUrl: string, nomeModelo: string) {
|
|
||||||
const link = document.createElement('a');
|
function baixarModelo(arquivoUrl: string, nomeModelo: string) {
|
||||||
link.href = arquivoUrl;
|
const link = document.createElement('a');
|
||||||
link.download = nomeModelo + '.pdf';
|
link.href = arquivoUrl;
|
||||||
link.target = '_blank';
|
link.download = nomeModelo + '.pdf';
|
||||||
document.body.appendChild(link);
|
link.target = '_blank';
|
||||||
link.click();
|
document.body.appendChild(link);
|
||||||
document.body.removeChild(link);
|
link.click();
|
||||||
}
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
async function gerarPreenchido(modeloId: string) {
|
|
||||||
if (!funcionario) {
|
async function gerarPreenchido(modeloId: string) {
|
||||||
alert('Dados do funcionário não disponíveis');
|
if (!funcionario) {
|
||||||
return;
|
alert('Dados do funcionário não disponíveis');
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
try {
|
|
||||||
generating = true;
|
try {
|
||||||
let blob: Blob;
|
generating = true;
|
||||||
let nomeArquivo: string;
|
let blob: Blob;
|
||||||
|
let nomeArquivo: string;
|
||||||
switch (modeloId) {
|
|
||||||
case 'acumulacao_cargo':
|
switch (modeloId) {
|
||||||
blob = await gerarDeclaracaoAcumulacaoCargo(funcionario);
|
case 'acumulacao_cargo':
|
||||||
nomeArquivo = `Declaracao_Acumulacao_Cargo_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
blob = await gerarDeclaracaoAcumulacaoCargo(funcionario);
|
||||||
break;
|
nomeArquivo = `Declaracao_Acumulacao_Cargo_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
||||||
|
break;
|
||||||
case 'dependentes_ir':
|
|
||||||
blob = await gerarDeclaracaoDependentesIR(funcionario);
|
case 'dependentes_ir':
|
||||||
nomeArquivo = `Declaracao_Dependentes_IR_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
blob = await gerarDeclaracaoDependentesIR(funcionario);
|
||||||
break;
|
nomeArquivo = `Declaracao_Dependentes_IR_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
||||||
|
break;
|
||||||
case 'idoneidade':
|
|
||||||
blob = await gerarDeclaracaoIdoneidade(funcionario);
|
case 'idoneidade':
|
||||||
nomeArquivo = `Declaracao_Idoneidade_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
blob = await gerarDeclaracaoIdoneidade(funcionario);
|
||||||
break;
|
nomeArquivo = `Declaracao_Idoneidade_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
||||||
|
break;
|
||||||
case 'nepotismo':
|
|
||||||
blob = await gerarTermoNepotismo(funcionario);
|
case 'nepotismo':
|
||||||
nomeArquivo = `Termo_Nepotismo_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
blob = await gerarTermoNepotismo(funcionario);
|
||||||
break;
|
nomeArquivo = `Termo_Nepotismo_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
||||||
|
break;
|
||||||
case 'opcao_remuneracao':
|
|
||||||
blob = await gerarTermoOpcaoRemuneracao(funcionario);
|
case 'opcao_remuneracao':
|
||||||
nomeArquivo = `Termo_Opcao_Remuneracao_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
blob = await gerarTermoOpcaoRemuneracao(funcionario);
|
||||||
break;
|
nomeArquivo = `Termo_Opcao_Remuneracao_${funcionario.nome.replace(/ /g, '_')}_${Date.now()}.pdf`;
|
||||||
|
break;
|
||||||
default:
|
|
||||||
alert('Modelo não encontrado');
|
default:
|
||||||
return;
|
alert('Modelo não encontrado');
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
downloadBlob(blob, nomeArquivo);
|
|
||||||
} catch (error) {
|
downloadBlob(blob, nomeArquivo);
|
||||||
console.error('Erro ao gerar declaração:', error);
|
} catch (error) {
|
||||||
alert('Erro ao gerar declaração preenchida');
|
console.error('Erro ao gerar declaração:', error);
|
||||||
} finally {
|
alert('Erro ao gerar declaração preenchida');
|
||||||
generating = false;
|
} finally {
|
||||||
}
|
generating = false;
|
||||||
}
|
}
|
||||||
</script>
|
}
|
||||||
|
</script>
|
||||||
<div class="card bg-base-100 shadow-xl">
|
|
||||||
<div class="card-body">
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<h2 class="card-title text-xl border-b pb-3">
|
<div class="card-body">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<h2 class="card-title text-xl border-b pb-3">
|
||||||
<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" />
|
<FileText class="h-5 w-5" strokeWidth={2} />
|
||||||
</svg>
|
Modelos de Declarações
|
||||||
Modelos de Declarações
|
</h2>
|
||||||
</h2>
|
|
||||||
|
<div class="alert alert-info shadow-sm mb-4">
|
||||||
<div class="alert alert-info shadow-sm mb-4">
|
<Info class="stroke-current shrink-0 h-5 w-5" strokeWidth={2} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-5 w-5" fill="none" viewBox="0 0 24 24">
|
<div class="text-sm">
|
||||||
<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" />
|
<p class="font-semibold">Baixe os modelos, preencha, assine e faça upload no sistema</p>
|
||||||
</svg>
|
<p class="text-xs opacity-80 mt-1">Estes documentos são necessários para completar o cadastro do funcionário</p>
|
||||||
<div class="text-sm">
|
</div>
|
||||||
<p class="font-semibold">Baixe os modelos, preencha, assine e faça upload no sistema</p>
|
</div>
|
||||||
<p class="text-xs opacity-80 mt-1">Estes documentos são necessários para completar o cadastro do funcionário</p>
|
|
||||||
</div>
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
</div>
|
{#each modelosDeclaracoes as modelo}
|
||||||
|
<div class="card bg-base-200 shadow-sm hover:shadow-md transition-shadow">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div class="card-body p-4">
|
||||||
{#each modelosDeclaracoes as modelo}
|
<div class="flex items-start gap-3">
|
||||||
<div class="card bg-base-200 shadow-sm hover:shadow-md transition-shadow">
|
<!-- Ícone PDF -->
|
||||||
<div class="card-body p-4">
|
<div class="flex-shrink-0 w-12 h-12 bg-error/10 rounded-lg flex items-center justify-center">
|
||||||
<div class="flex items-start gap-3">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-error" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<!-- Ícone PDF -->
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
||||||
<div class="flex-shrink-0 w-12 h-12 bg-error/10 rounded-lg flex items-center justify-center">
|
</svg>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-error" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
||||||
</svg>
|
<!-- Conteúdo -->
|
||||||
</div>
|
<div class="flex-1 min-w-0">
|
||||||
|
<h3 class="font-semibold text-sm mb-1 line-clamp-2">{modelo.nome}</h3>
|
||||||
<!-- Conteúdo -->
|
<p class="text-xs text-base-content/70 mb-3 line-clamp-2">{modelo.descricao}</p>
|
||||||
<div class="flex-1 min-w-0">
|
|
||||||
<h3 class="font-semibold text-sm mb-1 line-clamp-2">{modelo.nome}</h3>
|
<!-- Ações -->
|
||||||
<p class="text-xs text-base-content/70 mb-3 line-clamp-2">{modelo.descricao}</p>
|
<div class="flex flex-col gap-2">
|
||||||
|
<button
|
||||||
<!-- Ações -->
|
type="button"
|
||||||
<div class="flex flex-col gap-2">
|
class="btn btn-primary btn-xs gap-1"
|
||||||
<button
|
onclick={() => baixarModelo(modelo.arquivo, modelo.nome)}
|
||||||
type="button"
|
>
|
||||||
class="btn btn-primary btn-xs gap-1"
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
onclick={() => baixarModelo(modelo.arquivo, modelo.nome)}
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||||
>
|
</svg>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
Baixar Modelo
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
</button>
|
||||||
</svg>
|
|
||||||
Baixar Modelo
|
{#if showPreencherButton && modelo.podePreencherAutomaticamente && funcionario}
|
||||||
</button>
|
<button
|
||||||
|
type="button"
|
||||||
{#if showPreencherButton && modelo.podePreencherAutomaticamente && funcionario}
|
class="btn btn-outline btn-xs gap-1"
|
||||||
<button
|
onclick={() => gerarPreenchido(modelo.id)}
|
||||||
type="button"
|
disabled={generating}
|
||||||
class="btn btn-outline btn-xs gap-1"
|
>
|
||||||
onclick={() => gerarPreenchido(modelo.id)}
|
{#if generating}
|
||||||
disabled={generating}
|
<span class="loading loading-spinner loading-xs"></span>
|
||||||
>
|
Gerando...
|
||||||
{#if generating}
|
{:else}
|
||||||
<span class="loading loading-spinner loading-xs"></span>
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
Gerando...
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||||||
{:else}
|
</svg>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
Gerar Preenchido
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
{/if}
|
||||||
</svg>
|
</button>
|
||||||
Gerar Preenchido
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
</button>
|
</div>
|
||||||
{/if}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{/each}
|
<div class="mt-4 text-xs text-base-content/60 text-center">
|
||||||
</div>
|
<p>💡 Dica: Após preencher e assinar os documentos, faça upload na seção "Documentação Anexa"</p>
|
||||||
|
</div>
|
||||||
<div class="mt-4 text-xs text-base-content/60 text-center">
|
</div>
|
||||||
<p>💡 Dica: Após preencher e assinar os documentos, faça upload na seção "Documentação Anexa"</p>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,463 +1,458 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
import autoTable from 'jspdf-autotable';
|
import autoTable from 'jspdf-autotable';
|
||||||
import { maskCPF, maskCEP, maskPhone } from "$lib/utils/masks";
|
import { maskCPF, maskCEP, maskPhone } from "$lib/utils/masks";
|
||||||
import {
|
import {
|
||||||
SEXO_OPTIONS, ESTADO_CIVIL_OPTIONS, GRAU_INSTRUCAO_OPTIONS,
|
SEXO_OPTIONS, ESTADO_CIVIL_OPTIONS, GRAU_INSTRUCAO_OPTIONS,
|
||||||
GRUPO_SANGUINEO_OPTIONS, FATOR_RH_OPTIONS, APOSENTADO_OPTIONS
|
GRUPO_SANGUINEO_OPTIONS, FATOR_RH_OPTIONS, APOSENTADO_OPTIONS
|
||||||
} from "$lib/utils/constants";
|
} from "$lib/utils/constants";
|
||||||
import logoGovPE from "$lib/assets/logo_governo_PE.png";
|
import logoGovPE from "$lib/assets/logo_governo_PE.png";
|
||||||
|
import { CheckCircle2, X, Printer } from "lucide-svelte";
|
||||||
interface Props {
|
|
||||||
funcionario: any;
|
interface Props {
|
||||||
onClose: () => void;
|
funcionario: any;
|
||||||
}
|
onClose: () => void;
|
||||||
|
}
|
||||||
let { funcionario, onClose }: Props = $props();
|
|
||||||
|
let { funcionario, onClose }: Props = $props();
|
||||||
let modalRef: HTMLDialogElement;
|
|
||||||
let generating = $state(false);
|
let modalRef: HTMLDialogElement;
|
||||||
|
let generating = $state(false);
|
||||||
// Seções selecionáveis
|
|
||||||
let sections = $state({
|
// Seções selecionáveis
|
||||||
dadosPessoais: true,
|
let sections = $state({
|
||||||
filiacao: true,
|
dadosPessoais: true,
|
||||||
naturalidade: true,
|
filiacao: true,
|
||||||
documentos: true,
|
naturalidade: true,
|
||||||
formacao: true,
|
documentos: true,
|
||||||
saude: true,
|
formacao: true,
|
||||||
endereco: true,
|
saude: true,
|
||||||
contato: true,
|
endereco: true,
|
||||||
cargo: true,
|
contato: true,
|
||||||
bancario: true,
|
cargo: true,
|
||||||
});
|
bancario: true,
|
||||||
|
});
|
||||||
function getLabelFromOptions(value: string | undefined, options: Array<{value: string, label: string}>): string {
|
|
||||||
if (!value) return "-";
|
function getLabelFromOptions(value: string | undefined, options: Array<{value: string, label: string}>): string {
|
||||||
return options.find(opt => opt.value === value)?.label || value;
|
if (!value) return "-";
|
||||||
}
|
return options.find(opt => opt.value === value)?.label || value;
|
||||||
|
}
|
||||||
function selectAll() {
|
|
||||||
Object.keys(sections).forEach(key => {
|
function selectAll() {
|
||||||
sections[key as keyof typeof sections] = true;
|
Object.keys(sections).forEach(key => {
|
||||||
});
|
sections[key as keyof typeof sections] = true;
|
||||||
}
|
});
|
||||||
|
}
|
||||||
function deselectAll() {
|
|
||||||
Object.keys(sections).forEach(key => {
|
function deselectAll() {
|
||||||
sections[key as keyof typeof sections] = false;
|
Object.keys(sections).forEach(key => {
|
||||||
});
|
sections[key as keyof typeof sections] = false;
|
||||||
}
|
});
|
||||||
|
}
|
||||||
async function gerarPDF() {
|
|
||||||
try {
|
async function gerarPDF() {
|
||||||
generating = true;
|
try {
|
||||||
|
generating = true;
|
||||||
const doc = new jsPDF();
|
|
||||||
|
const doc = new jsPDF();
|
||||||
// Logo no canto superior esquerdo (proporcional)
|
|
||||||
let yPosition = 20;
|
// Logo no canto superior esquerdo (proporcional)
|
||||||
try {
|
let yPosition = 20;
|
||||||
const logoImg = new Image();
|
try {
|
||||||
logoImg.src = logoGovPE;
|
const logoImg = new Image();
|
||||||
await new Promise<void>((resolve, reject) => {
|
logoImg.src = logoGovPE;
|
||||||
logoImg.onload = () => resolve();
|
await new Promise<void>((resolve, reject) => {
|
||||||
logoImg.onerror = () => reject();
|
logoImg.onload = () => resolve();
|
||||||
setTimeout(() => reject(), 3000); // timeout após 3s
|
logoImg.onerror = () => reject();
|
||||||
});
|
setTimeout(() => reject(), 3000); // timeout após 3s
|
||||||
|
});
|
||||||
// Logo proporcional: largura 25mm, altura ajustada automaticamente
|
|
||||||
const logoWidth = 25;
|
// Logo proporcional: largura 25mm, altura ajustada automaticamente
|
||||||
const aspectRatio = logoImg.height / logoImg.width;
|
const logoWidth = 25;
|
||||||
const logoHeight = logoWidth * aspectRatio;
|
const aspectRatio = logoImg.height / logoImg.width;
|
||||||
|
const logoHeight = logoWidth * aspectRatio;
|
||||||
doc.addImage(logoImg, 'PNG', 15, 10, logoWidth, logoHeight);
|
|
||||||
|
doc.addImage(logoImg, 'PNG', 15, 10, logoWidth, logoHeight);
|
||||||
// Ajustar posição inicial do texto para ficar ao lado da logo
|
|
||||||
yPosition = Math.max(20, 10 + logoHeight / 2);
|
// Ajustar posição inicial do texto para ficar ao lado da logo
|
||||||
} catch (err) {
|
yPosition = Math.max(20, 10 + logoHeight / 2);
|
||||||
console.warn('Não foi possível carregar a logo:', err);
|
} catch (err) {
|
||||||
}
|
console.warn('Não foi possível carregar a logo:', err);
|
||||||
|
}
|
||||||
// Cabeçalho (alinhado com a logo)
|
|
||||||
doc.setFontSize(16);
|
// Cabeçalho (alinhado com a logo)
|
||||||
doc.setFont('helvetica', 'bold');
|
doc.setFontSize(16);
|
||||||
doc.text('Secretaria de Esportes', 50, yPosition);
|
doc.setFont('helvetica', 'bold');
|
||||||
doc.setFontSize(12);
|
doc.text('Secretaria de Esportes', 50, yPosition);
|
||||||
doc.setFont('helvetica', 'normal');
|
doc.setFontSize(12);
|
||||||
doc.text('Governo de Pernambuco', 50, yPosition + 7);
|
doc.setFont('helvetica', 'normal');
|
||||||
|
doc.text('Governo de Pernambuco', 50, yPosition + 7);
|
||||||
yPosition = Math.max(45, yPosition + 25);
|
|
||||||
|
yPosition = Math.max(45, yPosition + 25);
|
||||||
// Título da ficha
|
|
||||||
doc.setFontSize(18);
|
// Título da ficha
|
||||||
doc.setFont('helvetica', 'bold');
|
doc.setFontSize(18);
|
||||||
doc.text('FICHA CADASTRAL DE FUNCIONÁRIO', 105, yPosition, { align: 'center' });
|
doc.setFont('helvetica', 'bold');
|
||||||
|
doc.text('FICHA CADASTRAL DE FUNCIONÁRIO', 105, yPosition, { align: 'center' });
|
||||||
yPosition += 8;
|
|
||||||
doc.setFontSize(10);
|
yPosition += 8;
|
||||||
doc.setFont('helvetica', 'normal');
|
doc.setFontSize(10);
|
||||||
doc.text(`Gerado em: ${new Date().toLocaleString('pt-BR')}`, 105, yPosition, { align: 'center' });
|
doc.setFont('helvetica', 'normal');
|
||||||
|
doc.text(`Gerado em: ${new Date().toLocaleString('pt-BR')}`, 105, yPosition, { align: 'center' });
|
||||||
yPosition += 12;
|
|
||||||
|
yPosition += 12;
|
||||||
// Dados Pessoais
|
|
||||||
if (sections.dadosPessoais) {
|
// Dados Pessoais
|
||||||
const dadosPessoais: any[] = [
|
if (sections.dadosPessoais) {
|
||||||
['Nome', funcionario.nome],
|
const dadosPessoais: any[] = [
|
||||||
['Matrícula', funcionario.matricula],
|
['Nome', funcionario.nome],
|
||||||
['CPF', maskCPF(funcionario.cpf)],
|
['Matrícula', funcionario.matricula],
|
||||||
['RG', funcionario.rg],
|
['CPF', maskCPF(funcionario.cpf)],
|
||||||
['Data Nascimento', funcionario.nascimento],
|
['RG', funcionario.rg],
|
||||||
];
|
['Data Nascimento', funcionario.nascimento],
|
||||||
|
];
|
||||||
if (funcionario.rgOrgaoExpedidor) dadosPessoais.push(['Órgão Expedidor RG', funcionario.rgOrgaoExpedidor]);
|
|
||||||
if (funcionario.rgDataEmissao) dadosPessoais.push(['Data Emissão RG', funcionario.rgDataEmissao]);
|
if (funcionario.rgOrgaoExpedidor) dadosPessoais.push(['Órgão Expedidor RG', funcionario.rgOrgaoExpedidor]);
|
||||||
if (funcionario.sexo) dadosPessoais.push(['Sexo', getLabelFromOptions(funcionario.sexo, SEXO_OPTIONS)]);
|
if (funcionario.rgDataEmissao) dadosPessoais.push(['Data Emissão RG', funcionario.rgDataEmissao]);
|
||||||
if (funcionario.estadoCivil) dadosPessoais.push(['Estado Civil', getLabelFromOptions(funcionario.estadoCivil, ESTADO_CIVIL_OPTIONS)]);
|
if (funcionario.sexo) dadosPessoais.push(['Sexo', getLabelFromOptions(funcionario.sexo, SEXO_OPTIONS)]);
|
||||||
if (funcionario.nacionalidade) dadosPessoais.push(['Nacionalidade', funcionario.nacionalidade]);
|
if (funcionario.estadoCivil) dadosPessoais.push(['Estado Civil', getLabelFromOptions(funcionario.estadoCivil, ESTADO_CIVIL_OPTIONS)]);
|
||||||
|
if (funcionario.nacionalidade) dadosPessoais.push(['Nacionalidade', funcionario.nacionalidade]);
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['DADOS PESSOAIS', '']],
|
startY: yPosition,
|
||||||
body: dadosPessoais,
|
head: [['DADOS PESSOAIS', '']],
|
||||||
theme: 'grid',
|
body: dadosPessoais,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Filiação
|
|
||||||
if (sections.filiacao && (funcionario.nomePai || funcionario.nomeMae)) {
|
// Filiação
|
||||||
const filiacao: any[] = [];
|
if (sections.filiacao && (funcionario.nomePai || funcionario.nomeMae)) {
|
||||||
if (funcionario.nomePai) filiacao.push(['Nome do Pai', funcionario.nomePai]);
|
const filiacao: any[] = [];
|
||||||
if (funcionario.nomeMae) filiacao.push(['Nome da Mãe', funcionario.nomeMae]);
|
if (funcionario.nomePai) filiacao.push(['Nome do Pai', funcionario.nomePai]);
|
||||||
|
if (funcionario.nomeMae) filiacao.push(['Nome da Mãe', funcionario.nomeMae]);
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['FILIAÇÃO', '']],
|
startY: yPosition,
|
||||||
body: filiacao,
|
head: [['FILIAÇÃO', '']],
|
||||||
theme: 'grid',
|
body: filiacao,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Naturalidade
|
|
||||||
if (sections.naturalidade && (funcionario.naturalidade || funcionario.naturalidadeUF)) {
|
// Naturalidade
|
||||||
const naturalidade: any[] = [];
|
if (sections.naturalidade && (funcionario.naturalidade || funcionario.naturalidadeUF)) {
|
||||||
if (funcionario.naturalidade) naturalidade.push(['Cidade', funcionario.naturalidade]);
|
const naturalidade: any[] = [];
|
||||||
if (funcionario.naturalidadeUF) naturalidade.push(['UF', funcionario.naturalidadeUF]);
|
if (funcionario.naturalidade) naturalidade.push(['Cidade', funcionario.naturalidade]);
|
||||||
|
if (funcionario.naturalidadeUF) naturalidade.push(['UF', funcionario.naturalidadeUF]);
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['NATURALIDADE', '']],
|
startY: yPosition,
|
||||||
body: naturalidade,
|
head: [['NATURALIDADE', '']],
|
||||||
theme: 'grid',
|
body: naturalidade,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Documentos
|
|
||||||
if (sections.documentos) {
|
// Documentos
|
||||||
const documentosData: any[] = [];
|
if (sections.documentos) {
|
||||||
|
const documentosData: any[] = [];
|
||||||
if (funcionario.carteiraProfissionalNumero) {
|
|
||||||
documentosData.push(['Cart. Profissional', `Nº ${funcionario.carteiraProfissionalNumero}${funcionario.carteiraProfissionalSerie ? ' - Série: ' + funcionario.carteiraProfissionalSerie : ''}`]);
|
if (funcionario.carteiraProfissionalNumero) {
|
||||||
}
|
documentosData.push(['Cart. Profissional', `Nº ${funcionario.carteiraProfissionalNumero}${funcionario.carteiraProfissionalSerie ? ' - Série: ' + funcionario.carteiraProfissionalSerie : ''}`]);
|
||||||
if (funcionario.reservistaNumero) {
|
}
|
||||||
documentosData.push(['Reservista', `Nº ${funcionario.reservistaNumero}${funcionario.reservistaSerie ? ' - Série: ' + funcionario.reservistaSerie : ''}`]);
|
if (funcionario.reservistaNumero) {
|
||||||
}
|
documentosData.push(['Reservista', `Nº ${funcionario.reservistaNumero}${funcionario.reservistaSerie ? ' - Série: ' + funcionario.reservistaSerie : ''}`]);
|
||||||
if (funcionario.tituloEleitorNumero) {
|
}
|
||||||
let titulo = `Nº ${funcionario.tituloEleitorNumero}`;
|
if (funcionario.tituloEleitorNumero) {
|
||||||
if (funcionario.tituloEleitorZona) titulo += ` - Zona: ${funcionario.tituloEleitorZona}`;
|
let titulo = `Nº ${funcionario.tituloEleitorNumero}`;
|
||||||
if (funcionario.tituloEleitorSecao) titulo += ` - Seção: ${funcionario.tituloEleitorSecao}`;
|
if (funcionario.tituloEleitorZona) titulo += ` - Zona: ${funcionario.tituloEleitorZona}`;
|
||||||
documentosData.push(['Título Eleitor', titulo]);
|
if (funcionario.tituloEleitorSecao) titulo += ` - Seção: ${funcionario.tituloEleitorSecao}`;
|
||||||
}
|
documentosData.push(['Título Eleitor', titulo]);
|
||||||
if (funcionario.pisNumero) documentosData.push(['PIS/PASEP', funcionario.pisNumero]);
|
}
|
||||||
|
if (funcionario.pisNumero) documentosData.push(['PIS/PASEP', funcionario.pisNumero]);
|
||||||
if (documentosData.length > 0) {
|
|
||||||
autoTable(doc, {
|
if (documentosData.length > 0) {
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['DOCUMENTOS', '']],
|
startY: yPosition,
|
||||||
body: documentosData,
|
head: [['DOCUMENTOS', '']],
|
||||||
theme: 'grid',
|
body: documentosData,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Formação
|
|
||||||
if (sections.formacao && (funcionario.grauInstrucao || funcionario.formacao)) {
|
// Formação
|
||||||
const formacaoData: any[] = [];
|
if (sections.formacao && (funcionario.grauInstrucao || funcionario.formacao)) {
|
||||||
if (funcionario.grauInstrucao) formacaoData.push(['Grau Instrução', getLabelFromOptions(funcionario.grauInstrucao, GRAU_INSTRUCAO_OPTIONS)]);
|
const formacaoData: any[] = [];
|
||||||
if (funcionario.formacao) formacaoData.push(['Formação', funcionario.formacao]);
|
if (funcionario.grauInstrucao) formacaoData.push(['Grau Instrução', getLabelFromOptions(funcionario.grauInstrucao, GRAU_INSTRUCAO_OPTIONS)]);
|
||||||
if (funcionario.formacaoRegistro) formacaoData.push(['Registro Nº', funcionario.formacaoRegistro]);
|
if (funcionario.formacao) formacaoData.push(['Formação', funcionario.formacao]);
|
||||||
|
if (funcionario.formacaoRegistro) formacaoData.push(['Registro Nº', funcionario.formacaoRegistro]);
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['FORMAÇÃO', '']],
|
startY: yPosition,
|
||||||
body: formacaoData,
|
head: [['FORMAÇÃO', '']],
|
||||||
theme: 'grid',
|
body: formacaoData,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Saúde
|
|
||||||
if (sections.saude && (funcionario.grupoSanguineo || funcionario.fatorRH)) {
|
// Saúde
|
||||||
const saudeData: any[] = [];
|
if (sections.saude && (funcionario.grupoSanguineo || funcionario.fatorRH)) {
|
||||||
if (funcionario.grupoSanguineo) saudeData.push(['Grupo Sanguíneo', funcionario.grupoSanguineo]);
|
const saudeData: any[] = [];
|
||||||
if (funcionario.fatorRH) saudeData.push(['Fator RH', getLabelFromOptions(funcionario.fatorRH, FATOR_RH_OPTIONS)]);
|
if (funcionario.grupoSanguineo) saudeData.push(['Grupo Sanguíneo', funcionario.grupoSanguineo]);
|
||||||
|
if (funcionario.fatorRH) saudeData.push(['Fator RH', getLabelFromOptions(funcionario.fatorRH, FATOR_RH_OPTIONS)]);
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['SAÚDE', '']],
|
startY: yPosition,
|
||||||
body: saudeData,
|
head: [['SAÚDE', '']],
|
||||||
theme: 'grid',
|
body: saudeData,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Endereço
|
|
||||||
if (sections.endereco) {
|
// Endereço
|
||||||
const enderecoData: any[] = [
|
if (sections.endereco) {
|
||||||
['Endereço', funcionario.endereco],
|
const enderecoData: any[] = [
|
||||||
['Cidade', funcionario.cidade],
|
['Endereço', funcionario.endereco],
|
||||||
['UF', funcionario.uf],
|
['Cidade', funcionario.cidade],
|
||||||
['CEP', maskCEP(funcionario.cep)],
|
['UF', funcionario.uf],
|
||||||
];
|
['CEP', maskCEP(funcionario.cep)],
|
||||||
|
];
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['ENDEREÇO', '']],
|
startY: yPosition,
|
||||||
body: enderecoData,
|
head: [['ENDEREÇO', '']],
|
||||||
theme: 'grid',
|
body: enderecoData,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Contato
|
|
||||||
if (sections.contato) {
|
// Contato
|
||||||
const contatoData: any[] = [
|
if (sections.contato) {
|
||||||
['E-mail', funcionario.email],
|
const contatoData: any[] = [
|
||||||
['Telefone', maskPhone(funcionario.telefone)],
|
['E-mail', funcionario.email],
|
||||||
];
|
['Telefone', maskPhone(funcionario.telefone)],
|
||||||
|
];
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['CONTATO', '']],
|
startY: yPosition,
|
||||||
body: contatoData,
|
head: [['CONTATO', '']],
|
||||||
theme: 'grid',
|
body: contatoData,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Nova página para cargo
|
|
||||||
if (yPosition > 200) {
|
// Nova página para cargo
|
||||||
doc.addPage();
|
if (yPosition > 200) {
|
||||||
yPosition = 20;
|
doc.addPage();
|
||||||
}
|
yPosition = 20;
|
||||||
|
}
|
||||||
// Cargo e Vínculo
|
|
||||||
if (sections.cargo) {
|
// Cargo e Vínculo
|
||||||
const cargoData: any[] = [
|
if (sections.cargo) {
|
||||||
['Tipo', funcionario.simboloTipo === 'cargo_comissionado' ? 'Cargo Comissionado' : 'Função Gratificada'],
|
const cargoData: any[] = [
|
||||||
];
|
['Tipo', funcionario.simboloTipo === 'cargo_comissionado' ? 'Cargo Comissionado' : 'Função Gratificada'],
|
||||||
|
];
|
||||||
if (funcionario.simbolo) {
|
|
||||||
cargoData.push(['Símbolo', funcionario.simbolo.nome]);
|
if (funcionario.simbolo) {
|
||||||
}
|
cargoData.push(['Símbolo', funcionario.simbolo.nome]);
|
||||||
if (funcionario.descricaoCargo) cargoData.push(['Descrição', funcionario.descricaoCargo]);
|
}
|
||||||
if (funcionario.admissaoData) cargoData.push(['Data Admissão', funcionario.admissaoData]);
|
if (funcionario.descricaoCargo) cargoData.push(['Descrição', funcionario.descricaoCargo]);
|
||||||
if (funcionario.nomeacaoPortaria) cargoData.push(['Portaria', funcionario.nomeacaoPortaria]);
|
if (funcionario.admissaoData) cargoData.push(['Data Admissão', funcionario.admissaoData]);
|
||||||
if (funcionario.nomeacaoData) cargoData.push(['Data Nomeação', funcionario.nomeacaoData]);
|
if (funcionario.nomeacaoPortaria) cargoData.push(['Portaria', funcionario.nomeacaoPortaria]);
|
||||||
if (funcionario.nomeacaoDOE) cargoData.push(['DOE', funcionario.nomeacaoDOE]);
|
if (funcionario.nomeacaoData) cargoData.push(['Data Nomeação', funcionario.nomeacaoData]);
|
||||||
if (funcionario.pertenceOrgaoPublico) {
|
if (funcionario.nomeacaoDOE) cargoData.push(['DOE', funcionario.nomeacaoDOE]);
|
||||||
cargoData.push(['Pertence Órgão Público', 'Sim']);
|
if (funcionario.pertenceOrgaoPublico) {
|
||||||
if (funcionario.orgaoOrigem) cargoData.push(['Órgão Origem', funcionario.orgaoOrigem]);
|
cargoData.push(['Pertence Órgão Público', 'Sim']);
|
||||||
}
|
if (funcionario.orgaoOrigem) cargoData.push(['Órgão Origem', funcionario.orgaoOrigem]);
|
||||||
if (funcionario.aposentado && funcionario.aposentado !== 'nao') {
|
}
|
||||||
cargoData.push(['Aposentado', getLabelFromOptions(funcionario.aposentado, APOSENTADO_OPTIONS)]);
|
if (funcionario.aposentado && funcionario.aposentado !== 'nao') {
|
||||||
}
|
cargoData.push(['Aposentado', getLabelFromOptions(funcionario.aposentado, APOSENTADO_OPTIONS)]);
|
||||||
|
}
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['CARGO E VÍNCULO', '']],
|
startY: yPosition,
|
||||||
body: cargoData,
|
head: [['CARGO E VÍNCULO', '']],
|
||||||
theme: 'grid',
|
body: cargoData,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Dados Bancários
|
|
||||||
if (sections.bancario && funcionario.contaBradescoNumero) {
|
// Dados Bancários
|
||||||
const bancarioData: any[] = [
|
if (sections.bancario && funcionario.contaBradescoNumero) {
|
||||||
['Conta', `${funcionario.contaBradescoNumero}${funcionario.contaBradescoDV ? '-' + funcionario.contaBradescoDV : ''}`],
|
const bancarioData: any[] = [
|
||||||
];
|
['Conta', `${funcionario.contaBradescoNumero}${funcionario.contaBradescoDV ? '-' + funcionario.contaBradescoDV : ''}`],
|
||||||
if (funcionario.contaBradescoAgencia) bancarioData.push(['Agência', funcionario.contaBradescoAgencia]);
|
];
|
||||||
|
if (funcionario.contaBradescoAgencia) bancarioData.push(['Agência', funcionario.contaBradescoAgencia]);
|
||||||
autoTable(doc, {
|
|
||||||
startY: yPosition,
|
autoTable(doc, {
|
||||||
head: [['DADOS BANCÁRIOS - BRADESCO', '']],
|
startY: yPosition,
|
||||||
body: bancarioData,
|
head: [['DADOS BANCÁRIOS - BRADESCO', '']],
|
||||||
theme: 'grid',
|
body: bancarioData,
|
||||||
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
theme: 'grid',
|
||||||
styles: { fontSize: 9 },
|
headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold' },
|
||||||
});
|
styles: { fontSize: 9 },
|
||||||
|
});
|
||||||
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
|
||||||
}
|
yPosition = (doc as any).lastAutoTable.finalY + 10;
|
||||||
|
}
|
||||||
// Adicionar rodapé em todas as páginas
|
|
||||||
const pageCount = (doc as any).internal.getNumberOfPages();
|
// Adicionar rodapé em todas as páginas
|
||||||
for (let i = 1; i <= pageCount; i++) {
|
const pageCount = (doc as any).internal.getNumberOfPages();
|
||||||
doc.setPage(i);
|
for (let i = 1; i <= pageCount; i++) {
|
||||||
doc.setFontSize(9);
|
doc.setPage(i);
|
||||||
doc.setFont('helvetica', 'normal');
|
doc.setFontSize(9);
|
||||||
doc.setTextColor(128, 128, 128);
|
doc.setFont('helvetica', 'normal');
|
||||||
doc.text('SGSE - Sistema de Gerenciamento da Secretaria de Esportes', 105, 285, { align: 'center' });
|
doc.setTextColor(128, 128, 128);
|
||||||
doc.text(`Página ${i} de ${pageCount}`, 195, 285, { align: 'right' });
|
doc.text('SGSE - Sistema de Gerenciamento da Secretaria de Esportes', 105, 285, { align: 'center' });
|
||||||
}
|
doc.text(`Página ${i} de ${pageCount}`, 195, 285, { align: 'right' });
|
||||||
|
}
|
||||||
// Salvar PDF
|
|
||||||
doc.save(`Ficha_${funcionario.nome.replace(/ /g, '_')}_${new Date().getTime()}.pdf`);
|
// Salvar PDF
|
||||||
|
doc.save(`Ficha_${funcionario.nome.replace(/ /g, '_')}_${new Date().getTime()}.pdf`);
|
||||||
onClose();
|
|
||||||
} catch (error) {
|
onClose();
|
||||||
console.error('Erro ao gerar PDF:', error);
|
} catch (error) {
|
||||||
alert('Erro ao gerar PDF. Verifique o console para mais detalhes.');
|
console.error('Erro ao gerar PDF:', error);
|
||||||
} finally {
|
alert('Erro ao gerar PDF. Verifique o console para mais detalhes.');
|
||||||
generating = false;
|
} finally {
|
||||||
}
|
generating = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$effect(() => {
|
|
||||||
if (modalRef) {
|
$effect(() => {
|
||||||
modalRef.showModal();
|
if (modalRef) {
|
||||||
}
|
modalRef.showModal();
|
||||||
});
|
}
|
||||||
</script>
|
});
|
||||||
|
</script>
|
||||||
<dialog bind:this={modalRef} class="modal">
|
|
||||||
<div class="modal-box max-w-4xl">
|
<dialog bind:this={modalRef} class="modal">
|
||||||
<h3 class="font-bold text-2xl mb-4">Imprimir Ficha Cadastral</h3>
|
<div class="modal-box max-w-4xl">
|
||||||
<p class="text-sm text-base-content/70 mb-6">Selecione as seções que deseja incluir no PDF</p>
|
<h3 class="font-bold text-2xl mb-4">Imprimir Ficha Cadastral</h3>
|
||||||
|
<p class="text-sm text-base-content/70 mb-6">Selecione as seções que deseja incluir no PDF</p>
|
||||||
<!-- Botões de seleção -->
|
|
||||||
<div class="flex gap-2 mb-6">
|
<!-- Botões de seleção -->
|
||||||
<button type="button" class="btn btn-sm btn-outline" onclick={selectAll}>
|
<div class="flex gap-2 mb-6">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<button type="button" class="btn btn-sm btn-outline" onclick={selectAll}>
|
||||||
<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" />
|
<CheckCircle2 class="h-4 w-4" strokeWidth={2} />
|
||||||
</svg>
|
Selecionar Todos
|
||||||
Selecionar Todos
|
</button>
|
||||||
</button>
|
<button type="button" class="btn btn-sm btn-outline" onclick={deselectAll}>
|
||||||
<button type="button" class="btn btn-sm btn-outline" onclick={deselectAll}>
|
<X class="h-4 w-4" strokeWidth={2} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
Desmarcar Todos
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
</button>
|
||||||
</svg>
|
</div>
|
||||||
Desmarcar Todos
|
|
||||||
</button>
|
<!-- Grid de checkboxes -->
|
||||||
</div>
|
<div class="grid grid-cols-2 md:grid-cols-3 gap-4 mb-6 max-h-96 overflow-y-auto p-2 border rounded-lg bg-base-200">
|
||||||
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
<!-- Grid de checkboxes -->
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.dadosPessoais} />
|
||||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4 mb-6 max-h-96 overflow-y-auto p-2 border rounded-lg bg-base-200">
|
<span class="label-text">Dados Pessoais</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.dadosPessoais} />
|
|
||||||
<span class="label-text">Dados Pessoais</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.filiacao} />
|
||||||
|
<span class="label-text">Filiação</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.filiacao} />
|
|
||||||
<span class="label-text">Filiação</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.naturalidade} />
|
||||||
|
<span class="label-text">Naturalidade</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.naturalidade} />
|
|
||||||
<span class="label-text">Naturalidade</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.documentos} />
|
||||||
|
<span class="label-text">Documentos</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.documentos} />
|
|
||||||
<span class="label-text">Documentos</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.formacao} />
|
||||||
|
<span class="label-text">Formação</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.formacao} />
|
|
||||||
<span class="label-text">Formação</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.saude} />
|
||||||
|
<span class="label-text">Saúde</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.saude} />
|
|
||||||
<span class="label-text">Saúde</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.endereco} />
|
||||||
|
<span class="label-text">Endereço</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.endereco} />
|
|
||||||
<span class="label-text">Endereço</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.contato} />
|
||||||
|
<span class="label-text">Contato</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.contato} />
|
|
||||||
<span class="label-text">Contato</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.cargo} />
|
||||||
|
<span class="label-text">Cargo e Vínculo</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.cargo} />
|
|
||||||
<span class="label-text">Cargo e Vínculo</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
</label>
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.bancario} />
|
||||||
|
<span class="label-text">Dados Bancários</span>
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
</label>
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={sections.bancario} />
|
</div>
|
||||||
<span class="label-text">Dados Bancários</span>
|
|
||||||
</label>
|
<!-- Ações -->
|
||||||
</div>
|
<div class="modal-action">
|
||||||
|
<button type="button" class="btn btn-ghost" onclick={onClose} disabled={generating}>
|
||||||
<!-- Ações -->
|
Cancelar
|
||||||
<div class="modal-action">
|
</button>
|
||||||
<button type="button" class="btn btn-ghost" onclick={onClose} disabled={generating}>
|
<button type="button" class="btn btn-primary gap-2" onclick={gerarPDF} disabled={generating}>
|
||||||
Cancelar
|
{#if generating}
|
||||||
</button>
|
<span class="loading loading-spinner loading-sm"></span>
|
||||||
<button type="button" class="btn btn-primary gap-2" onclick={gerarPDF} disabled={generating}>
|
Gerando PDF...
|
||||||
{#if generating}
|
{:else}
|
||||||
<span class="loading loading-spinner loading-sm"></span>
|
<Printer class="h-5 w-5" strokeWidth={2} />
|
||||||
Gerando PDF...
|
Gerar PDF
|
||||||
{:else}
|
{/if}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</button>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Gerar PDF
|
|
||||||
{/if}
|
<form method="dialog" class="modal-backdrop">
|
||||||
</button>
|
<button type="button" onclick={onClose}>fechar</button>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</dialog>
|
||||||
|
|
||||||
<form method="dialog" class="modal-backdrop">
|
|
||||||
<button type="button" onclick={onClose}>fechar</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
import PresenceManager from "$lib/components/chat/PresenceManager.svelte";
|
import PresenceManager from "$lib/components/chat/PresenceManager.svelte";
|
||||||
import { getBrowserInfo } from "$lib/utils/browserInfo";
|
import { getBrowserInfo } from "$lib/utils/browserInfo";
|
||||||
import { getAvatarUrl } from "$lib/utils/avatarGenerator";
|
import { getAvatarUrl } from "$lib/utils/avatarGenerator";
|
||||||
|
import { Menu, User, Home, UserPlus, XCircle, LogIn, Tag, Plus, Check } from "lucide-svelte";
|
||||||
|
|
||||||
let { children }: { children: Snippet } = $props();
|
let { children }: { children: Snippet } = $props();
|
||||||
|
|
||||||
@@ -180,21 +181,11 @@
|
|||||||
<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>
|
<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 -->
|
<!-- Ícone de menu hambúrguer -->
|
||||||
<svg
|
<Menu
|
||||||
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"
|
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));"
|
style="filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3));"
|
||||||
>
|
strokeWidth={2.5}
|
||||||
<path
|
/>
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2.5"
|
|
||||||
d="M4 6h16M4 12h16M4 18h16"
|
|
||||||
stroke="currentColor"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 flex items-center gap-4 lg:gap-6">
|
<div class="flex-1 flex items-center gap-4 lg:gap-6">
|
||||||
@@ -261,15 +252,10 @@
|
|||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<!-- Ícone de usuário moderno (fallback) -->
|
<!-- Ícone de usuário moderno (fallback) -->
|
||||||
<svg
|
<User
|
||||||
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"
|
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));"
|
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>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Badge de status online -->
|
<!-- Badge de status online -->
|
||||||
@@ -301,21 +287,11 @@
|
|||||||
<div class="absolute inset-0 rounded-full bg-white/10 group-hover:animate-ping"></div>
|
<div class="absolute inset-0 rounded-full bg-white/10 group-hover:animate-ping"></div>
|
||||||
|
|
||||||
<!-- Ícone de login premium -->
|
<!-- Ícone de login premium -->
|
||||||
<svg
|
<User
|
||||||
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"
|
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));"
|
style="filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3));"
|
||||||
>
|
strokeWidth={2.5}
|
||||||
<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>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@@ -365,20 +341,10 @@
|
|||||||
href="/"
|
href="/"
|
||||||
class={getMenuClasses(currentPath === "/")}
|
class={getMenuClasses(currentPath === "/")}
|
||||||
>
|
>
|
||||||
<svg
|
<Home
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="h-5 w-5 group-hover:scale-110 transition-transform"
|
class="h-5 w-5 group-hover:scale-110 transition-transform"
|
||||||
fill="none"
|
strokeWidth={2}
|
||||||
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>
|
<span>Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -399,20 +365,10 @@
|
|||||||
href="/solicitar-acesso"
|
href="/solicitar-acesso"
|
||||||
class={getSolicitarClasses(currentPath === "/solicitar-acesso")}
|
class={getSolicitarClasses(currentPath === "/solicitar-acesso")}
|
||||||
>
|
>
|
||||||
<svg
|
<UserPlus
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="h-5 w-5"
|
class="h-5 w-5"
|
||||||
fill="none"
|
strokeWidth={2}
|
||||||
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>
|
<span>Solicitar acesso</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -446,9 +402,7 @@
|
|||||||
|
|
||||||
{#if erroLogin}
|
{#if erroLogin}
|
||||||
<div class="alert alert-error mb-4">
|
<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">
|
<XCircle class="stroke-current shrink-0 h-6 w-6" strokeWidth={2} />
|
||||||
<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>
|
<span>{erroLogin}</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -492,9 +446,7 @@
|
|||||||
<span class="loading loading-spinner loading-sm"></span>
|
<span class="loading loading-spinner loading-sm"></span>
|
||||||
Entrando...
|
Entrando...
|
||||||
{:else}
|
{:else}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<LogIn class="h-5 w-5" strokeWidth={2} />
|
||||||
<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
|
Entrar
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
@@ -559,16 +511,12 @@
|
|||||||
<!-- Informações de Versão -->
|
<!-- Informações de Versão -->
|
||||||
<div class="bg-primary/10 rounded-xl p-6 space-y-3">
|
<div class="bg-primary/10 rounded-xl p-6 space-y-3">
|
||||||
<div class="flex items-center justify-center gap-2">
|
<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">
|
<Tag class="h-5 w-5 text-primary" strokeWidth={2} />
|
||||||
<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>
|
<p class="text-sm font-medium text-base-content/70">Versão</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-2xl font-bold text-primary">1.0 26_2025</p>
|
<p class="text-2xl font-bold text-primary">1.0 26_2025</p>
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
<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">
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
|
||||||
</svg>
|
|
||||||
Em Desenvolvimento
|
Em Desenvolvimento
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -603,9 +551,7 @@
|
|||||||
class="btn btn-primary btn-lg w-full max-w-xs mx-auto shadow-lg hover:shadow-xl transition-all duration-300"
|
class="btn btn-primary btn-lg w-full max-w-xs mx-auto shadow-lg hover:shadow-xl transition-all duration-300"
|
||||||
onclick={closeAboutModal}
|
onclick={closeAboutModal}
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<Check class="h-6 w-6" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
||||||
</svg>
|
|
||||||
OK
|
OK
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
import SalaReuniaoManager from "./SalaReuniaoManager.svelte";
|
import SalaReuniaoManager from "./SalaReuniaoManager.svelte";
|
||||||
import { getAvatarUrl } from "$lib/utils/avatarGenerator";
|
import { getAvatarUrl } from "$lib/utils/avatarGenerator";
|
||||||
import { authStore } from "$lib/stores/auth.svelte";
|
import { authStore } from "$lib/stores/auth.svelte";
|
||||||
import { Bell, X } from "lucide-svelte";
|
import { Bell, X, ArrowLeft, LogOut, MoreVertical, Users, Clock, XCircle } from "lucide-svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
conversaId: string;
|
conversaId: string;
|
||||||
@@ -117,18 +117,10 @@
|
|||||||
aria-label="Voltar"
|
aria-label="Voltar"
|
||||||
title="Voltar para lista de conversas"
|
title="Voltar para lista de conversas"
|
||||||
>
|
>
|
||||||
<svg
|
<ArrowLeft
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-6 h-6 text-primary"
|
class="w-6 h-6 text-primary"
|
||||||
>
|
strokeWidth={2.5}
|
||||||
<path d="M19 12H5M12 19l-7-7 7-7"/>
|
/>
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Avatar e Info -->
|
<!-- Avatar e Info -->
|
||||||
@@ -215,20 +207,10 @@
|
|||||||
title="Sair da conversa"
|
title="Sair da conversa"
|
||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-red-500/0 group-hover:bg-red-500/10 transition-colors duration-300"></div>
|
<div class="absolute inset-0 bg-red-500/0 group-hover:bg-red-500/10 transition-colors duration-300"></div>
|
||||||
<svg
|
<LogOut
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-5 h-5 text-red-500 relative z-10 group-hover:scale-110 transition-transform"
|
class="w-5 h-5 text-red-500 relative z-10 group-hover:scale-110 transition-transform"
|
||||||
>
|
strokeWidth={2}
|
||||||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
|
/>
|
||||||
<polyline points="16 17 21 12 16 7"/>
|
|
||||||
<line x1="21" y1="12" x2="9" y2="12"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -247,20 +229,10 @@
|
|||||||
title="Recursos administrativos"
|
title="Recursos administrativos"
|
||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-blue-500/0 group-hover:bg-blue-500/10 transition-colors duration-300"></div>
|
<div class="absolute inset-0 bg-blue-500/0 group-hover:bg-blue-500/10 transition-colors duration-300"></div>
|
||||||
<svg
|
<MoreVertical
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-5 h-5 text-blue-500 relative z-10 group-hover:scale-110 transition-transform"
|
class="w-5 h-5 text-blue-500 relative z-10 group-hover:scale-110 transition-transform"
|
||||||
>
|
strokeWidth={2}
|
||||||
<circle cx="12" cy="12" r="1"/>
|
/>
|
||||||
<circle cx="12" cy="5" r="1"/>
|
|
||||||
<circle cx="12" cy="19" r="1"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
{#if showAdminMenu}
|
{#if showAdminMenu}
|
||||||
<ul
|
<ul
|
||||||
@@ -277,9 +249,7 @@
|
|||||||
showAdminMenu = false;
|
showAdminMenu = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4">
|
<Users class="w-4 h-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
|
|
||||||
</svg>
|
|
||||||
Gerenciar Participantes
|
Gerenciar Participantes
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@@ -293,9 +263,7 @@
|
|||||||
showAdminMenu = false;
|
showAdminMenu = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4">
|
<Bell class="w-4 h-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
|
|
||||||
</svg>
|
|
||||||
Enviar Notificação
|
Enviar Notificação
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@@ -324,9 +292,7 @@
|
|||||||
})();
|
})();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4">
|
<XCircle class="w-4 h-4" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
|
||||||
</svg>
|
|
||||||
Encerrar Reunião
|
Encerrar Reunião
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@@ -345,19 +311,10 @@
|
|||||||
title="Agendar mensagem"
|
title="Agendar mensagem"
|
||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-purple-500/0 group-hover:bg-purple-500/10 transition-colors duration-300"></div>
|
<div class="absolute inset-0 bg-purple-500/0 group-hover:bg-purple-500/10 transition-colors duration-300"></div>
|
||||||
<svg
|
<Clock
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-5 h-5 text-purple-500 relative z-10 group-hover:scale-110 transition-transform"
|
class="w-5 h-5 text-purple-500 relative z-10 group-hover:scale-110 transition-transform"
|
||||||
>
|
strokeWidth={2}
|
||||||
<circle cx="12" cy="12" r="10"/>
|
/>
|
||||||
<polyline points="12 6 12 12 16 14"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { authStore } from "$lib/stores/auth.svelte";
|
import { authStore } from "$lib/stores/auth.svelte";
|
||||||
|
import { Paperclip, Smile, Send } from "lucide-svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
conversaId: Id<"conversas">;
|
conversaId: Id<"conversas">;
|
||||||
@@ -340,18 +341,10 @@
|
|||||||
<span class="loading loading-spinner loading-sm relative z-10"></span>
|
<span class="loading loading-spinner loading-sm relative z-10"></span>
|
||||||
{:else}
|
{:else}
|
||||||
<!-- Ícone de clipe moderno -->
|
<!-- Ícone de clipe moderno -->
|
||||||
<svg
|
<Paperclip
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-5 h-5 text-primary relative z-10 group-hover:scale-110 transition-transform"
|
class="w-5 h-5 text-primary relative z-10 group-hover:scale-110 transition-transform"
|
||||||
>
|
strokeWidth={2}
|
||||||
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/>
|
/>
|
||||||
</svg>
|
|
||||||
{/if}
|
{/if}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -367,21 +360,10 @@
|
|||||||
title="Adicionar emoji"
|
title="Adicionar emoji"
|
||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-warning/0 group-hover:bg-warning/10 transition-colors duration-300"></div>
|
<div class="absolute inset-0 bg-warning/0 group-hover:bg-warning/10 transition-colors duration-300"></div>
|
||||||
<svg
|
<Smile
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-5 h-5 text-warning relative z-10 group-hover:scale-110 transition-transform"
|
class="w-5 h-5 text-warning relative z-10 group-hover:scale-110 transition-transform"
|
||||||
>
|
strokeWidth={2}
|
||||||
<circle cx="12" cy="12" r="10"/>
|
/>
|
||||||
<path d="M8 14s1.5 2 4 2 4-2 4-2"/>
|
|
||||||
<line x1="9" y1="9" x2="9.01" y2="9"/>
|
|
||||||
<line x1="15" y1="9" x2="15.01" y2="9"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Picker de Emojis -->
|
<!-- Picker de Emojis -->
|
||||||
@@ -458,14 +440,9 @@
|
|||||||
<span class="loading loading-spinner loading-sm relative z-10 text-white"></span>
|
<span class="loading loading-spinner loading-sm relative z-10 text-white"></span>
|
||||||
{:else}
|
{:else}
|
||||||
<!-- Ícone de avião de papel moderno -->
|
<!-- Ícone de avião de papel moderno -->
|
||||||
<svg
|
<Send
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="currentColor"
|
|
||||||
class="w-5 h-5 text-white relative z-10 group-hover:scale-110 group-hover:translate-x-1 transition-all"
|
class="w-5 h-5 text-white relative z-10 group-hover:scale-110 group-hover:translate-x-1 transition-all"
|
||||||
>
|
/>
|
||||||
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z"/>
|
|
||||||
</svg>
|
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import { ptBR } from "date-fns/locale";
|
import { ptBR } from "date-fns/locale";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { authStore } from "$lib/stores/auth.svelte";
|
import { authStore } from "$lib/stores/auth.svelte";
|
||||||
|
import { Bell, Mail, AtSign, Users, Calendar, Clock, BellOff } from "lucide-svelte";
|
||||||
|
|
||||||
// Queries e Client
|
// Queries e Client
|
||||||
const client = useConvexClient();
|
const client = useConvexClient();
|
||||||
@@ -200,22 +201,14 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Ícone do sino PREENCHIDO moderno -->
|
<!-- Ícone do sino PREENCHIDO moderno -->
|
||||||
<svg
|
<Bell
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="currentColor"
|
|
||||||
class="w-7 h-7 text-white relative z-10 transition-all duration-300 group-hover:scale-110"
|
class="w-7 h-7 text-white relative z-10 transition-all duration-300 group-hover:scale-110"
|
||||||
style="filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3)); animation: {count &&
|
style="filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3)); animation: {count &&
|
||||||
count > 0
|
count > 0
|
||||||
? 'bell-ring 2s ease-in-out infinite'
|
? 'bell-ring 2s ease-in-out infinite'
|
||||||
: 'none'};"
|
: 'none'};"
|
||||||
>
|
fill="currentColor"
|
||||||
<path
|
/>
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M5.25 9a6.75 6.75 0 0113.5 0v.75c0 2.123.8 4.057 2.118 5.52a.75.75 0 01-.297 1.206c-1.544.57-3.16.99-4.831 1.243a3.75 3.75 0 11-7.48 0 24.585 24.585 0 01-4.831-1.244.75.75 0 01-.298-1.205A8.217 8.217 0 005.25 9.75V9zm4.502 8.9a2.25 2.25 0 104.496 0 25.057 25.057 0 01-4.496 0z"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<!-- Badge premium MODERNO com gradiente -->
|
<!-- Badge premium MODERNO com gradiente -->
|
||||||
{#if count + (notificacoesFerias?.length || 0) > 0}
|
{#if count + (notificacoesFerias?.length || 0) > 0}
|
||||||
@@ -264,50 +257,11 @@
|
|||||||
<!-- Ícone -->
|
<!-- Ícone -->
|
||||||
<div class="flex-shrink-0 mt-1">
|
<div class="flex-shrink-0 mt-1">
|
||||||
{#if notificacao.tipo === "nova_mensagem"}
|
{#if notificacao.tipo === "nova_mensagem"}
|
||||||
<svg
|
<Mail class="w-5 h-5 text-primary" strokeWidth={1.5} />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-5 h-5 text-primary"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{:else if notificacao.tipo === "mencao"}
|
{:else if notificacao.tipo === "mencao"}
|
||||||
<svg
|
<AtSign class="w-5 h-5 text-warning" strokeWidth={1.5} />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-5 h-5 text-warning"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M16.5 12a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Zm0 0c0 1.657 1.007 3 2.25 3S21 13.657 21 12a9 9 0 1 0-2.636 6.364M16.5 12V8.25"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{:else}
|
{:else}
|
||||||
<svg
|
<Users class="w-5 h-5 text-info" strokeWidth={1.5} />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-5 h-5 text-info"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M18 18.72a9.094 9.094 0 0 0 3.741-.479 3 3 0 0 0-4.682-2.72m.94 3.198.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0 1 12 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 0 1 6 18.719m12 0a5.971 5.971 0 0 0-.941-3.197m0 0A5.995 5.995 0 0 0 12 12.75a5.995 5.995 0 0 0-5.058 2.772m0 0a3 3 0 0 0-4.681 2.72 8.986 8.986 0 0 0 3.74.477m.94-3.197a5.971 5.971 0 0 0-.94 3.197M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -349,20 +303,7 @@
|
|||||||
<div class="flex items-start gap-3">
|
<div class="flex items-start gap-3">
|
||||||
<!-- Ícone -->
|
<!-- Ícone -->
|
||||||
<div class="flex-shrink-0 mt-1">
|
<div class="flex-shrink-0 mt-1">
|
||||||
<svg
|
<Calendar class="w-5 h-5 text-purple-600" strokeWidth={2} />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="w-5 h-5 text-purple-600"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Conteúdo -->
|
<!-- Conteúdo -->
|
||||||
@@ -398,20 +339,7 @@
|
|||||||
<div class="flex items-start gap-3">
|
<div class="flex items-start gap-3">
|
||||||
<!-- Ícone -->
|
<!-- Ícone -->
|
||||||
<div class="flex-shrink-0 mt-1">
|
<div class="flex-shrink-0 mt-1">
|
||||||
<svg
|
<Clock class="w-5 h-5 text-orange-600" strokeWidth={2} />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="w-5 h-5 text-orange-600"
|
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Conteúdo -->
|
<!-- Conteúdo -->
|
||||||
@@ -436,20 +364,7 @@
|
|||||||
<!-- Sem notificações -->
|
<!-- Sem notificações -->
|
||||||
{#if notificacoes.length === 0 && notificacoesFerias.length === 0 && notificacoesAusencias.length === 0}
|
{#if notificacoes.length === 0 && notificacoesFerias.length === 0 && notificacoesAusencias.length === 0}
|
||||||
<div class="px-4 py-8 text-center text-base-content/50">
|
<div class="px-4 py-8 text-center text-base-content/50">
|
||||||
<svg
|
<BellOff class="w-12 h-12 mx-auto mb-2 opacity-50" strokeWidth={1.5} />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-12 h-12 mx-auto mb-2 opacity-50"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M9.143 17.082a24.248 24.248 0 0 0 3.844.148m-3.844-.148a23.856 23.856 0 0 1-5.455-1.31 8.964 8.964 0 0 0 2.3-5.542m3.155 6.852a3 3 0 0 0 5.667 1.97m1.965-2.277L21 21m-4.225-4.225a23.81 23.81 0 0 0 3.536-1.003A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6.53 6.53m10.245 10.245L6.53 6.53M3 3l3.53 3.53"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<p class="text-sm">Nenhuma notificação</p>
|
<p class="text-sm">Nenhuma notificação</p>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,39 +1,42 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
interface Props {
|
import type { Component } from "svelte";
|
||||||
title: string;
|
|
||||||
value: string | number;
|
interface Props {
|
||||||
icon?: string;
|
title: string;
|
||||||
trend?: {
|
value: string | number;
|
||||||
value: number;
|
Icon?: Component;
|
||||||
isPositive: boolean;
|
icon?: string; // Mantido para compatibilidade retroativa
|
||||||
};
|
trend?: {
|
||||||
description?: string;
|
value: number;
|
||||||
color?: "primary" | "secondary" | "accent" | "success" | "warning" | "error";
|
isPositive: boolean;
|
||||||
}
|
};
|
||||||
|
description?: string;
|
||||||
let { title, value, icon, trend, description, color = "primary" }: Props = $props();
|
color?: "primary" | "secondary" | "accent" | "success" | "warning" | "error";
|
||||||
</script>
|
}
|
||||||
|
|
||||||
<div class="stats shadow bg-base-100">
|
let { title, value, Icon, icon, trend, description, color = "primary" }: Props = $props();
|
||||||
<div class="stat">
|
</script>
|
||||||
<div class="stat-figure text-{color}">
|
|
||||||
{#if icon}
|
<div class="stats shadow bg-base-100">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current">
|
<div class="stat">
|
||||||
{@html icon}
|
<div class="stat-figure text-{color}">
|
||||||
</svg>
|
{#if Icon}
|
||||||
{/if}
|
<svelte:component this={Icon} class="inline-block w-8 h-8 stroke-current" strokeWidth={2} />
|
||||||
</div>
|
{:else if icon}
|
||||||
<div class="stat-title">{title}</div>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current">
|
||||||
<div class="stat-value text-{color}">{value}</div>
|
{@html icon}
|
||||||
{#if description}
|
</svg>
|
||||||
<div class="stat-desc">{description}</div>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
{#if trend}
|
<div class="stat-title">{title}</div>
|
||||||
<div class="stat-desc {trend.isPositive ? 'text-success' : 'text-error'}">
|
<div class="stat-value text-{color}">{value}</div>
|
||||||
{trend.isPositive ? '↗︎' : '↘︎'} {Math.abs(trend.value)}%
|
{#if description}
|
||||||
</div>
|
<div class="stat-desc">{description}</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
{#if trend}
|
||||||
</div>
|
<div class="stat-desc {trend.isPositive ? 'text-success' : 'text-error'}">
|
||||||
|
{trend.isPositive ? '↗︎' : '↘︎'} {Math.abs(trend.value)}%
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,48 +1,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
import { ShoppingCart, ShoppingBag, Plus } from "lucide-svelte";
|
||||||
|
</script>
|
||||||
<main class="container mx-auto px-4 py-4">
|
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<ul>
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
<ul>
|
||||||
<li>Compras</li>
|
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
||||||
</ul>
|
<li>Compras</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
<div class="mb-6">
|
|
||||||
<div class="flex items-center gap-4 mb-2">
|
<div class="mb-6">
|
||||||
<div class="p-3 bg-cyan-500/20 rounded-xl">
|
<div class="flex items-center gap-4 mb-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-cyan-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="p-3 bg-cyan-500/20 rounded-xl">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" />
|
<ShoppingCart class="h-8 w-8 text-cyan-600" strokeWidth={2} />
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<h1 class="text-3xl font-bold text-primary">Compras</h1>
|
||||||
<h1 class="text-3xl font-bold text-primary">Compras</h1>
|
<p class="text-base-content/70">Gestão de compras e aquisições</p>
|
||||||
<p class="text-base-content/70">Gestão de compras e aquisições</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
<div class="mb-6">
|
||||||
<div class="mb-6">
|
<ShoppingBag class="h-24 w-24 text-base-content/20" strokeWidth={1.5} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" />
|
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
||||||
</svg>
|
<p class="text-base-content/70 max-w-md mb-6">
|
||||||
</div>
|
O módulo de Compras está sendo desenvolvido e em breve estará disponível com funcionalidades completas para gestão de compras e aquisições.
|
||||||
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
</p>
|
||||||
<p class="text-base-content/70 max-w-md mb-6">
|
<div class="badge badge-warning badge-lg gap-2">
|
||||||
O módulo de Compras está sendo desenvolvido e em breve estará disponível com funcionalidades completas para gestão de compras e aquisições.
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
</p>
|
Em Desenvolvimento
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Em Desenvolvimento
|
</main>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
import { Megaphone, Edit, Plus } from "lucide-svelte";
|
||||||
|
</script>
|
||||||
<main class="container mx-auto px-4 py-4">
|
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<ul>
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
<ul>
|
||||||
<li>Comunicação</li>
|
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
||||||
</ul>
|
<li>Comunicação</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
<div class="mb-6">
|
|
||||||
<div class="flex items-center gap-4 mb-2">
|
<div class="mb-6">
|
||||||
<div class="p-3 bg-pink-500/20 rounded-xl">
|
<div class="flex items-center gap-4 mb-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-pink-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="p-3 bg-pink-500/20 rounded-xl">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5.882V19.24a1.76 1.76 0 01-3.417.592l-2.147-6.15M18 13a3 3 0 100-6M5.436 13.683A4.001 4.001 0 017 6h1.832c4.1 0 7.625-1.234 9.168-3v14c-1.543-1.766-5.067-3-9.168-3H7a3.988 3.988 0 01-1.564-.317z" />
|
<Megaphone class="h-8 w-8 text-pink-600" strokeWidth={2} />
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<h1 class="text-3xl font-bold text-primary">Comunicação</h1>
|
||||||
<h1 class="text-3xl font-bold text-primary">Comunicação</h1>
|
<p class="text-base-content/70">Gestão de comunicação institucional</p>
|
||||||
<p class="text-base-content/70">Gestão de comunicação institucional</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
<div class="mb-6">
|
||||||
<div class="mb-6">
|
<Edit class="h-24 w-24 text-base-content/20" strokeWidth={1.5} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
||||||
</svg>
|
<p class="text-base-content/70 max-w-md mb-6">
|
||||||
</div>
|
O módulo de Comunicação está sendo desenvolvido e em breve estará disponível com funcionalidades completas de gestão de comunicação institucional.
|
||||||
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
</p>
|
||||||
<p class="text-base-content/70 max-w-md mb-6">
|
<div class="badge badge-warning badge-lg gap-2">
|
||||||
O módulo de Comunicação está sendo desenvolvido e em breve estará disponível com funcionalidades completas de gestão de comunicação institucional.
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
</p>
|
Em Desenvolvimento
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Em Desenvolvimento
|
</main>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,99 +1,88 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
import { BarChart3, ClipboardCheck, Plus, CheckCircle2, Clock, TrendingUp } from "lucide-svelte";
|
||||||
|
</script>
|
||||||
<main class="container mx-auto px-4 py-4">
|
|
||||||
<!-- Breadcrumb -->
|
<main class="container mx-auto px-4 py-4">
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<!-- Breadcrumb -->
|
||||||
<ul>
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
<ul>
|
||||||
<li>Controladoria</li>
|
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
||||||
</ul>
|
<li>Controladoria</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
<!-- Cabeçalho -->
|
|
||||||
<div class="mb-6">
|
<!-- Cabeçalho -->
|
||||||
<div class="flex items-center gap-4 mb-2">
|
<div class="mb-6">
|
||||||
<div class="p-3 bg-purple-500/20 rounded-xl">
|
<div class="flex items-center gap-4 mb-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-purple-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="p-3 bg-purple-500/20 rounded-xl">
|
||||||
<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" />
|
<BarChart3 class="h-8 w-8 text-purple-600" strokeWidth={2} />
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<h1 class="text-3xl font-bold text-primary">Controladoria</h1>
|
||||||
<h1 class="text-3xl font-bold text-primary">Controladoria</h1>
|
<p class="text-base-content/70">Controle e auditoria interna da secretaria</p>
|
||||||
<p class="text-base-content/70">Controle e auditoria interna da secretaria</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- Card de Aviso -->
|
||||||
<!-- Card de Aviso -->
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
<div class="mb-6">
|
||||||
<div class="mb-6">
|
<ClipboardCheck class="h-24 w-24 text-base-content/20" strokeWidth={1.5} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" />
|
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
||||||
</svg>
|
<p class="text-base-content/70 max-w-md mb-6">
|
||||||
</div>
|
O módulo de Controladoria está sendo desenvolvido e em breve estará disponível com funcionalidades completas de controle e auditoria.
|
||||||
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
</p>
|
||||||
<p class="text-base-content/70 max-w-md mb-6">
|
<div class="badge badge-warning badge-lg gap-2">
|
||||||
O módulo de Controladoria está sendo desenvolvido e em breve estará disponível com funcionalidades completas de controle e auditoria.
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
</p>
|
Em Desenvolvimento
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Em Desenvolvimento
|
|
||||||
</div>
|
<!-- Funcionalidades Previstas -->
|
||||||
</div>
|
<div class="mt-6">
|
||||||
</div>
|
<h3 class="text-xl font-bold mb-4">Funcionalidades Previstas</h3>
|
||||||
</div>
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
<!-- Funcionalidades Previstas -->
|
<div class="card-body">
|
||||||
<div class="mt-6">
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<h3 class="text-xl font-bold mb-4">Funcionalidades Previstas</h3>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<CheckCircle2 class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
<h4 class="font-semibold">Auditoria Interna</h4>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
<p class="text-sm text-base-content/70">Controle e verificação de processos internos</p>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<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" />
|
</div>
|
||||||
</svg>
|
|
||||||
</div>
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
<h4 class="font-semibold">Auditoria Interna</h4>
|
<div class="card-body">
|
||||||
</div>
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<p class="text-sm text-base-content/70">Controle e verificação de processos internos</p>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
</div>
|
<Clock class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
</div>
|
</div>
|
||||||
|
<h4 class="font-semibold">Compliance</h4>
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
<p class="text-sm text-base-content/70">Conformidade com normas e regulamentos</p>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" 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" />
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
</svg>
|
<div class="card-body">
|
||||||
</div>
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<h4 class="font-semibold">Compliance</h4>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
</div>
|
<TrendingUp class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
<p class="text-sm text-base-content/70">Conformidade com normas e regulamentos</p>
|
</div>
|
||||||
</div>
|
<h4 class="font-semibold">Indicadores de Gestão</h4>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="text-sm text-base-content/70">Monitoramento de KPIs e métricas</p>
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
</div>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</main>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<h4 class="font-semibold">Indicadores de Gestão</h4>
|
|
||||||
</div>
|
|
||||||
<p class="text-sm text-base-content/70">Monitoramento de KPIs e métricas</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,99 +1,88 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
import { DollarSign, Building2, Plus, Calculator, TrendingUp, FileText } from "lucide-svelte";
|
||||||
|
</script>
|
||||||
<main class="container mx-auto px-4 py-4">
|
|
||||||
<!-- Breadcrumb -->
|
<main class="container mx-auto px-4 py-4">
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<!-- Breadcrumb -->
|
||||||
<ul>
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
<ul>
|
||||||
<li>Financeiro</li>
|
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
||||||
</ul>
|
<li>Financeiro</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
<!-- Cabeçalho -->
|
|
||||||
<div class="mb-6">
|
<!-- Cabeçalho -->
|
||||||
<div class="flex items-center gap-4 mb-2">
|
<div class="mb-6">
|
||||||
<div class="p-3 bg-green-500/20 rounded-xl">
|
<div class="flex items-center gap-4 mb-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-green-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="p-3 bg-green-500/20 rounded-xl">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<DollarSign class="h-8 w-8 text-green-600" strokeWidth={2} />
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<h1 class="text-3xl font-bold text-primary">Financeiro</h1>
|
||||||
<h1 class="text-3xl font-bold text-primary">Financeiro</h1>
|
<p class="text-base-content/70">Gestão financeira e orçamentária da secretaria</p>
|
||||||
<p class="text-base-content/70">Gestão financeira e orçamentária da secretaria</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- Card de Aviso -->
|
||||||
<!-- Card de Aviso -->
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
<div class="mb-6">
|
||||||
<div class="mb-6">
|
<Building2 class="h-24 w-24 text-base-content/20" strokeWidth={1.5} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" 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" />
|
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
||||||
</svg>
|
<p class="text-base-content/70 max-w-md mb-6">
|
||||||
</div>
|
O módulo Financeiro está sendo desenvolvido e em breve estará disponível com funcionalidades completas de gestão financeira e orçamentária.
|
||||||
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
</p>
|
||||||
<p class="text-base-content/70 max-w-md mb-6">
|
<div class="badge badge-warning badge-lg gap-2">
|
||||||
O módulo Financeiro está sendo desenvolvido e em breve estará disponível com funcionalidades completas de gestão financeira e orçamentária.
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
</p>
|
Em Desenvolvimento
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Em Desenvolvimento
|
|
||||||
</div>
|
<!-- Funcionalidades Previstas -->
|
||||||
</div>
|
<div class="mt-6">
|
||||||
</div>
|
<h3 class="text-xl font-bold mb-4">Funcionalidades Previstas</h3>
|
||||||
</div>
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
<!-- Funcionalidades Previstas -->
|
<div class="card-body">
|
||||||
<div class="mt-6">
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<h3 class="text-xl font-bold mb-4">Funcionalidades Previstas</h3>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<Calculator class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
<h4 class="font-semibold">Controle Orçamentário</h4>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
<p class="text-sm text-base-content/70">Gestão e acompanhamento do orçamento anual</p>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
</div>
|
||||||
</svg>
|
|
||||||
</div>
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
<h4 class="font-semibold">Controle Orçamentário</h4>
|
<div class="card-body">
|
||||||
</div>
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<p class="text-sm text-base-content/70">Gestão e acompanhamento do orçamento anual</p>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
</div>
|
<TrendingUp class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
</div>
|
</div>
|
||||||
|
<h4 class="font-semibold">Fluxo de Caixa</h4>
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
<p class="text-sm text-base-content/70">Controle de entradas e saídas financeiras</p>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z" />
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
</svg>
|
<div class="card-body">
|
||||||
</div>
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<h4 class="font-semibold">Fluxo de Caixa</h4>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
</div>
|
<FileText class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
<p class="text-sm text-base-content/70">Controle de entradas e saídas financeiras</p>
|
</div>
|
||||||
</div>
|
<h4 class="font-semibold">Relatórios Financeiros</h4>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="text-sm text-base-content/70">Geração de relatórios e demonstrativos</p>
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
</div>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</main>
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<h4 class="font-semibold">Relatórios Financeiros</h4>
|
|
||||||
</div>
|
|
||||||
<p class="text-sm text-base-content/70">Geração de relatórios e demonstrativos</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
import { Scale, BookOpen, Plus } from "lucide-svelte";
|
||||||
|
</script>
|
||||||
<main class="container mx-auto px-4 py-4">
|
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<ul>
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
<ul>
|
||||||
<li>Jurídico</li>
|
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
||||||
</ul>
|
<li>Jurídico</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
<div class="mb-6">
|
|
||||||
<div class="flex items-center gap-4 mb-2">
|
<div class="mb-6">
|
||||||
<div class="p-3 bg-red-500/20 rounded-xl">
|
<div class="flex items-center gap-4 mb-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="p-3 bg-red-500/20 rounded-xl">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3" />
|
<Scale class="h-8 w-8 text-red-600" strokeWidth={2} />
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<h1 class="text-3xl font-bold text-primary">Jurídico</h1>
|
||||||
<h1 class="text-3xl font-bold text-primary">Jurídico</h1>
|
<p class="text-base-content/70">Assessoria jurídica e gestão de processos</p>
|
||||||
<p class="text-base-content/70">Assessoria jurídica e gestão de processos</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
<div class="mb-6">
|
||||||
<div class="mb-6">
|
<BookOpen class="h-24 w-24 text-base-content/20" strokeWidth={1.5} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
||||||
</svg>
|
<p class="text-base-content/70 max-w-md mb-6">
|
||||||
</div>
|
O módulo Jurídico está sendo desenvolvido e em breve estará disponível com funcionalidades completas de assessoria jurídica e gestão de processos.
|
||||||
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
</p>
|
||||||
<p class="text-base-content/70 max-w-md mb-6">
|
<div class="badge badge-warning badge-lg gap-2">
|
||||||
O módulo Jurídico está sendo desenvolvido e em breve estará disponível com funcionalidades completas de assessoria jurídica e gestão de processos.
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
</p>
|
Em Desenvolvimento
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Em Desenvolvimento
|
</main>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,99 +1,88 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
import { FileText, ClipboardCopy, Plus, Users, FileDoc } from "lucide-svelte";
|
||||||
|
</script>
|
||||||
<main class="container mx-auto px-4 py-4">
|
|
||||||
<!-- Breadcrumb -->
|
<main class="container mx-auto px-4 py-4">
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<!-- Breadcrumb -->
|
||||||
<ul>
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
<ul>
|
||||||
<li>Licitações</li>
|
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
||||||
</ul>
|
<li>Licitações</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
<!-- Cabeçalho -->
|
|
||||||
<div class="mb-6">
|
<!-- Cabeçalho -->
|
||||||
<div class="flex items-center gap-4 mb-2">
|
<div class="mb-6">
|
||||||
<div class="p-3 bg-orange-500/20 rounded-xl">
|
<div class="flex items-center gap-4 mb-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-orange-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="p-3 bg-orange-500/20 rounded-xl">
|
||||||
<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" />
|
<FileText class="h-8 w-8 text-orange-600" strokeWidth={2} />
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<h1 class="text-3xl font-bold text-primary">Licitações</h1>
|
||||||
<h1 class="text-3xl font-bold text-primary">Licitações</h1>
|
<p class="text-base-content/70">Gestão de processos licitatórios</p>
|
||||||
<p class="text-base-content/70">Gestão de processos licitatórios</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- Card de Aviso -->
|
||||||
<!-- Card de Aviso -->
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
<div class="mb-6">
|
||||||
<div class="mb-6">
|
<FileDoc class="h-24 w-24 text-base-content/20" strokeWidth={1.5} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" 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" />
|
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
||||||
</svg>
|
<p class="text-base-content/70 max-w-md mb-6">
|
||||||
</div>
|
O módulo de Licitações está sendo desenvolvido e em breve estará disponível com funcionalidades completas para gestão de processos licitatórios.
|
||||||
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
</p>
|
||||||
<p class="text-base-content/70 max-w-md mb-6">
|
<div class="badge badge-warning badge-lg gap-2">
|
||||||
O módulo de Licitações está sendo desenvolvido e em breve estará disponível com funcionalidades completas para gestão de processos licitatórios.
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
</p>
|
Em Desenvolvimento
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Em Desenvolvimento
|
|
||||||
</div>
|
<!-- Funcionalidades Previstas -->
|
||||||
</div>
|
<div class="mt-6">
|
||||||
</div>
|
<h3 class="text-xl font-bold mb-4">Funcionalidades Previstas</h3>
|
||||||
</div>
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
<!-- Funcionalidades Previstas -->
|
<div class="card-body">
|
||||||
<div class="mt-6">
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<h3 class="text-xl font-bold mb-4">Funcionalidades Previstas</h3>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<ClipboardCopy class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
<h4 class="font-semibold">Processos Licitatórios</h4>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
<p class="text-sm text-base-content/70">Cadastro e acompanhamento de licitações</p>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
</div>
|
||||||
</svg>
|
|
||||||
</div>
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
<h4 class="font-semibold">Processos Licitatórios</h4>
|
<div class="card-body">
|
||||||
</div>
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<p class="text-sm text-base-content/70">Cadastro e acompanhamento de licitações</p>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
</div>
|
<Users class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
</div>
|
</div>
|
||||||
|
<h4 class="font-semibold">Fornecedores</h4>
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
<p class="text-sm text-base-content/70">Cadastro e gestão de fornecedores</p>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" 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" />
|
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
||||||
</svg>
|
<div class="card-body">
|
||||||
</div>
|
<div class="flex items-center gap-3 mb-2">
|
||||||
<h4 class="font-semibold">Fornecedores</h4>
|
<div class="p-2 bg-primary/10 rounded-lg">
|
||||||
</div>
|
<FileDoc class="h-6 w-6 text-primary" strokeWidth={2} />
|
||||||
<p class="text-sm text-base-content/70">Cadastro e gestão de fornecedores</p>
|
</div>
|
||||||
</div>
|
<h4 class="font-semibold">Documentação</h4>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="text-sm text-base-content/70">Gestão de documentos e editais</p>
|
||||||
<div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow">
|
</div>
|
||||||
<div class="card-body">
|
</div>
|
||||||
<div class="flex items-center gap-3 mb-2">
|
</div>
|
||||||
<div class="p-2 bg-primary/10 rounded-lg">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</main>
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<h4 class="font-semibold">Documentação</h4>
|
|
||||||
</div>
|
|
||||||
<p class="text-sm text-base-content/70">Gestão de documentos e editais</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
import { Trophy, Award, Plus } from "lucide-svelte";
|
||||||
|
</script>
|
||||||
<main class="container mx-auto px-4 py-4">
|
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<ul>
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
<ul>
|
||||||
<li>Programas Esportivos</li>
|
<li><a href="/" class="text-primary hover:underline">Dashboard</a></li>
|
||||||
</ul>
|
<li>Programas Esportivos</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
<div class="mb-6">
|
|
||||||
<div class="flex items-center gap-4 mb-2">
|
<div class="mb-6">
|
||||||
<div class="p-3 bg-yellow-500/20 rounded-xl">
|
<div class="flex items-center gap-4 mb-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-yellow-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="p-3 bg-yellow-500/20 rounded-xl">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<Trophy class="h-8 w-8 text-yellow-600" strokeWidth={2} />
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<h1 class="text-3xl font-bold text-primary">Programas Esportivos</h1>
|
||||||
<h1 class="text-3xl font-bold text-primary">Programas Esportivos</h1>
|
<p class="text-base-content/70">Gestão de programas e projetos esportivos</p>
|
||||||
<p class="text-base-content/70">Gestão de programas e projetos esportivos</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="card bg-base-100 shadow-xl">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
<div class="mb-6">
|
||||||
<div class="mb-6">
|
<Award class="h-24 w-24 text-base-content/20" strokeWidth={1.5} />
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/20" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" />
|
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
||||||
</svg>
|
<p class="text-base-content/70 max-w-md mb-6">
|
||||||
</div>
|
O módulo de Programas Esportivos está sendo desenvolvido e em breve estará disponível com funcionalidades completas para gestão de programas e projetos esportivos.
|
||||||
<h2 class="text-2xl font-bold mb-2">Módulo em Desenvolvimento</h2>
|
</p>
|
||||||
<p class="text-base-content/70 max-w-md mb-6">
|
<div class="badge badge-warning badge-lg gap-2">
|
||||||
O módulo de Programas Esportivos está sendo desenvolvido e em breve estará disponível com funcionalidades completas para gestão de programas e projetos esportivos.
|
<Plus class="h-4 w-4" strokeWidth={2} />
|
||||||
</p>
|
Em Desenvolvimento
|
||||||
<div class="badge badge-warning badge-lg gap-2">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
</div>
|
||||||
</svg>
|
</div>
|
||||||
Em Desenvolvimento
|
</main>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,281 +1,253 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { useQuery } from "convex-svelte";
|
import { useQuery } from "convex-svelte";
|
||||||
import { api } from "@sgse-app/backend/convex/_generated/api";
|
import { api } from "@sgse-app/backend/convex/_generated/api";
|
||||||
|
import { Users, UserPlus, ClipboardList, Trash2, BarChart3, Calendar, FileText, BadgeCheck, Plus, List, ChevronRight, CheckCircle2, Info, ArrowRight } from "lucide-svelte";
|
||||||
// Buscar estatísticas para exibir nos cards
|
import type { Component } from "svelte";
|
||||||
const statsQuery = useQuery(api.dashboard.getStats, {});
|
|
||||||
|
// Buscar estatísticas para exibir nos cards
|
||||||
const menuItems = [
|
const statsQuery = useQuery(api.dashboard.getStats, {});
|
||||||
{
|
|
||||||
categoria: "Gestão de Funcionários",
|
interface MenuOpcao {
|
||||||
descricao: "Gerencie o cadastro e informações dos funcionários",
|
nome: string;
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
descricao: string;
|
||||||
<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" />
|
href: string;
|
||||||
</svg>`,
|
Icon: Component;
|
||||||
gradient: "from-blue-500/10 to-blue-600/20",
|
}
|
||||||
accentColor: "text-blue-600",
|
|
||||||
bgIcon: "bg-blue-500/20",
|
interface MenuCategoria {
|
||||||
opcoes: [
|
categoria: string;
|
||||||
{
|
descricao: string;
|
||||||
nome: "Cadastrar Funcionário",
|
Icon: Component;
|
||||||
descricao: "Adicionar novo funcionário ao sistema",
|
gradient: string;
|
||||||
href: "/recursos-humanos/funcionarios/cadastro",
|
accentColor: string;
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
bgIcon: string;
|
||||||
<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" />
|
opcoes: MenuOpcao[];
|
||||||
</svg>`,
|
}
|
||||||
},
|
|
||||||
{
|
const menuItems: MenuCategoria[] = [
|
||||||
nome: "Listar Funcionários",
|
{
|
||||||
descricao: "Visualizar e editar cadastros",
|
categoria: "Gestão de Funcionários",
|
||||||
href: "/recursos-humanos/funcionarios",
|
descricao: "Gerencie o cadastro e informações dos funcionários",
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
Icon: Users,
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" />
|
gradient: "from-blue-500/10 to-blue-600/20",
|
||||||
</svg>`,
|
accentColor: "text-blue-600",
|
||||||
},
|
bgIcon: "bg-blue-500/20",
|
||||||
{
|
opcoes: [
|
||||||
nome: "Excluir Cadastro",
|
{
|
||||||
descricao: "Remover funcionário do sistema",
|
nome: "Cadastrar Funcionário",
|
||||||
href: "/recursos-humanos/funcionarios/excluir",
|
descricao: "Adicionar novo funcionário ao sistema",
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
href: "/recursos-humanos/funcionarios/cadastro",
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
Icon: UserPlus,
|
||||||
</svg>`,
|
},
|
||||||
},
|
{
|
||||||
{
|
nome: "Listar Funcionários",
|
||||||
nome: "Relatórios",
|
descricao: "Visualizar e editar cadastros",
|
||||||
descricao: "Visualizar estatísticas e gráficos",
|
href: "/recursos-humanos/funcionarios",
|
||||||
href: "/recursos-humanos/funcionarios/relatorios",
|
Icon: ClipboardList,
|
||||||
icon: `<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 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>`,
|
nome: "Excluir Cadastro",
|
||||||
},
|
descricao: "Remover funcionário do sistema",
|
||||||
],
|
href: "/recursos-humanos/funcionarios/excluir",
|
||||||
},
|
Icon: Trash2,
|
||||||
{
|
},
|
||||||
categoria: "Gestão de Férias e Licenças",
|
{
|
||||||
descricao: "Controle de férias, atestados e licenças",
|
nome: "Relatórios",
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
descricao: "Visualizar estatísticas e gráficos",
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
href: "/recursos-humanos/funcionarios/relatorios",
|
||||||
</svg>`,
|
Icon: BarChart3,
|
||||||
gradient: "from-purple-500/10 to-purple-600/20",
|
},
|
||||||
accentColor: "text-purple-600",
|
],
|
||||||
bgIcon: "bg-purple-500/20",
|
},
|
||||||
opcoes: [
|
{
|
||||||
{
|
categoria: "Gestão de Férias e Licenças",
|
||||||
nome: "Gestão de Férias",
|
descricao: "Controle de férias, atestados e licenças",
|
||||||
descricao: "Controlar períodos de férias",
|
Icon: Calendar,
|
||||||
href: "/recursos-humanos/ferias",
|
gradient: "from-purple-500/10 to-purple-600/20",
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
accentColor: "text-purple-600",
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
bgIcon: "bg-purple-500/20",
|
||||||
</svg>`,
|
opcoes: [
|
||||||
},
|
{
|
||||||
{
|
nome: "Gestão de Férias",
|
||||||
nome: "Atestados & Licenças",
|
descricao: "Controlar períodos de férias",
|
||||||
descricao: "Registrar atestados e licenças",
|
href: "/recursos-humanos/ferias",
|
||||||
href: "/recursos-humanos/atestados-licencas",
|
Icon: Calendar,
|
||||||
icon: `<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>`,
|
nome: "Atestados & Licenças",
|
||||||
},
|
descricao: "Registrar atestados e licenças",
|
||||||
],
|
href: "/recursos-humanos/atestados-licencas",
|
||||||
},
|
Icon: FileText,
|
||||||
{
|
},
|
||||||
categoria: "Gestão de Símbolos",
|
],
|
||||||
descricao: "Gerencie cargos comissionados e funções gratificadas",
|
},
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" 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" />
|
categoria: "Gestão de Símbolos",
|
||||||
</svg>`,
|
descricao: "Gerencie cargos comissionados e funções gratificadas",
|
||||||
gradient: "from-green-500/10 to-green-600/20",
|
Icon: BadgeCheck,
|
||||||
accentColor: "text-green-600",
|
gradient: "from-green-500/10 to-green-600/20",
|
||||||
bgIcon: "bg-green-500/20",
|
accentColor: "text-green-600",
|
||||||
opcoes: [
|
bgIcon: "bg-green-500/20",
|
||||||
{
|
opcoes: [
|
||||||
nome: "Cadastrar Símbolo",
|
{
|
||||||
descricao: "Adicionar novo cargo ou função",
|
nome: "Cadastrar Símbolo",
|
||||||
href: "/recursos-humanos/simbolos/cadastro",
|
descricao: "Adicionar novo cargo ou função",
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
href: "/recursos-humanos/simbolos/cadastro",
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
Icon: Plus,
|
||||||
</svg>`,
|
},
|
||||||
},
|
{
|
||||||
{
|
nome: "Listar Símbolos",
|
||||||
nome: "Listar Símbolos",
|
descricao: "Visualizar e editar símbolos",
|
||||||
descricao: "Visualizar e editar símbolos",
|
href: "/recursos-humanos/simbolos",
|
||||||
href: "/recursos-humanos/simbolos",
|
Icon: List,
|
||||||
icon: `<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="M4 6h16M4 10h16M4 14h16M4 18h16" />
|
],
|
||||||
</svg>`,
|
},
|
||||||
},
|
];
|
||||||
],
|
</script>
|
||||||
},
|
|
||||||
];
|
<main class="container mx-auto px-4 py-4">
|
||||||
</script>
|
<!-- Cabeçalho -->
|
||||||
|
<div class="mb-8">
|
||||||
<main class="container mx-auto px-4 py-4">
|
<h1 class="text-4xl font-bold text-primary mb-2">Recursos Humanos</h1>
|
||||||
<!-- Cabeçalho -->
|
<p class="text-lg text-base-content/70">
|
||||||
<div class="mb-8">
|
Gerencie funcionários, símbolos e visualize relatórios do departamento
|
||||||
<h1 class="text-4xl font-bold text-primary mb-2">Recursos Humanos</h1>
|
</p>
|
||||||
<p class="text-lg text-base-content/70">
|
</div>
|
||||||
Gerencie funcionários, símbolos e visualize relatórios do departamento
|
|
||||||
</p>
|
<!-- Estatísticas Rápidas -->
|
||||||
</div>
|
{#if statsQuery.data}
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
|
||||||
<!-- Estatísticas Rápidas -->
|
<div class="stats shadow-lg bg-gradient-to-br from-primary/10 to-primary/20">
|
||||||
{#if statsQuery.data}
|
<div class="stat">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
|
<div class="stat-figure text-primary">
|
||||||
<div class="stats shadow-lg bg-gradient-to-br from-primary/10 to-primary/20">
|
<Users class="h-8 w-8" strokeWidth={2} />
|
||||||
<div class="stat">
|
</div>
|
||||||
<div class="stat-figure text-primary">
|
<div class="stat-title">Total</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<div class="stat-value text-primary">{statsQuery.data.totalFuncionarios}</div>
|
||||||
<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" />
|
<div class="stat-desc">Funcionários cadastrados</div>
|
||||||
</svg>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-title">Total</div>
|
|
||||||
<div class="stat-value text-primary">{statsQuery.data.totalFuncionarios}</div>
|
<div class="stats shadow-lg bg-gradient-to-br from-success/10 to-success/20">
|
||||||
<div class="stat-desc">Funcionários cadastrados</div>
|
<div class="stat">
|
||||||
</div>
|
<div class="stat-figure text-success">
|
||||||
</div>
|
<CheckCircle2 class="h-8 w-8" strokeWidth={2} />
|
||||||
|
</div>
|
||||||
<div class="stats shadow-lg bg-gradient-to-br from-success/10 to-success/20">
|
<div class="stat-title">Ativos</div>
|
||||||
<div class="stat">
|
<div class="stat-value text-success">{statsQuery.data.funcionariosAtivos}</div>
|
||||||
<div class="stat-figure text-success">
|
<div class="stat-desc">Funcionários ativos</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
</div>
|
||||||
<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" />
|
</div>
|
||||||
</svg>
|
|
||||||
</div>
|
<div class="stats shadow-lg bg-gradient-to-br from-secondary/10 to-secondary/20">
|
||||||
<div class="stat-title">Ativos</div>
|
<div class="stat">
|
||||||
<div class="stat-value text-success">{statsQuery.data.funcionariosAtivos}</div>
|
<div class="stat-figure text-secondary">
|
||||||
<div class="stat-desc">Funcionários ativos</div>
|
<BadgeCheck class="h-8 w-8" strokeWidth={2} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="stat-title">Símbolos</div>
|
||||||
|
<div class="stat-value text-secondary">{statsQuery.data.totalSimbolos}</div>
|
||||||
<div class="stats shadow-lg bg-gradient-to-br from-secondary/10 to-secondary/20">
|
<div class="stat-desc">Cargos e funções</div>
|
||||||
<div class="stat">
|
</div>
|
||||||
<div class="stat-figure text-secondary">
|
</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="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" />
|
<div class="stats shadow-lg bg-gradient-to-br from-accent/10 to-accent/20">
|
||||||
</svg>
|
<div class="stat">
|
||||||
</div>
|
<div class="stat-figure text-accent">
|
||||||
<div class="stat-title">Símbolos</div>
|
<BarChart3 class="h-8 w-8" strokeWidth={2} />
|
||||||
<div class="stat-value text-secondary">{statsQuery.data.totalSimbolos}</div>
|
</div>
|
||||||
<div class="stat-desc">Cargos e funções</div>
|
<div class="stat-title">CC / FG</div>
|
||||||
</div>
|
<div class="stat-value text-accent">{statsQuery.data.cargoComissionado} / {statsQuery.data.funcaoGratificada}</div>
|
||||||
</div>
|
<div class="stat-desc">Distribuição</div>
|
||||||
|
</div>
|
||||||
<div class="stats shadow-lg bg-gradient-to-br from-accent/10 to-accent/20">
|
</div>
|
||||||
<div class="stat">
|
</div>
|
||||||
<div class="stat-figure text-accent">
|
{/if}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="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 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" />
|
<!-- Menu de Opções -->
|
||||||
</svg>
|
<div class="space-y-8">
|
||||||
</div>
|
{#each menuItems as categoria}
|
||||||
<div class="stat-title">CC / FG</div>
|
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-all duration-300">
|
||||||
<div class="stat-value text-accent">{statsQuery.data.cargoComissionado} / {statsQuery.data.funcaoGratificada}</div>
|
<div class="card-body">
|
||||||
<div class="stat-desc">Distribuição</div>
|
<!-- Cabeçalho da Categoria -->
|
||||||
</div>
|
<div class="flex items-start gap-6 mb-6">
|
||||||
</div>
|
<div class="p-4 {categoria.bgIcon} rounded-2xl">
|
||||||
</div>
|
<svelte:component this={categoria.Icon} class="h-12 w-12 {categoria.accentColor}" strokeWidth={2} />
|
||||||
{/if}
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
<!-- Menu de Opções -->
|
<h2 class="card-title text-2xl mb-2 {categoria.accentColor}">
|
||||||
<div class="space-y-8">
|
{categoria.categoria}
|
||||||
{#each menuItems as categoria}
|
</h2>
|
||||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-all duration-300">
|
<p class="text-base-content/70">{categoria.descricao}</p>
|
||||||
<div class="card-body">
|
</div>
|
||||||
<!-- Cabeçalho da Categoria -->
|
</div>
|
||||||
<div class="flex items-start gap-6 mb-6">
|
|
||||||
<div class="p-4 {categoria.bgIcon} rounded-2xl">
|
<!-- Grid de Opções -->
|
||||||
<div class="{categoria.accentColor}">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
{@html categoria.icon}
|
{#each categoria.opcoes as opcao}
|
||||||
</div>
|
<a
|
||||||
</div>
|
href={opcao.href}
|
||||||
<div class="flex-1">
|
class="group relative overflow-hidden rounded-xl border-2 border-base-300 bg-gradient-to-br {categoria.gradient} p-6 hover:border-primary hover:shadow-lg transition-all duration-300 transform hover:-translate-y-1"
|
||||||
<h2 class="card-title text-2xl mb-2 {categoria.accentColor}">
|
>
|
||||||
{categoria.categoria}
|
<div class="flex flex-col h-full">
|
||||||
</h2>
|
<div class="flex items-start justify-between mb-4">
|
||||||
<p class="text-base-content/70">{categoria.descricao}</p>
|
<div class="p-3 bg-base-100 rounded-lg group-hover:bg-primary group-hover:text-white transition-colors duration-300">
|
||||||
</div>
|
<svelte:component
|
||||||
</div>
|
this={opcao.Icon}
|
||||||
|
class="h-5 w-5 {categoria.accentColor} group-hover:text-white transition-colors duration-300"
|
||||||
<!-- Grid de Opções -->
|
strokeWidth={2}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
/>
|
||||||
{#each categoria.opcoes as opcao}
|
</div>
|
||||||
<a
|
<ChevronRight
|
||||||
href={opcao.href}
|
class="h-5 w-5 text-base-content/30 group-hover:text-primary transition-colors duration-300"
|
||||||
class="group relative overflow-hidden rounded-xl border-2 border-base-300 bg-gradient-to-br {categoria.gradient} p-6 hover:border-primary hover:shadow-lg transition-all duration-300 transform hover:-translate-y-1"
|
strokeWidth={2}
|
||||||
>
|
/>
|
||||||
<div class="flex flex-col h-full">
|
</div>
|
||||||
<div class="flex items-start justify-between mb-4">
|
<h3 class="text-lg font-bold text-base-content mb-2 group-hover:text-primary transition-colors duration-300">
|
||||||
<div class="p-3 bg-base-100 rounded-lg group-hover:bg-primary group-hover:text-white transition-colors duration-300">
|
{opcao.nome}
|
||||||
<div class="{categoria.accentColor} group-hover:text-white">
|
</h3>
|
||||||
{@html opcao.icon}
|
<p class="text-sm text-base-content/70 flex-1">
|
||||||
</div>
|
{opcao.descricao}
|
||||||
</div>
|
</p>
|
||||||
<svg
|
</div>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
</a>
|
||||||
class="h-5 w-5 text-base-content/30 group-hover:text-primary transition-colors duration-300"
|
{/each}
|
||||||
fill="none"
|
</div>
|
||||||
viewBox="0 0 24 24"
|
</div>
|
||||||
stroke="currentColor"
|
</div>
|
||||||
>
|
{/each}
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
</div>
|
||||||
</svg>
|
|
||||||
</div>
|
<!-- Card de Ajuda -->
|
||||||
<h3 class="text-lg font-bold text-base-content mb-2 group-hover:text-primary transition-colors duration-300">
|
<div class="alert alert-info shadow-lg mt-8">
|
||||||
{opcao.nome}
|
<Info class="stroke-current shrink-0 w-6 h-6" strokeWidth={2} />
|
||||||
</h3>
|
<div>
|
||||||
<p class="text-sm text-base-content/70 flex-1">
|
<h3 class="font-bold">Precisa de ajuda?</h3>
|
||||||
{opcao.descricao}
|
<div class="text-sm">
|
||||||
</p>
|
Entre em contato com o suporte técnico ou consulte a documentação do sistema para mais informações sobre as funcionalidades de Recursos Humanos.
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</div>
|
||||||
{/each}
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</div>
|
|
||||||
</div>
|
<style>
|
||||||
{/each}
|
@keyframes fadeInUp {
|
||||||
</div>
|
from {
|
||||||
|
opacity: 0;
|
||||||
<!-- Card de Ajuda -->
|
transform: translateY(20px);
|
||||||
<div class="alert alert-info shadow-lg mt-8">
|
}
|
||||||
<svg
|
to {
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
opacity: 1;
|
||||||
fill="none"
|
transform: translateY(0);
|
||||||
viewBox="0 0 24 24"
|
}
|
||||||
class="stroke-current shrink-0 w-6 h-6"
|
}
|
||||||
>
|
|
||||||
<path
|
.card {
|
||||||
stroke-linecap="round"
|
animation: fadeInUp 0.5s ease-out;
|
||||||
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"
|
.stats {
|
||||||
></path>
|
animation: fadeInUp 0.6s ease-out;
|
||||||
</svg>
|
}
|
||||||
<div>
|
</style>
|
||||||
<h3 class="font-bold">Precisa de ajuda?</h3>
|
|
||||||
<div class="text-sm">
|
|
||||||
Entre em contato com o suporte técnico ou consulte a documentação do sistema para mais informações sobre as funcionalidades de Recursos Humanos.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@keyframes fadeInUp {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(20px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
animation: fadeInUp 0.5s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats {
|
|
||||||
animation: fadeInUp 0.6s ease-out;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { useQuery, useConvexClient } from "convex-svelte";
|
import { useQuery, useConvexClient } from "convex-svelte";
|
||||||
import { api } from "@sgse-app/backend/convex/_generated/api";
|
import { api } from "@sgse-app/backend/convex/_generated/api";
|
||||||
import StatsCard from "$lib/components/ti/StatsCard.svelte";
|
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 client = useConvexClient();
|
||||||
const usuariosQuery = useQuery(api.usuarios.listar, {});
|
const usuariosQuery = useQuery(api.usuarios.listar, {});
|
||||||
@@ -45,9 +46,7 @@
|
|||||||
<div class="flex items-center justify-between mb-8">
|
<div class="flex items-center justify-between mb-8">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<div class="p-3 bg-primary/10 rounded-xl">
|
<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">
|
<BarChart3 class="h-8 w-8 text-primary" strokeWidth={2} />
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-bold text-base-content">Dashboard Administrativo TI</h1>
|
<h1 class="text-3xl font-bold text-base-content">Dashboard Administrativo TI</h1>
|
||||||
@@ -62,7 +61,7 @@
|
|||||||
<StatsCard
|
<StatsCard
|
||||||
title="Total de Usuários"
|
title="Total de Usuários"
|
||||||
value={stats.total}
|
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"
|
color="primary"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -70,7 +69,7 @@
|
|||||||
title="Usuários Ativos"
|
title="Usuários Ativos"
|
||||||
value={stats.ativos}
|
value={stats.ativos}
|
||||||
description="{stats.total > 0 ? ((stats.ativos / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
|
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"
|
color="success"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -78,7 +77,7 @@
|
|||||||
title="Usuários Bloqueados"
|
title="Usuários Bloqueados"
|
||||||
value={stats.bloqueados}
|
value={stats.bloqueados}
|
||||||
description="Requerem atenção"
|
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"
|
color="error"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -86,7 +85,7 @@
|
|||||||
title="Usuários Inativos"
|
title="Usuários Inativos"
|
||||||
value={stats.inativos}
|
value={stats.inativos}
|
||||||
description="Desativados"
|
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"
|
color="warning"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -102,23 +101,17 @@
|
|||||||
<h2 class="card-title text-2xl mb-4">Ações Rápidas</h2>
|
<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">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
<a href="/ti/usuarios" class="btn btn-primary">
|
<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">
|
<Plus class="h-5 w-5" strokeWidth={2} />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
|
||||||
</svg>
|
|
||||||
Criar Usuário
|
Criar Usuário
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/ti/perfis" class="btn btn-secondary">
|
<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">
|
<Layers class="h-5 w-5" strokeWidth={2} />
|
||||||
<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>
|
|
||||||
Gerenciar Perfis
|
Gerenciar Perfis
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/ti/auditoria" class="btn btn-accent">
|
<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">
|
<FileText class="h-5 w-5" strokeWidth={2} />
|
||||||
<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>
|
|
||||||
Ver Logs
|
Ver Logs
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -127,9 +120,7 @@
|
|||||||
|
|
||||||
<!-- Informação Sistema -->
|
<!-- Informação Sistema -->
|
||||||
<div class="alert alert-info">
|
<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">
|
<Info class="stroke-current shrink-0 w-6 h-6" strokeWidth={2} />
|
||||||
<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>
|
|
||||||
<span>Sistema de Gestão da Secretaria de Esportes - Versão 2.0 com controle avançado de acesso</span>
|
<span>Sistema de Gestão da Secretaria de Esportes - Versão 2.0 com controle avançado de acesso</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { ptBR } from "date-fns/locale";
|
import { ptBR } from "date-fns/locale";
|
||||||
|
import { Users, Shield, AlertTriangle, Info, Building2 } from "lucide-svelte";
|
||||||
|
|
||||||
type Role = {
|
type Role = {
|
||||||
_id: Id<"roles">;
|
_id: Id<"roles">;
|
||||||
@@ -174,35 +175,35 @@
|
|||||||
<StatsCard
|
<StatsCard
|
||||||
title="Total de Perfis"
|
title="Total de Perfis"
|
||||||
value={stats.total}
|
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"
|
color="primary"
|
||||||
/>
|
/>
|
||||||
<StatsCard
|
<StatsCard
|
||||||
title="Nível Máximo"
|
title="Nível Máximo"
|
||||||
value={stats.nivelMaximo}
|
value={stats.nivelMaximo}
|
||||||
description="Acesso total"
|
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"
|
color="error"
|
||||||
/>
|
/>
|
||||||
<StatsCard
|
<StatsCard
|
||||||
title="Nível Alto"
|
title="Nível Alto"
|
||||||
value={stats.nivelAlto}
|
value={stats.nivelAlto}
|
||||||
description="Acesso elevado"
|
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"
|
color="warning"
|
||||||
/>
|
/>
|
||||||
<StatsCard
|
<StatsCard
|
||||||
title="Nível Médio"
|
title="Nível Médio"
|
||||||
value={stats.nivelMedio}
|
value={stats.nivelMedio}
|
||||||
description="Acesso padrão"
|
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"
|
color="info"
|
||||||
/>
|
/>
|
||||||
<StatsCard
|
<StatsCard
|
||||||
title="Com Setor"
|
title="Com Setor"
|
||||||
value={stats.comSetor}
|
value={stats.comSetor}
|
||||||
description="{stats.total > 0 ? ((stats.comSetor / stats.total) * 100).toFixed(0) + '% do total' : '0%'}"
|
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"
|
color="secondary"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import StatsCard from "$lib/components/ti/StatsCard.svelte";
|
import StatsCard from "$lib/components/ti/StatsCard.svelte";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { ptBR } from "date-fns/locale";
|
import { ptBR } from "date-fns/locale";
|
||||||
|
import { FileText, Clock, CheckCircle2, XCircle } from "lucide-svelte";
|
||||||
|
|
||||||
type StatusSolicitacao = "pendente" | "aprovado" | "rejeitado";
|
type StatusSolicitacao = "pendente" | "aprovado" | "rejeitado";
|
||||||
|
|
||||||
@@ -294,7 +295,7 @@
|
|||||||
<StatsCard
|
<StatsCard
|
||||||
title="Total de Solicitações"
|
title="Total de Solicitações"
|
||||||
value={stats.total}
|
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"
|
color="primary"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -302,7 +303,7 @@
|
|||||||
title="Pendentes"
|
title="Pendentes"
|
||||||
value={stats.pendentes}
|
value={stats.pendentes}
|
||||||
description="{stats.total > 0 ? ((stats.pendentes / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
|
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"
|
color="warning"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -310,7 +311,7 @@
|
|||||||
title="Aprovadas"
|
title="Aprovadas"
|
||||||
value={stats.aprovadas}
|
value={stats.aprovadas}
|
||||||
description="{stats.total > 0 ? ((stats.aprovadas / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
|
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"
|
color="success"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -318,7 +319,7 @@
|
|||||||
title="Rejeitadas"
|
title="Rejeitadas"
|
||||||
value={stats.rejeitadas}
|
value={stats.rejeitadas}
|
||||||
description="{stats.total > 0 ? ((stats.rejeitadas / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
|
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"
|
color="error"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user