Files
sgse-app/apps/web/src/routes/(dashboard)/recursos-humanos/+page.svelte
deyvisonwanderley f0c6e4468f feat: integrate point management features into the dashboard
- Added a new "Meu Ponto" section for users to register their work hours, breaks, and attendance.
- Introduced a "Controle de Ponto" category in the Recursos Humanos section for managing employee time records.
- Enhanced the backend schema to support point registration and configuration settings.
- Updated various components to improve UI consistency and user experience across the dashboard.
2025-11-18 11:44:12 -03:00

313 lines
9.8 KiB
Svelte

<script lang="ts">
import { goto } from "$app/navigation";
import { useQuery } from "convex-svelte";
import { api } from "@sgse-app/backend/convex/_generated/api";
import {
Users,
UserPlus,
ClipboardList,
Trash2,
BarChart3,
Calendar,
FileText,
BadgeCheck,
Plus,
List,
ChevronRight,
CheckCircle2,
Info,
ArrowRight,
Clock,
} from "lucide-svelte";
import type { Component } from "svelte";
// Buscar estatísticas para exibir nos cards
const statsQuery = useQuery(api.dashboard.getStats, {});
interface MenuOpcao {
nome: string;
descricao: string;
href: string;
Icon: Component;
}
interface MenuCategoria {
categoria: string;
descricao: string;
Icon: Component;
gradient: string;
accentColor: string;
bgIcon: string;
opcoes: MenuOpcao[];
}
const menuItems: MenuCategoria[] = [
{
categoria: "Gestão de Funcionários",
descricao: "Gerencie o cadastro e informações dos funcionários",
Icon: Users,
gradient: "from-blue-500/10 to-blue-600/20",
accentColor: "text-blue-600",
bgIcon: "bg-blue-500/20",
opcoes: [
{
nome: "Cadastrar Funcionário",
descricao: "Adicionar novo funcionário ao sistema",
href: "/recursos-humanos/funcionarios/cadastro",
Icon: UserPlus,
},
{
nome: "Listar Funcionários",
descricao: "Visualizar e editar cadastros",
href: "/recursos-humanos/funcionarios",
Icon: ClipboardList,
},
{
nome: "Excluir Cadastro",
descricao: "Remover funcionário do sistema",
href: "/recursos-humanos/funcionarios/excluir",
Icon: Trash2,
},
{
nome: "Relatórios",
descricao: "Visualizar estatísticas e gráficos",
href: "/recursos-humanos/funcionarios/relatorios",
Icon: BarChart3,
},
],
},
{
categoria: "Gestão de Férias e Licenças",
descricao: "Controle de férias, atestados e licenças",
Icon: Calendar,
gradient: "from-purple-500/10 to-purple-600/20",
accentColor: "text-purple-600",
bgIcon: "bg-purple-500/20",
opcoes: [
{
nome: "Gestão de Férias",
descricao: "Controlar períodos de férias",
href: "/recursos-humanos/ferias",
Icon: Calendar,
},
{
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: BadgeCheck,
gradient: "from-green-500/10 to-green-600/20",
accentColor: "text-green-600",
bgIcon: "bg-green-500/20",
opcoes: [
{
nome: "Cadastrar Símbolo",
descricao: "Adicionar novo cargo ou função",
href: "/recursos-humanos/simbolos/cadastro",
Icon: Plus,
},
{
nome: "Listar Símbolos",
descricao: "Visualizar e editar símbolos",
href: "/recursos-humanos/simbolos",
Icon: List,
},
],
},
{
categoria: "Controle de Ponto",
descricao: "Gerencie registros de ponto dos funcionários",
Icon: Clock,
gradient: "from-cyan-500/10 to-cyan-600/20",
accentColor: "text-cyan-600",
bgIcon: "bg-cyan-500/20",
opcoes: [
{
nome: "Registro de Pontos",
descricao: "Visualizar e gerenciar registros de ponto",
href: "/recursos-humanos/registro-pontos",
Icon: Clock,
},
],
},
];
</script>
<main class="container mx-auto px-4 py-4">
<!-- Cabeçalho -->
<div class="mb-8">
<h1 class="text-4xl font-bold text-primary mb-2">Recursos Humanos</h1>
<p class="text-lg text-base-content/70">
Gerencie funcionários, símbolos e visualize relatórios do departamento
</p>
</div>
<!-- Estatísticas Rápidas -->
{#if statsQuery.data}
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
<div
class="stats shadow-lg bg-linear-to-br from-primary/10 to-primary/20"
>
<div class="stat">
<div class="stat-figure text-primary">
<Users class="h-8 w-8" strokeWidth={2} />
</div>
<div class="stat-title">Total</div>
<div class="stat-value text-primary">
{statsQuery.data.totalFuncionarios}
</div>
<div class="stat-desc">Funcionários cadastrados</div>
</div>
</div>
<div
class="stats shadow-lg bg-linear-to-br from-success/10 to-success/20"
>
<div class="stat">
<div class="stat-figure text-success">
<CheckCircle2 class="h-8 w-8" strokeWidth={2} />
</div>
<div class="stat-title">Ativos</div>
<div class="stat-value text-success">
{statsQuery.data.funcionariosAtivos}
</div>
<div class="stat-desc">Funcionários ativos</div>
</div>
</div>
<div
class="stats shadow-lg bg-linear-to-br from-secondary/10 to-secondary/20"
>
<div class="stat">
<div class="stat-figure text-secondary">
<BadgeCheck class="h-8 w-8" strokeWidth={2} />
</div>
<div class="stat-title">Símbolos</div>
<div class="stat-value text-secondary">
{statsQuery.data.totalSimbolos}
</div>
<div class="stat-desc">Cargos e funções</div>
</div>
</div>
<div class="stats shadow-lg bg-linear-to-br from-accent/10 to-accent/20">
<div class="stat">
<div class="stat-figure text-accent">
<BarChart3 class="h-8 w-8" strokeWidth={2} />
</div>
<div class="stat-title">CC / FG</div>
<div class="stat-value text-accent">
{statsQuery.data.cargoComissionado} / {statsQuery.data
.funcaoGratificada}
</div>
<div class="stat-desc">Distribuição</div>
</div>
</div>
</div>
{/if}
<!-- Menu de Opções -->
<div class="space-y-8">
{#each menuItems as categoria}
<div
class="card bg-base-100 shadow-xl hover:shadow-2xl transition-all duration-300"
>
<div class="card-body">
<!-- Cabeçalho da Categoria -->
<div class="flex items-start gap-6 mb-6">
<div class="p-4 {categoria.bgIcon} rounded-2xl">
<svelte:component
this={categoria.Icon}
class="h-12 w-12 {categoria.accentColor}"
strokeWidth={2}
/>
</div>
<div class="flex-1">
<h2 class="card-title text-2xl mb-2 {categoria.accentColor}">
{categoria.categoria}
</h2>
<p class="text-base-content/70">{categoria.descricao}</p>
</div>
</div>
<!-- Grid de Opções -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
{#each categoria.opcoes as opcao}
<a
href={opcao.href}
class="group relative overflow-hidden rounded-xl border-2 border-base-300 bg-linear-to-br {categoria.gradient} p-6 hover:border-primary hover:shadow-lg transition-all duration-300 transform hover:-translate-y-1"
>
<div class="flex flex-col h-full">
<div class="flex items-start justify-between mb-4">
<div
class="p-3 bg-base-100 rounded-lg group-hover:bg-primary group-hover:text-white transition-colors duration-300"
>
<svelte:component
this={opcao.Icon}
class="h-5 w-5 {categoria.accentColor} group-hover:text-white transition-colors duration-300"
strokeWidth={2}
/>
</div>
<ChevronRight
class="h-5 w-5 text-base-content/30 group-hover:text-primary transition-colors duration-300"
strokeWidth={2}
/>
</div>
<h3
class="text-lg font-bold text-base-content mb-2 group-hover:text-primary transition-colors duration-300"
>
{opcao.nome}
</h3>
<p class="text-sm text-base-content/70 flex-1">
{opcao.descricao}
</p>
</div>
</a>
{/each}
</div>
</div>
</div>
{/each}
</div>
<!-- Card de Ajuda -->
<div class="alert alert-info shadow-lg mt-8">
<Info class="stroke-current shrink-0 w-6 h-6" strokeWidth={2} />
<div>
<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>