refactor: update user role management and enhance UI components

- Updated the user role management logic to improve type safety and error handling, including better handling of role permissions and user associations.
- Refactored the UI components for user management, enhancing the layout and styling for better user experience.
- Removed outdated code related to menu permissions and streamlined the database schema for roles and profiles.
- Improved the overall structure and readability of the codebase, ensuring consistency across components.
This commit is contained in:
2025-11-03 15:12:10 -03:00
parent 5cb63f9437
commit c1d9958c9f
10 changed files with 749 additions and 494 deletions

View File

@@ -3,49 +3,30 @@
import { useQuery } from "convex-svelte";
import { api } from "@sgse-app/backend/convex/_generated/api";
// Buscar todas as solicitações (RH vê tudo)
// Buscar TODAS as solicitações de férias (Dashboard RH)
const todasSolicitacoesQuery = useQuery(api.ferias.listarTodas, {});
const todosFuncionariosQuery = useQuery(api.funcionarios.getAll, {});
let filtroStatus = $state<string>("todos");
let filtroTime = $state<string>("todos");
let filtroBusca = $state("");
const solicitacoes = $derived(todasSolicitacoesQuery?.data || []);
const funcionarios = $derived(todosFuncionariosQuery?.data || []);
// Filtrar solicitações
const solicitacoesFiltradas = $derived(
solicitacoes.filter((s: any) => {
// Filtro de status
if (filtroStatus !== "todos" && s.status !== filtroStatus) return false;
// Filtro de time
if (filtroTime !== "todos" && s.time?._id !== filtroTime) return false;
// Filtro de busca
if (filtroBusca && !s.funcionario?.nome.toLowerCase().includes(filtroBusca.toLowerCase())) {
return false;
}
return true;
})
);
// Estatísticas
// Estatísticas gerais
const stats = $derived({
total: solicitacoes.length,
aguardando: solicitacoes.filter((s: any) => s.status === "aguardando_aprovacao").length,
aprovadas: solicitacoes.filter((s: any) => s.status === "aprovado" || s.status === "data_ajustada_aprovada").length,
reprovadas: solicitacoes.filter((s: any) => s.status === "reprovado").length,
emFerias: funcionarios.filter((f: any) => f.statusFerias === "em_ferias").length,
});
// Times únicos para filtro
const timesDisponiveis = $derived(
Array.from(new Set(solicitacoes.map((s: any) => s.time).filter(Boolean)))
);
function getStatusBadge(status: string) {
const badges: Record<string, string> = {
aguardando_aprovacao: "badge-warning",
@@ -104,7 +85,7 @@
</div>
<!-- Estatísticas -->
<div class="grid grid-cols-1 md:grid-cols-5 gap-4 mb-6">
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
<div class="stat bg-base-100 shadow-lg rounded-box border border-base-300">
<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">
@@ -148,38 +129,13 @@
<div class="stat-value text-error">{stats.reprovadas}</div>
<div class="stat-desc">Indeferidas</div>
</div>
<div class="stat bg-gradient-to-br from-purple-500/10 to-purple-600/20 shadow-lg rounded-box border-2 border-purple-500/30">
<div class="stat-figure text-purple-600">
<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="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" />
</svg>
</div>
<div class="stat-title">Em Férias</div>
<div class="stat-value text-purple-600">{stats.emFerias}</div>
<div class="stat-desc">Agora</div>
</div>
</div>
<!-- Filtros -->
<div class="card bg-base-100 shadow-lg mb-6">
<div class="card-body">
<h2 class="card-title text-lg mb-4">Filtros</h2>
<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">Buscar Funcionário</span>
</label>
<input
id="busca"
type="text"
placeholder="Digite o nome..."
class="input input-bordered"
bind:value={filtroBusca}
/>
</div>
<div class="grid grid-cols-1 md:grid-cols-1 gap-4">
<!-- Filtro Status -->
<div class="form-control">
<label class="label" for="status">
@@ -193,21 +149,6 @@
<option value="data_ajustada_aprovada">Data Ajustada</option>
</select>
</div>
<!-- Filtro Time -->
<div class="form-control">
<label class="label" for="time">
<span class="label-text">Time</span>
</label>
<select id="time" class="select select-bordered" bind:value={filtroTime}>
<option value="todos">Todos os Times</option>
{#each timesDisponiveis as time}
{#if time}
<option value={time._id}>{time.nome}</option>
{/if}
{/each}
</select>
</div>
</div>
</div>
</div>