refactor: improve UI and functionality in employee registration and audit pages
- Enhanced the employee registration form by adding a dependents management section, allowing users to input details such as relationship, name, CPF, and birth date. - Updated the layout and styling of the audit page, including improved statistics display and user feedback elements. - Refined the handling of user actions in the audit logs, providing clearer labels and better organization of information. - Improved the overall user experience by ensuring consistent design patterns and responsive elements across the registration and audit interfaces.
This commit is contained in:
@@ -702,71 +702,51 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Filtros -->
|
||||
<div class="card bg-base-100 shadow-xl mb-6">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4">Filtros</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Tipo</span>
|
||||
</label>
|
||||
<select
|
||||
bind:value={filtroTipo}
|
||||
class="select select-bordered"
|
||||
>
|
||||
<!-- Filtros -->
|
||||
<div class="card bg-base-100 shadow-xl mb-6">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4">Filtros</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-5 gap-4 items-end">
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer flex flex-col gap-2" for="filtro-tipo">
|
||||
<span class="label-text">Tipo</span>
|
||||
<select id="filtro-tipo" class="select select-bordered" bind:value={filtroTipo}>
|
||||
<option value="todos">Todos</option>
|
||||
<option value="atestado_medico">Atestado Médico</option>
|
||||
<option value="declaracao_comparecimento">Declaração</option>
|
||||
<option value="maternidade">Licença Maternidade</option>
|
||||
<option value="paternidade">Licença Paternidade</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Funcionário</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
bind:value={filtroFuncionario}
|
||||
placeholder="Buscar por nome..."
|
||||
class="input input-bordered"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer flex flex-col gap-2" for="filtro-funcionario">
|
||||
<span class="label-text">Funcionário</span>
|
||||
<input id="filtro-funcionario" class="input input-bordered" type="text" bind:value={filtroFuncionario} placeholder="Nome do colaborador" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Data Início</span>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={filtroDataInicio}
|
||||
class="input input-bordered"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer flex flex-col gap-2" for="filtro-data-inicio">
|
||||
<span class="label-text">Data Início</span>
|
||||
<input id="filtro-data-inicio" class="input input-bordered" type="date" bind:value={filtroDataInicio} />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Data Fim</span>
|
||||
</label>
|
||||
<div class="flex gap-2">
|
||||
<input
|
||||
type="date"
|
||||
bind:value={filtroDataFim}
|
||||
class="input input-bordered flex-1"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-outline"
|
||||
onclick={limparFiltros}
|
||||
>
|
||||
Limpar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer flex flex-col gap-2" for="filtro-data-fim">
|
||||
<span class="label-text">Data Fim</span>
|
||||
<input id="filtro-data-fim" class="input input-bordered" type="date" bind:value={filtroDataFim} />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 justify-end">
|
||||
<button class="btn btn-outline" onclick={limparFiltros}>Limpar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Calendário Interativo -->
|
||||
{#if eventosQuery?.data}
|
||||
@@ -1136,8 +1116,8 @@
|
||||
: "Declaração"}
|
||||
</span>
|
||||
</td>
|
||||
<td>{formatarData(atestado.dataInicio)}</td>
|
||||
<td>{formatarData(atestado.dataFim)}</td>
|
||||
<td class="whitespace-nowrap font-mono text-xs">{formatarData(atestado.dataInicio)}</td>
|
||||
<td class="whitespace-nowrap font-mono text-xs">{formatarData(atestado.dataFim)}</td>
|
||||
<td>{atestado.dias}</td>
|
||||
<td>
|
||||
<span
|
||||
@@ -1203,8 +1183,8 @@
|
||||
{licenca.ehProrrogacao ? " (Prorrogação)" : ""}
|
||||
</span>
|
||||
</td>
|
||||
<td>{formatarData(licenca.dataInicio)}</td>
|
||||
<td>{formatarData(licenca.dataFim)}</td>
|
||||
<td class="whitespace-nowrap font-mono text-xs">{formatarData(licenca.dataInicio)}</td>
|
||||
<td class="whitespace-nowrap font-mono text-xs">{formatarData(licenca.dataFim)}</td>
|
||||
<td>{licenca.dias}</td>
|
||||
<td>
|
||||
<span
|
||||
@@ -1279,9 +1259,9 @@
|
||||
/>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Início <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={atestadoMedico.dataInicio}
|
||||
@@ -1291,9 +1271,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Fim <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={atestadoMedico.dataFim}
|
||||
@@ -1303,9 +1283,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">CID <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
bind:value={atestadoMedico.cid}
|
||||
@@ -1333,9 +1313,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Observações</span>
|
||||
</label>
|
||||
</div>
|
||||
<textarea
|
||||
bind:value={atestadoMedico.observacoes}
|
||||
class="textarea textarea-bordered h-24"
|
||||
@@ -1379,9 +1359,9 @@
|
||||
/>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Início <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={declaracao.dataInicio}
|
||||
@@ -1391,9 +1371,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Fim <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={declaracao.dataFim}
|
||||
@@ -1417,9 +1397,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Observações</span>
|
||||
</label>
|
||||
</div>
|
||||
<textarea
|
||||
bind:value={declaracao.observacoes}
|
||||
class="textarea textarea-bordered h-24"
|
||||
@@ -1463,9 +1443,9 @@
|
||||
/>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Início <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={licencaMaternidade.dataInicio}
|
||||
@@ -1475,18 +1455,18 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Fim <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={licencaMaternidade.dataFim}
|
||||
class="input input-bordered"
|
||||
required
|
||||
/>
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text-alt">Calculado automaticamente (120 dias)</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-control md:col-span-2">
|
||||
@@ -1502,9 +1482,9 @@
|
||||
|
||||
{#if licencaMaternidade.ehProrrogacao}
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Licença Original <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<select
|
||||
bind:value={licencaMaternidade.licencaOriginalId}
|
||||
class="select select-bordered"
|
||||
@@ -1539,9 +1519,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Observações</span>
|
||||
</label>
|
||||
</div>
|
||||
<textarea
|
||||
bind:value={licencaMaternidade.observacoes}
|
||||
class="textarea textarea-bordered h-24"
|
||||
@@ -1585,9 +1565,9 @@
|
||||
/>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Início <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={licencaPaternidade.dataInicio}
|
||||
@@ -1597,18 +1577,18 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Data Fim <span class="text-error">*</span></span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={licencaPaternidade.dataFim}
|
||||
class="input input-bordered"
|
||||
required
|
||||
/>
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text-alt">Calculado automaticamente (20 dias)</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-control md:col-span-2">
|
||||
@@ -1628,9 +1608,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label">
|
||||
<div class="label">
|
||||
<span class="label-text font-medium">Observações</span>
|
||||
</label>
|
||||
</div>
|
||||
<textarea
|
||||
bind:value={licencaPaternidade.observacoes}
|
||||
class="textarea textarea-bordered h-24"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,8 @@
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,55 +31,128 @@
|
||||
};
|
||||
return colors[acao] || "badge-neutral";
|
||||
}
|
||||
|
||||
function getAcaoLabel(acao: string) {
|
||||
const labels: Record<string, string> = {
|
||||
criar: "Criar",
|
||||
editar: "Editar",
|
||||
excluir: "Excluir",
|
||||
bloquear: "Bloquear",
|
||||
desbloquear: "Desbloquear",
|
||||
resetar_senha: "Resetar Senha"
|
||||
};
|
||||
return labels[acao] || acao;
|
||||
}
|
||||
|
||||
// Estatísticas
|
||||
const totalAtividades = $derived(atividades?.data?.length || 0);
|
||||
const totalLogins = $derived(logins?.data?.length || 0);
|
||||
const loginsSucesso = $derived(logins?.data?.filter(l => l.sucesso).length || 0);
|
||||
const loginsFalha = $derived(logins?.data?.filter(l => !l.sucesso).length || 0);
|
||||
</script>
|
||||
|
||||
<div class="container mx-auto px-4 py-6 max-w-7xl">
|
||||
<main class="container mx-auto px-4 py-6 max-w-7xl">
|
||||
<!-- Breadcrumb -->
|
||||
<div class="text-sm breadcrumbs mb-4">
|
||||
<ul>
|
||||
<li><a href="/ti" class="text-primary hover:underline">TI</a></li>
|
||||
<li>Auditoria e Logs</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-3 bg-accent/10 rounded-xl">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-accent" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<div class="mb-6">
|
||||
<div class="flex items-center gap-4 mb-2">
|
||||
<div class="p-3 bg-blue-500/20 rounded-xl">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-blue-600" 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>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-base-content">Auditoria e Logs</h1>
|
||||
<p class="text-base-content/60 mt-1">Histórico completo de atividades e acessos</p>
|
||||
<h1 class="text-3xl font-bold text-primary">Auditoria e Logs</h1>
|
||||
<p class="text-base-content/70">Monitoramento completo de atividades e acessos do sistema</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cards de Estatísticas -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
||||
<div class="stat bg-base-100 shadow-lg rounded-lg">
|
||||
<div class="stat-figure text-primary">
|
||||
<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 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" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title text-xs">Atividades</div>
|
||||
<div class="stat-value text-2xl">{totalAtividades}</div>
|
||||
<div class="stat-desc">Registros exibidos</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-lg">
|
||||
<div class="stat-figure text-success">
|
||||
<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="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>
|
||||
</div>
|
||||
<div class="stat-title text-xs">Logins Totais</div>
|
||||
<div class="stat-value text-2xl">{totalLogins}</div>
|
||||
<div class="stat-desc">Tentativas de acesso</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-lg">
|
||||
<div class="stat-figure text-success">
|
||||
<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-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title text-xs">Logins Bem-sucedidos</div>
|
||||
<div class="stat-value text-2xl text-success">{loginsSucesso}</div>
|
||||
<div class="stat-desc">{totalLogins > 0 ? Math.round((loginsSucesso / totalLogins) * 100) : 0}% de sucesso</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-lg">
|
||||
<div class="stat-figure text-error">
|
||||
<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="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title text-xs">Logins Falhados</div>
|
||||
<div class="stat-value text-2xl text-error">{loginsFalha}</div>
|
||||
<div class="stat-desc">{totalLogins > 0 ? Math.round((loginsFalha / totalLogins) * 100) : 0}% de falhas</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tabs -->
|
||||
<div class="tabs tabs-boxed mb-6 bg-base-100 shadow-lg p-2">
|
||||
<div class="tabs tabs-boxed mb-6 bg-base-100 shadow-lg p-1">
|
||||
<button
|
||||
class="tab {abaAtiva === 'atividades' ? 'tab-active' : ''}"
|
||||
class="tab flex items-center gap-2 {abaAtiva === 'atividades' ? 'tab-active' : ''}"
|
||||
onclick={() => abaAtiva = "atividades"}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<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" />
|
||||
<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 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-6 9l2 2 4-4" />
|
||||
</svg>
|
||||
Atividades no Sistema
|
||||
<span class="font-medium">Atividades no Sistema</span>
|
||||
</button>
|
||||
<button
|
||||
class="tab {abaAtiva === 'logins' ? 'tab-active' : ''}"
|
||||
class="tab flex items-center gap-2 {abaAtiva === 'logins' ? 'tab-active' : ''}"
|
||||
onclick={() => abaAtiva = "logins"}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
|
||||
</svg>
|
||||
Histórico de Logins
|
||||
<span class="font-medium">Histórico de Logins</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Controles -->
|
||||
<div class="card bg-base-100 shadow-xl mb-6">
|
||||
<div class="card-body">
|
||||
<div class="card-body py-4">
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Quantidade de registros</span>
|
||||
<label class="label py-1">
|
||||
<span class="label-text font-medium">Quantidade de registros</span>
|
||||
</label>
|
||||
<select bind:value={limite} class="select select-bordered">
|
||||
<select bind:value={limite} class="select select-bordered select-sm w-full max-w-xs">
|
||||
<option value={20}>20 registros</option>
|
||||
<option value={50}>50 registros</option>
|
||||
<option value={100}>100 registros</option>
|
||||
@@ -87,14 +161,14 @@
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button class="btn btn-outline btn-primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<button class="btn btn-outline btn-primary btn-sm gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||
</svg>
|
||||
Exportar CSV
|
||||
</button>
|
||||
<button class="btn btn-outline btn-secondary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<button class="btn btn-outline btn-secondary btn-sm gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
|
||||
</svg>
|
||||
Filtros Avançados
|
||||
@@ -108,45 +182,79 @@
|
||||
{#if abaAtiva === "atividades"}
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4">Atividades Recentes</h2>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="card-title text-xl">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<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" />
|
||||
</svg>
|
||||
Atividades Recentes
|
||||
</h2>
|
||||
{#if atividades?.data}
|
||||
<div class="badge badge-outline badge-lg">{atividades.data.length} registro{atividades.data.length !== 1 ? 's' : ''}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if !atividades?.data}
|
||||
<div class="flex justify-center py-10">
|
||||
<span class="loading loading-spinner loading-lg text-primary"></span>
|
||||
<div class="flex flex-col items-center justify-center py-16">
|
||||
<span class="loading loading-spinner loading-lg text-primary mb-4"></span>
|
||||
<p class="text-base-content/60">Carregando atividades...</p>
|
||||
</div>
|
||||
{:else if atividades.data.length === 0}
|
||||
<div class="text-center py-10 text-base-content/60">
|
||||
Nenhuma atividade registrada
|
||||
<div class="flex flex-col items-center justify-center py-16 text-base-content/60">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 mb-4 opacity-50" 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>
|
||||
<p class="text-lg font-medium">Nenhuma atividade registrada</p>
|
||||
<p class="text-sm mt-1">As atividades do sistema aparecerão aqui</p>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<div class="overflow-x-auto rounded-lg">
|
||||
<table class="table table-zebra">
|
||||
<thead class="bg-base-200">
|
||||
<tr>
|
||||
<th>Data/Hora</th>
|
||||
<th>Usuário</th>
|
||||
<th>Ação</th>
|
||||
<th>Recurso</th>
|
||||
<th>Detalhes</th>
|
||||
<th class="font-semibold">Data/Hora</th>
|
||||
<th class="font-semibold">Usuário</th>
|
||||
<th class="font-semibold">Ação</th>
|
||||
<th class="font-semibold">Recurso</th>
|
||||
<th class="font-semibold">Detalhes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each atividades.data as atividade}
|
||||
<tr class="hover">
|
||||
<td class="font-mono text-xs">{formatarData(atividade.timestamp)}</td>
|
||||
<tr class="hover transition-colors">
|
||||
<td>
|
||||
<div class="font-medium">{atividade.usuarioNome || "Sistema"}</div>
|
||||
<div class="text-xs opacity-60">{atividade.usuarioMatricula || "-"}</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-base-content/40" 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>
|
||||
<span class="font-mono text-xs">{formatarData(atividade.timestamp)}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {getAcaoColor(atividade.acao)} badge-sm">
|
||||
{atividade.acao}
|
||||
<div class="flex flex-col">
|
||||
<div class="font-semibold text-sm">{atividade.usuarioNome || "Sistema"}</div>
|
||||
{#if atividade.usuarioMatricula}
|
||||
<div class="text-xs text-base-content/50 font-mono">{atividade.usuarioMatricula}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {getAcaoColor(atividade.acao)} badge-sm gap-1">
|
||||
{getAcaoLabel(atividade.acao)}
|
||||
</span>
|
||||
</td>
|
||||
<td class="font-medium">{atividade.recurso}</td>
|
||||
<td>
|
||||
<div class="text-xs max-w-md truncate" title={atividade.detalhes}>
|
||||
{atividade.detalhes || "-"}
|
||||
<span class="font-medium text-sm">{atividade.recurso}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="max-w-md">
|
||||
{#if atividade.detalhes}
|
||||
<div class="text-xs text-base-content/70 truncate" title={atividade.detalhes}>
|
||||
{atividade.detalhes}
|
||||
</div>
|
||||
{:else}
|
||||
<span class="text-base-content/40 text-xs">-</span>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -160,49 +268,98 @@
|
||||
{:else}
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4">Histórico de Logins</h2>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="card-title text-xl">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
|
||||
</svg>
|
||||
Histórico de Logins
|
||||
</h2>
|
||||
{#if logins?.data}
|
||||
<div class="badge badge-outline badge-lg">{logins.data.length} registro{logins.data.length !== 1 ? 's' : ''}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if !logins?.data}
|
||||
<div class="flex justify-center py-10">
|
||||
<span class="loading loading-spinner loading-lg text-primary"></span>
|
||||
<div class="flex flex-col items-center justify-center py-16">
|
||||
<span class="loading loading-spinner loading-lg text-primary mb-4"></span>
|
||||
<p class="text-base-content/60">Carregando logins...</p>
|
||||
</div>
|
||||
{:else if logins.data.length === 0}
|
||||
<div class="text-center py-10 text-base-content/60">
|
||||
Nenhum login registrado
|
||||
<div class="flex flex-col items-center justify-center py-16 text-base-content/60">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 mb-4 opacity-50" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
|
||||
</svg>
|
||||
<p class="text-lg font-medium">Nenhum login registrado</p>
|
||||
<p class="text-sm mt-1">Os acessos ao sistema aparecerão aqui</p>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<div class="overflow-x-auto rounded-lg">
|
||||
<table class="table table-zebra">
|
||||
<thead class="bg-base-200">
|
||||
<tr>
|
||||
<th>Data/Hora</th>
|
||||
<th>Usuário/Email</th>
|
||||
<th>Status</th>
|
||||
<th>IP</th>
|
||||
<th>Dispositivo</th>
|
||||
<th>Navegador</th>
|
||||
<th>Sistema</th>
|
||||
<th class="font-semibold">Data/Hora</th>
|
||||
<th class="font-semibold">Usuário/Email</th>
|
||||
<th class="font-semibold">Status</th>
|
||||
<th class="font-semibold">IP</th>
|
||||
<th class="font-semibold">Dispositivo</th>
|
||||
<th class="font-semibold">Navegador</th>
|
||||
<th class="font-semibold">Sistema</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each logins.data as login}
|
||||
<tr class="hover">
|
||||
<td class="font-mono text-xs">{formatarData(login.timestamp)}</td>
|
||||
<td class="text-sm">{login.matriculaOuEmail}</td>
|
||||
<tr class="hover transition-colors">
|
||||
<td>
|
||||
{#if login.sucesso}
|
||||
<span class="badge badge-success badge-sm">Sucesso</span>
|
||||
{:else}
|
||||
<span class="badge badge-error badge-sm">Falhou</span>
|
||||
{#if login.motivoFalha}
|
||||
<div class="text-xs text-error mt-1">{login.motivoFalha}</div>
|
||||
{/if}
|
||||
{/if}
|
||||
<div class="flex items-center gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-base-content/40" 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>
|
||||
<span class="font-mono text-xs">{formatarData(login.timestamp)}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-base-content/40" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||
</svg>
|
||||
<span class="text-sm font-medium">{login.matriculaOuEmail}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex flex-col gap-1">
|
||||
{#if login.sucesso}
|
||||
<span class="badge badge-success badge-sm gap-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Sucesso
|
||||
</span>
|
||||
{:else}
|
||||
<span class="badge badge-error badge-sm gap-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
Falhou
|
||||
</span>
|
||||
{#if login.motivoFalha}
|
||||
<div class="text-xs text-error mt-1 font-medium">{login.motivoFalha}</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="font-mono text-xs bg-base-200 px-2 py-1 rounded">{login.ipAddress || "-"}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-xs text-base-content/70">{login.device || "-"}</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-xs text-base-content/70">{login.browser || "-"}</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-xs text-base-content/70">{login.sistema || "-"}</div>
|
||||
</td>
|
||||
<td class="font-mono text-xs">{login.ipAddress || "-"}</td>
|
||||
<td class="text-xs">{login.device || "-"}</td>
|
||||
<td class="text-xs">{login.browser || "-"}</td>
|
||||
<td class="text-xs">{login.sistema || "-"}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
@@ -214,11 +371,14 @@
|
||||
{/if}
|
||||
|
||||
<!-- Informação -->
|
||||
<div class="alert alert-info mt-6">
|
||||
<div class="alert alert-info shadow-lg mt-6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
<span>Os logs são armazenados permanentemente e não podem ser alterados ou excluídos.</span>
|
||||
<div>
|
||||
<h3 class="font-bold">Informação Importante</h3>
|
||||
<div class="text-sm">Os logs são armazenados permanentemente e não podem ser alterados ou excluídos.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user