Fix usuarios page #6
@@ -2,6 +2,7 @@
|
||||
import { useQuery, useConvexClient } from "convex-svelte";
|
||||
import { api } from "@sgse-app/backend/convex/_generated/api";
|
||||
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||
import StatsCard from "$lib/components/ti/StatsCard.svelte";
|
||||
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
||||
import { format } from "date-fns";
|
||||
import { ptBR } from "date-fns/locale";
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
let busca = $state("");
|
||||
let filtroSetor = $state("");
|
||||
let filtroNivel = $state<number | "">("");
|
||||
let roleSelecionada = $state<Role | null>(null);
|
||||
let modalDetalhesAberto = $state(false);
|
||||
|
||||
@@ -33,6 +35,27 @@
|
||||
return Array.from(setores).sort();
|
||||
});
|
||||
|
||||
// Estatísticas
|
||||
const stats = $derived.by(() => {
|
||||
if (carregando) return null;
|
||||
|
||||
const porNivel = {
|
||||
0: roles.filter(r => r.nivel === 0).length,
|
||||
1: roles.filter(r => r.nivel === 1).length,
|
||||
2: roles.filter(r => r.nivel === 2).length,
|
||||
3: roles.filter(r => r.nivel >= 3).length,
|
||||
};
|
||||
|
||||
return {
|
||||
total: roles.length,
|
||||
nivelMaximo: porNivel[0],
|
||||
nivelAlto: porNivel[1],
|
||||
nivelMedio: porNivel[2],
|
||||
nivelBaixo: porNivel[3],
|
||||
comSetor: roles.filter(r => r.setor).length,
|
||||
};
|
||||
});
|
||||
|
||||
const rolesFiltradas = $derived.by(() => {
|
||||
let resultado = roles;
|
||||
|
||||
@@ -51,6 +74,15 @@
|
||||
resultado = resultado.filter((r) => r.setor === filtroSetor);
|
||||
}
|
||||
|
||||
// Filtro por nível
|
||||
if (filtroNivel !== "") {
|
||||
if (filtroNivel === 3) {
|
||||
resultado = resultado.filter((r) => r.nivel >= 3);
|
||||
} else {
|
||||
resultado = resultado.filter((r) => r.nivel === filtroNivel);
|
||||
}
|
||||
}
|
||||
|
||||
return resultado.sort((a, b) => {
|
||||
// Ordenar por nível primeiro (menor nível = maior privilégio)
|
||||
if (a.nivel !== b.nivel) return a.nivel - b.nivel;
|
||||
@@ -74,6 +106,13 @@
|
||||
return `Nível ${nivel}`;
|
||||
}
|
||||
|
||||
function obterCorCardNivel(nivel: number): string {
|
||||
if (nivel === 0) return "border-l-4 border-error";
|
||||
if (nivel === 1) return "border-l-4 border-warning";
|
||||
if (nivel === 2) return "border-l-4 border-info";
|
||||
return "border-l-4 border-base-300";
|
||||
}
|
||||
|
||||
function abrirDetalhes(role: Role) {
|
||||
roleSelecionada = role;
|
||||
modalDetalhesAberto = true;
|
||||
@@ -95,13 +134,16 @@
|
||||
function limparFiltros() {
|
||||
busca = "";
|
||||
filtroSetor = "";
|
||||
filtroNivel = "";
|
||||
}
|
||||
|
||||
const temFiltrosAtivos = $derived(busca.trim() !== "" || filtroSetor !== "" || filtroNivel !== "");
|
||||
</script>
|
||||
|
||||
<ProtectedRoute allowedRoles={["ti_master", "admin", "ti_usuario"]} maxLevel={3}>
|
||||
<div class="container mx-auto px-4 py-6 max-w-7xl">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div class="flex items-center justify-between mb-8">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-3 bg-primary/10 rounded-xl">
|
||||
<svg
|
||||
@@ -126,13 +168,70 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Estatísticas -->
|
||||
{#if stats}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4 mb-8">
|
||||
<StatsCard
|
||||
title="Total de Perfis"
|
||||
value={stats.total}
|
||||
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />'
|
||||
color="primary"
|
||||
/>
|
||||
<StatsCard
|
||||
title="Nível Máximo"
|
||||
value={stats.nivelMaximo}
|
||||
description="Acesso total"
|
||||
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />'
|
||||
color="error"
|
||||
/>
|
||||
<StatsCard
|
||||
title="Nível Alto"
|
||||
value={stats.nivelAlto}
|
||||
description="Acesso elevado"
|
||||
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />'
|
||||
color="warning"
|
||||
/>
|
||||
<StatsCard
|
||||
title="Nível Médio"
|
||||
value={stats.nivelMedio}
|
||||
description="Acesso padrão"
|
||||
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />'
|
||||
color="info"
|
||||
/>
|
||||
<StatsCard
|
||||
title="Com Setor"
|
||||
value={stats.comSetor}
|
||||
description="{stats.total > 0 ? ((stats.comSetor / stats.total) * 100).toFixed(0) + '% do total' : '0%'}"
|
||||
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />'
|
||||
color="secondary"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Filtros -->
|
||||
{#if !carregando && roles.length > 0}
|
||||
<div class="card bg-base-100 shadow-xl mb-6">
|
||||
<div class="card bg-base-100 shadow-xl mb-6 border border-base-300">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="card-title">Filtros de Busca</h2>
|
||||
<button type="button" class="btn btn-sm btn-outline" onclick={limparFiltros}>
|
||||
<div class="flex flex-wrap items-center justify-between gap-4 mb-4">
|
||||
<div class="flex items-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"
|
||||
>
|
||||
<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>
|
||||
<h2 class="card-title text-lg">Filtros de Busca</h2>
|
||||
</div>
|
||||
{#if temFiltrosAtivos}
|
||||
<button type="button" class="btn btn-sm btn-outline btn-error" onclick={limparFiltros}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4"
|
||||
@@ -149,21 +248,38 @@
|
||||
</svg>
|
||||
Limpar Filtros
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<!-- Busca -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="busca">
|
||||
<span class="label-text font-medium">Buscar</span>
|
||||
</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
id="busca"
|
||||
type="text"
|
||||
bind:value={busca}
|
||||
placeholder="Buscar por nome ou descrição..."
|
||||
class="input input-bordered input-sm"
|
||||
class="input input-bordered w-full pl-10"
|
||||
/>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5 absolute left-3 top-1/2 transform -translate-y-1/2 text-base-content/40"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Setor -->
|
||||
@@ -171,17 +287,36 @@
|
||||
<label class="label" for="filtro-setor">
|
||||
<span class="label-text font-medium">Setor</span>
|
||||
</label>
|
||||
<select id="filtro-setor" bind:value={filtroSetor} class="select select-bordered select-sm">
|
||||
<select id="filtro-setor" bind:value={filtroSetor} class="select select-bordered">
|
||||
<option value="">Todos os setores</option>
|
||||
{#each setoresDisponiveis as setor}
|
||||
<option value={setor}>{setor}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Nível -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="filtro-nivel">
|
||||
<span class="label-text font-medium">Nível de Acesso</span>
|
||||
</label>
|
||||
<select id="filtro-nivel" bind:value={filtroNivel} class="select select-bordered">
|
||||
<option value="">Todos os níveis</option>
|
||||
<option value={0}>Máximo (0)</option>
|
||||
<option value={1}>Alto (1)</option>
|
||||
<option value={2}>Médio (2)</option>
|
||||
<option value={3}>Baixo (3+)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-sm text-base-content/60">
|
||||
Mostrando {rolesFiltradas.length} de {roles.length} perfil(is)
|
||||
<div class="mt-4 flex items-center justify-between">
|
||||
<div class="text-sm text-base-content/60">
|
||||
<span class="font-medium text-base-content">{rolesFiltradas.length}</span> de <span class="font-medium text-base-content">{roles.length}</span> perfil(is)
|
||||
{#if temFiltrosAtivos}
|
||||
<span class="badge badge-primary badge-sm ml-2">Filtrado</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -211,37 +346,145 @@
|
||||
<h3 class="text-xl font-semibold mt-4">Nenhum perfil encontrado</h3>
|
||||
<p class="text-base-content/60 mt-2">Não há perfis cadastrados no sistema.</p>
|
||||
</div>
|
||||
{:else if rolesFiltradas.length === 0}
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<div class="flex flex-col items-center justify-center py-16 text-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-16 w-16 text-base-content/30 mb-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<h3 class="text-xl font-semibold mt-4">Nenhum perfil encontrado</h3>
|
||||
<p class="text-base-content/60 mt-2">Nenhum perfil corresponde aos filtros aplicados.</p>
|
||||
{#if temFiltrosAtivos}
|
||||
<button class="btn btn-primary btn-sm mt-4" onclick={limparFiltros}>
|
||||
Limpar Filtros
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{#each rolesFiltradas as role}
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow cursor-pointer" onclick={() => abrirDetalhes(role)}>
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-all duration-300 cursor-pointer border border-base-300 {obterCorCardNivel(role.nivel)} hover:scale-[1.02]" onclick={() => abrirDetalhes(role)}>
|
||||
<div class="card-body">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<h2 class="card-title text-lg">{role.descricao}</h2>
|
||||
<div class="badge {obterCorNivel(role.nivel)}">{obterTextoNivel(role.nivel)}</div>
|
||||
<div class="flex-1">
|
||||
<h2 class="card-title text-lg mb-1">{role.descricao}</h2>
|
||||
<div class="badge {obterCorNivel(role.nivel)} badge-sm">{obterTextoNivel(role.nivel)}</div>
|
||||
</div>
|
||||
<div class="p-2 bg-base-200 rounded-lg">
|
||||
<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="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 text-sm">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="space-y-3 text-sm">
|
||||
<div class="flex items-center gap-2 p-2 bg-base-200 rounded-lg">
|
||||
<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="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>
|
||||
<span class="font-medium text-base-content/60">Nome técnico:</span>
|
||||
<code class="text-xs bg-base-200 px-2 py-1 rounded">{role.nome}</code>
|
||||
<code class="text-xs bg-base-100 px-2 py-1 rounded font-mono">{role.nome}</code>
|
||||
</div>
|
||||
|
||||
{#if role.setor}
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-2 p-2 bg-base-200 rounded-lg">
|
||||
<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="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"
|
||||
/>
|
||||
</svg>
|
||||
<span class="font-medium text-base-content/60">Setor:</span>
|
||||
<span>{role.setor}</span>
|
||||
<span class="font-medium">{role.setor}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-2 p-2 bg-base-200 rounded-lg">
|
||||
<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="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"
|
||||
/>
|
||||
</svg>
|
||||
<span class="font-medium text-base-content/60">Nível:</span>
|
||||
<span>{role.nivel}</span>
|
||||
<span class="font-bold text-lg">{role.nivel}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-actions justify-end mt-4">
|
||||
<button class="btn btn-sm btn-primary" onclick={(e) => { e.stopPropagation(); abrirDetalhes(role); }}>
|
||||
<div class="card-actions justify-end mt-4 pt-4 border-t border-base-300">
|
||||
<button class="btn btn-sm btn-primary btn-outline" onclick={(e) => { e.stopPropagation(); abrirDetalhes(role); }}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4 mr-1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<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>
|
||||
Ver Detalhes
|
||||
</button>
|
||||
</div>
|
||||
@@ -255,58 +498,132 @@
|
||||
<!-- Modal Detalhes -->
|
||||
{#if modalDetalhesAberto && roleSelecionada}
|
||||
<div class="modal modal-open">
|
||||
<div class="modal-box max-w-2xl">
|
||||
<h3 class="font-bold text-lg mb-4">Detalhes do Perfil</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">Nome Técnico</span>
|
||||
</label>
|
||||
<code class="block bg-base-200 px-3 py-2 rounded text-sm">{roleSelecionada.nome}</code>
|
||||
<div class="modal-box max-w-3xl">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="font-bold text-2xl">Detalhes do Perfil</h3>
|
||||
<button type="button" class="btn btn-sm btn-circle btn-ghost" onclick={fecharDetalhes}>
|
||||
<svg 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="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">Descrição</span>
|
||||
</label>
|
||||
<p class="text-base-content">{roleSelecionada.descricao}</p>
|
||||
<div class="space-y-6">
|
||||
<!-- Header do Perfil -->
|
||||
<div class="card bg-gradient-to-r from-primary/10 to-secondary/10 border border-primary/20">
|
||||
<div class="card-body">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex-1">
|
||||
<h2 class="text-2xl font-bold mb-2">{roleSelecionada.descricao}</h2>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="badge {obterCorNivel(roleSelecionada.nivel)} badge-lg">{obterTextoNivel(roleSelecionada.nivel)}</div>
|
||||
<span class="text-sm text-base-content/60">Nível {roleSelecionada.nivel}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3 bg-base-100 rounded-lg shadow-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-primary"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<!-- Informações Principais -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="card bg-base-100 border border-base-300">
|
||||
<div class="card-body">
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">Nível de Acesso</span>
|
||||
<span class="label-text font-semibold flex items-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">
|
||||
<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>
|
||||
Nome Técnico
|
||||
</span>
|
||||
</label>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-lg font-bold">{roleSelecionada.nivel}</span>
|
||||
<div class="badge {obterCorNivel(roleSelecionada.nivel)}">{obterTextoNivel(roleSelecionada.nivel)}</div>
|
||||
<code class="block bg-base-200 px-4 py-3 rounded-lg text-sm font-mono mt-2">{roleSelecionada.nome}</code>
|
||||
</div>
|
||||
<p class="text-xs text-base-content/60 mt-1">
|
||||
{roleSelecionada.nivel === 0 && "Acesso total irrestrito ao sistema"}
|
||||
{roleSelecionada.nivel === 1 && "Acesso alto com algumas restrições"}
|
||||
{roleSelecionada.nivel === 2 && "Acesso médio com permissões configuráveis"}
|
||||
{roleSelecionada.nivel >= 3 && "Acesso limitado com permissões específicas"}
|
||||
</div>
|
||||
|
||||
<div class="card bg-base-100 border border-base-300">
|
||||
<div class="card-body">
|
||||
<label class="label">
|
||||
<span class="label-text font-semibold flex items-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">
|
||||
<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" />
|
||||
</svg>
|
||||
Setor
|
||||
</span>
|
||||
</label>
|
||||
<p class="text-lg font-medium mt-2">
|
||||
{#if roleSelecionada.setor}
|
||||
{roleSelecionada.setor}
|
||||
{:else}
|
||||
<span class="text-base-content/40 italic">Não especificado</span>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- Nível de Acesso -->
|
||||
<div class="card bg-base-100 border border-base-300">
|
||||
<div class="card-body">
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">Setor</span>
|
||||
<span class="label-text font-semibold flex items-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">
|
||||
<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" />
|
||||
</svg>
|
||||
Nível de Acesso
|
||||
</span>
|
||||
</label>
|
||||
<p class="text-base-content">{roleSelecionada.setor || "Não especificado"}</p>
|
||||
<div class="mt-4">
|
||||
<div class="flex items-center gap-4 mb-3">
|
||||
<span class="text-4xl font-bold">{roleSelecionada.nivel}</span>
|
||||
<div class="badge {obterCorNivel(roleSelecionada.nivel)} badge-lg">{obterTextoNivel(roleSelecionada.nivel)}</div>
|
||||
</div>
|
||||
<div class="alert alert-info">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
<span class="text-sm">
|
||||
{roleSelecionada.nivel === 0 && "Acesso total irrestrito ao sistema. Pode realizar todas as operações sem restrições."}
|
||||
{roleSelecionada.nivel === 1 && "Acesso alto com algumas restrições. Pode realizar a maioria das operações administrativas."}
|
||||
{roleSelecionada.nivel === 2 && "Acesso médio com permissões configuráveis. Pode realizar operações padrão do sistema."}
|
||||
{roleSelecionada.nivel >= 3 && "Acesso limitado com permissões específicas. Operações restritas conforme configuração."}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- Data de Criação -->
|
||||
<div class="card bg-base-100 border border-base-300">
|
||||
<div class="card-body">
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">Data de Criação</span>
|
||||
<span class="label-text font-semibold flex items-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">
|
||||
<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>
|
||||
Data de Criação
|
||||
</span>
|
||||
</label>
|
||||
<p class="text-base-content">{formatarData(roleSelecionada._creationTime)}</p>
|
||||
<p class="text-lg font-medium mt-2">{formatarData(roleSelecionada._creationTime)}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informação sobre Permissões -->
|
||||
<div class="alert alert-info">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -321,17 +638,24 @@
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<span>
|
||||
Para configurar permissões específicas deste perfil, acesse o <a href="/ti/painel-permissoes" class="link link-primary">Painel de Permissões</a>.
|
||||
</span>
|
||||
<div>
|
||||
<h4 class="font-semibold mb-1">Configuração de Permissões</h4>
|
||||
<p class="text-sm">
|
||||
Para configurar permissões específicas deste perfil, acesse o <a href="/ti/painel-permissoes" class="link link-primary font-semibold">Painel de Permissões</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-action">
|
||||
<div class="modal-action mt-6">
|
||||
<button type="button" class="btn btn-ghost" onclick={fecharDetalhes}>
|
||||
Fechar
|
||||
</button>
|
||||
<a href="/ti/painel-permissoes" class="btn btn-primary">
|
||||
<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="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
Configurar Permissões
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user