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.
This commit is contained in:
2025-11-18 11:44:12 -03:00
parent 52123a33b3
commit f0c6e4468f
22 changed files with 3604 additions and 128 deletions

View File

@@ -11,7 +11,28 @@
import ProtectedRoute from '$lib/components/ProtectedRoute.svelte';
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
import type { FunctionReturnType } from 'convex/server';
import { X, Calendar, Users, Clock, CheckCircle2, Eye, FileCheck, CalendarDays, User, Mail, Shield, Briefcase, Hash, CreditCard, Building2, CheckCircle, ListChecks, Info } from 'lucide-svelte';
import {
X,
Calendar,
Users,
Clock,
CheckCircle2,
Eye,
FileCheck,
CalendarDays,
User,
Mail,
Shield,
Briefcase,
Hash,
CreditCard,
Building2,
CheckCircle,
ListChecks,
Info,
Fingerprint
} from 'lucide-svelte';
import RegistroPonto from '$lib/components/ponto/RegistroPonto.svelte';
import TicketCard from '$lib/components/chamados/TicketCard.svelte';
import TicketTimeline from '$lib/components/chamados/TicketTimeline.svelte';
import { chamadosStore } from '$lib/stores/chamados';
@@ -45,6 +66,7 @@
| 'minhas-ausencias'
| 'aprovar-ferias'
| 'aprovar-ausencias'
| 'meu-ponto'
>('meu-perfil');
let periodoSelecionado = $state<Id<'ferias'> | null>(null);
@@ -216,11 +238,7 @@
if (!selectedTicketId && chamadosQuery.data.length > 0) {
selectedTicketId = chamadosQuery.data[0]._id;
}
} else if (
chamadosQuery !== undefined &&
chamadosQuery?.data === null &&
!gestorIdDisponivel
) {
} else if (chamadosQuery !== undefined && chamadosQuery?.data === null && !gestorIdDisponivel) {
chamadosEstaveis = [];
chamadosStore.setTickets([]);
}
@@ -703,12 +721,12 @@
<!-- Tabs PREMIUM -->
<div
role="tablist"
class="tabs tabs-boxed from-base-200 to-base-300 mb-8 bg-gradient-to-r p-2 shadow-xl rounded-xl border border-base-300"
class="tabs tabs-boxed from-base-200 to-base-300 border-base-300 mb-8 rounded-xl border bg-gradient-to-r p-2 shadow-xl"
>
<button
type="button"
role="tab"
class={`tab tab-lg font-semibold transition-all duration-300 gap-2 ${abaAtiva === 'meu-perfil' ? 'tab-active scale-105 bg-gradient-to-r from-purple-600 to-blue-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'meu-perfil' ? 'tab-active scale-105 bg-gradient-to-r from-purple-600 to-blue-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
onclick={() => (abaAtiva = 'meu-perfil')}
>
<User class="h-5 w-5" strokeWidth={2} />
@@ -718,7 +736,7 @@
<button
type="button"
role="tab"
class={`tab tab-lg font-semibold transition-all duration-300 gap-2 ${abaAtiva === 'meus-chamados' ? 'tab-active scale-105 bg-gradient-to-r from-purple-600 to-blue-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'meus-chamados' ? 'tab-active scale-105 bg-gradient-to-r from-purple-600 to-blue-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
onclick={() => (abaAtiva = 'meus-chamados')}
aria-label="Meus Chamados"
>
@@ -730,7 +748,7 @@
<button
type="button"
role="tab"
class={`tab tab-lg font-semibold transition-all duration-300 gap-2 ${abaAtiva === 'minhas-ferias' ? 'tab-active scale-105 bg-gradient-to-r from-purple-600 to-blue-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'minhas-ferias' ? 'tab-active scale-105 bg-gradient-to-r from-purple-600 to-blue-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
onclick={() => (abaAtiva = 'minhas-ferias')}
>
<Calendar class="h-5 w-5" strokeWidth={2} />
@@ -740,7 +758,7 @@
<button
type="button"
role="tab"
class={`tab tab-lg font-semibold transition-all duration-300 gap-2 ${abaAtiva === 'minhas-ausencias' ? 'tab-active scale-105 bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'minhas-ausencias' ? 'tab-active scale-105 bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
onclick={() => (abaAtiva = 'minhas-ausencias')}
>
<Clock class="h-5 w-5" strokeWidth={2} />
@@ -751,7 +769,7 @@
<button
type="button"
role="tab"
class={`tab tab-lg font-semibold transition-all duration-300 gap-2 ${abaAtiva === 'aprovar-ferias' ? 'tab-active scale-105 bg-gradient-to-r from-green-600 to-emerald-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'aprovar-ferias' ? 'tab-active scale-105 bg-gradient-to-r from-green-600 to-emerald-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
onclick={() => (abaAtiva = 'aprovar-ferias')}
>
<CheckCircle2 class="h-5 w-5" strokeWidth={2} />
@@ -768,7 +786,7 @@
<button
type="button"
role="tab"
class={`tab tab-lg font-semibold transition-all duration-300 gap-2 ${abaAtiva === 'aprovar-ausencias' ? 'tab-active scale-105 bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'aprovar-ausencias' ? 'tab-active scale-105 bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
onclick={() => (abaAtiva = 'aprovar-ausencias')}
>
<Clock class="h-5 w-5" strokeWidth={2} />
@@ -782,6 +800,16 @@
</button>
{/if}
{/if}
<button
type="button"
role="tab"
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'meu-ponto' ? 'tab-active scale-105 bg-gradient-to-r from-blue-600 to-cyan-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
onclick={() => (abaAtiva = 'meu-ponto')}
>
<Fingerprint class="h-5 w-5" strokeWidth={2} />
Meu Ponto
</button>
</div>
<!-- Conteúdo das Abas -->
@@ -915,19 +943,21 @@
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
<!-- Informações Pessoais PREMIUM -->
<div
class="card bg-gradient-to-br from-base-100 to-base-200 hover:shadow-3xl border-t-4 border-purple-500 shadow-2xl transition-shadow overflow-hidden"
class="card from-base-100 to-base-200 hover:shadow-3xl overflow-hidden border-t-4 border-purple-500 bg-gradient-to-br shadow-2xl transition-shadow"
>
<div class="card-body p-6">
<div class="flex items-center justify-between mb-6">
<div class="mb-6 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-purple-500 to-purple-600 shadow-lg ring-2 ring-purple-500/20">
<div
class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-purple-500 to-purple-600 shadow-lg ring-2 ring-purple-500/20"
>
<User class="h-6 w-6 text-white" strokeWidth={2.5} />
</div>
<div>
<h2 class="text-2xl font-bold text-base-content flex items-center gap-2">
<h2 class="text-base-content flex items-center gap-2 text-2xl font-bold">
Informações Pessoais
</h2>
<p class="text-sm text-base-content/60 mt-0.5">
<p class="text-base-content/60 mt-0.5 text-sm">
Seus dados pessoais e de acesso
</p>
</div>
@@ -935,45 +965,54 @@
</div>
<div class="space-y-3">
<div
class="hover:bg-base-200/60 flex items-start gap-3 rounded-lg border border-base-300/50 p-4 transition-all shadow-sm hover:shadow-md"
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
>
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-purple-500/20 to-purple-600/20">
<User class="text-purple-600 h-5 w-5" strokeWidth={2} />
<div
class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-purple-500/20 to-purple-600/20"
>
<User class="h-5 w-5 text-purple-600" strokeWidth={2} />
</div>
<div class="flex-1">
<span class="label-text text-base-content/60 text-xs font-semibold uppercase tracking-wide"
<span
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
>Nome Completo</span
>
<p class="text-base-content text-base font-semibold mt-1">
<p class="text-base-content mt-1 text-base font-semibold">
{currentUser.data?.nome}
</p>
</div>
</div>
<div
class="hover:bg-base-200/60 flex items-start gap-3 rounded-lg border border-base-300/50 p-4 transition-all shadow-sm hover:shadow-md"
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
>
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500/20 to-blue-600/20">
<Mail class="text-blue-600 h-5 w-5" strokeWidth={2} />
<div
class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500/20 to-blue-600/20"
>
<Mail class="h-5 w-5 text-blue-600" strokeWidth={2} />
</div>
<div class="flex-1">
<span class="label-text text-base-content/60 text-xs font-semibold uppercase tracking-wide"
<span
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
>E-mail Institucional</span
>
<p class="text-base-content text-base font-semibold break-all mt-1">
<p class="text-base-content mt-1 text-base font-semibold break-all">
{currentUser.data?.email}
</p>
</div>
</div>
<div
class="hover:bg-base-200/60 flex items-start gap-3 rounded-lg border border-base-300/50 p-4 transition-all shadow-sm hover:shadow-md"
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
>
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-primary/20 to-primary/30">
<div
class="from-primary/20 to-primary/30 flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br"
>
<Shield class="text-primary h-5 w-5" strokeWidth={2} />
</div>
<div class="flex-1">
<span class="label-text text-base-content/60 text-xs font-semibold uppercase tracking-wide"
<span
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
>Perfil de Acesso</span
>
<div class="badge badge-primary badge-lg mt-2 font-bold shadow-sm">
@@ -988,19 +1027,21 @@
<!-- Dados Funcionais PREMIUM -->
{#if funcionario}
<div
class="card bg-gradient-to-br from-base-100 to-base-200 hover:shadow-3xl border-t-4 border-blue-500 shadow-2xl transition-shadow overflow-hidden"
class="card from-base-100 to-base-200 hover:shadow-3xl overflow-hidden border-t-4 border-blue-500 bg-gradient-to-br shadow-2xl transition-shadow"
>
<div class="card-body p-6">
<div class="flex items-center justify-between mb-6">
<div class="mb-6 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-blue-500 to-blue-600 shadow-lg ring-2 ring-blue-500/20">
<div
class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-blue-500 to-blue-600 shadow-lg ring-2 ring-blue-500/20"
>
<Briefcase class="h-6 w-6 text-white" strokeWidth={2.5} />
</div>
<div>
<h2 class="text-2xl font-bold text-base-content flex items-center gap-2">
<h2 class="text-base-content flex items-center gap-2 text-2xl font-bold">
Dados Funcionais
</h2>
<p class="text-sm text-base-content/60 mt-0.5">
<p class="text-base-content/60 mt-0.5 text-sm">
Informações profissionais e organizacionais
</p>
</div>
@@ -1008,43 +1049,56 @@
</div>
<div class="space-y-3">
<div
class="hover:bg-base-200/60 flex items-start gap-3 rounded-lg border border-base-300/50 p-4 transition-all shadow-sm hover:shadow-md"
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
>
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500/20 to-blue-600/20">
<Hash class="text-blue-600 h-5 w-5" strokeWidth={2} />
<div
class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500/20 to-blue-600/20"
>
<Hash class="h-5 w-5 text-blue-600" strokeWidth={2} />
</div>
<div class="flex-1">
<span class="label-text text-base-content/60 text-xs font-semibold uppercase tracking-wide"
<span
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
>Matrícula</span
>
<p class="text-base-content text-base font-semibold mt-1">
<p class="text-base-content mt-1 text-base font-semibold">
{funcionario.matricula || 'Não informada'}
</p>
</div>
</div>
<div
class="hover:bg-base-200/60 flex items-start gap-3 rounded-lg border border-base-300/50 p-4 transition-all shadow-sm hover:shadow-md"
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
>
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-green-500/20 to-green-600/20">
<CreditCard class="text-green-600 h-5 w-5" strokeWidth={2} />
<div
class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-green-500/20 to-green-600/20"
>
<CreditCard class="h-5 w-5 text-green-600" strokeWidth={2} />
</div>
<div class="flex-1">
<span class="label-text text-base-content/60 text-xs font-semibold uppercase tracking-wide">CPF</span>
<p class="text-base-content text-base font-semibold mt-1">
<span
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
>CPF</span
>
<p class="text-base-content mt-1 text-base font-semibold">
{funcionario.cpf}
</p>
</div>
</div>
<div
class="hover:bg-base-200/60 flex items-start gap-3 rounded-lg border border-base-300/50 p-4 transition-all shadow-sm hover:shadow-md"
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
>
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500/20 to-orange-600/20">
<Building2 class="text-orange-600 h-5 w-5" strokeWidth={2} />
<div
class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500/20 to-orange-600/20"
>
<Building2 class="h-5 w-5 text-orange-600" strokeWidth={2} />
</div>
<div class="flex-1">
<span class="label-text text-base-content/60 text-xs font-semibold uppercase tracking-wide">Time</span>
<span
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
>Time</span
>
{#if meuTime}
<div class="mt-2">
<div
@@ -1064,13 +1118,16 @@
</div>
<div
class="hover:bg-base-200/60 flex items-start gap-3 rounded-lg border border-base-300/50 p-4 transition-all shadow-sm hover:shadow-md"
class="hover:bg-base-200/60 border-base-300/50 flex items-start gap-3 rounded-lg border p-4 shadow-sm transition-all hover:shadow-md"
>
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-success/20 to-success/30">
<div
class="from-success/20 to-success/30 flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br"
>
<CheckCircle class="text-success h-5 w-5" strokeWidth={2} />
</div>
<div class="flex-1">
<span class="label-text text-base-content/60 text-xs font-semibold uppercase tracking-wide"
<span
class="label-text text-base-content/60 text-xs font-semibold tracking-wide uppercase"
>Status Atual</span
>
{#if funcionario.statusFerias === 'em_ferias'}
@@ -1078,7 +1135,9 @@
🏖️ Em Férias
</div>
{:else}
<div class="badge badge-success badge-lg mt-2 font-bold shadow-sm">✅ Ativo</div>
<div class="badge badge-success badge-lg mt-2 font-bold shadow-sm">
✅ Ativo
</div>
{/if}
</div>
</div>
@@ -1091,12 +1150,10 @@
<!-- Times Gerenciados PREMIUM -->
{#if ehGestor}
<div
class="card border-t-4 border-warning bg-gradient-to-br from-warning/10 via-base-100 to-warning/5 shadow-2xl"
class="card border-warning from-warning/10 via-base-100 to-warning/5 border-t-4 bg-gradient-to-br shadow-2xl"
>
<div class="card-body">
<h2
class="card-title mb-6 flex items-center gap-2 text-2xl text-warning"
>
<h2 class="card-title text-warning mb-6 flex items-center gap-2 text-2xl">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-7 w-7"
@@ -1609,18 +1666,22 @@
</div>
<!-- Lista de Solicitações -->
<div class="card bg-gradient-to-br from-base-100 to-base-200 border-t-4 border-primary shadow-2xl overflow-hidden">
<div
class="card from-base-100 to-base-200 border-primary overflow-hidden border-t-4 bg-gradient-to-br shadow-2xl"
>
<div class="card-body p-6">
<div class="flex items-center justify-between mb-6">
<div class="mb-6 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-primary to-primary/80 shadow-lg ring-2 ring-primary/20">
<div
class="from-primary to-primary/80 ring-primary/20 flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br shadow-lg ring-2"
>
<ListChecks class="h-6 w-6 text-white" strokeWidth={2.5} />
</div>
<div>
<h2 class="text-2xl font-bold text-base-content flex items-center gap-2">
<h2 class="text-base-content flex items-center gap-2 text-2xl font-bold">
Minhas Solicitações
</h2>
<p class="text-sm text-base-content/60 mt-0.5">
<p class="text-base-content/60 mt-0.5 text-sm">
Histórico de solicitações de férias
</p>
</div>
@@ -1632,32 +1693,42 @@
</div>
{#if solicitacoesFiltradas.length === 0}
<div class="alert alert-info shadow-lg border border-info/20">
<div class="alert alert-info border-info/20 border shadow-lg">
<Info class="h-6 w-6 shrink-0 stroke-current" strokeWidth={2} />
<span class="font-semibold">Nenhuma solicitação encontrada com os filtros aplicados.</span>
<span class="font-semibold"
>Nenhuma solicitação encontrada com os filtros aplicados.</span
>
</div>
{:else}
<div class="overflow-x-auto rounded-lg border border-base-300 shadow-inner">
<table class="table table-zebra">
<div class="border-base-300 overflow-x-auto rounded-lg border shadow-inner">
<table class="table-zebra table">
<thead>
<tr class="bg-gradient-to-r from-base-200 to-base-300">
<th class="font-bold text-base-content">Ano</th>
<th class="font-bold text-base-content">Período</th>
<th class="font-bold text-base-content">Dias</th>
<th class="font-bold text-base-content">Status</th>
<th class="font-bold text-base-content">Solicitado em</th>
<tr class="from-base-200 to-base-300 bg-gradient-to-r">
<th class="text-base-content font-bold">Ano</th>
<th class="text-base-content font-bold">Período</th>
<th class="text-base-content font-bold">Dias</th>
<th class="text-base-content font-bold">Status</th>
<th class="text-base-content font-bold">Solicitado em</th>
</tr>
</thead>
<tbody>
{#each solicitacoesFiltradas as periodo (periodo._id)}
<tr class="hover:bg-base-200/50 transition-all duration-200 border-b border-base-300">
<td class="font-semibold text-base-content/80">{periodo.anoReferencia}</td>
<td class="font-medium text-base-content/70">
<tr
class="hover:bg-base-200/50 border-base-300 border-b transition-all duration-200"
>
<td class="text-base-content/80 font-semibold">{periodo.anoReferencia}</td
>
<td class="text-base-content/70 font-medium">
<div class="flex items-center gap-1.5">
<CalendarDays class="h-3.5 w-3.5 text-base-content/50" strokeWidth={2} />
<span>{formatarDataString(periodo.dataInicio)} - {formatarDataString(
periodo.dataFim
)}</span>
<CalendarDays
class="text-base-content/50 h-3.5 w-3.5"
strokeWidth={2}
/>
<span
>{formatarDataString(periodo.dataInicio)} - {formatarDataString(
periodo.dataFim
)}</span
>
</div>
</td>
<td>
@@ -1666,11 +1737,13 @@
</div>
</td>
<td>
<div class={`badge badge-sm font-semibold shadow-sm ${getStatusBadge(periodo.status)}`}>
<div
class={`badge badge-sm font-semibold shadow-sm ${getStatusBadge(periodo.status)}`}
>
{getStatusTexto(periodo.status)}
</div>
</td>
<td class="text-xs text-base-content/60 font-medium"
<td class="text-base-content/60 text-xs font-medium"
>{new Date(periodo._creationTime).toLocaleDateString('pt-BR')}</td
>
</tr>
@@ -1973,18 +2046,22 @@
</div>
{:else if abaAtiva === 'aprovar-ferias'}
<!-- Aprovar Férias (Gestores) PREMIUM -->
<div class="card bg-gradient-to-br from-base-100 to-base-200 border-t-4 border-green-500 shadow-2xl overflow-hidden">
<div
class="card from-base-100 to-base-200 overflow-hidden border-t-4 border-green-500 bg-gradient-to-br shadow-2xl"
>
<div class="card-body p-6">
<div class="flex items-center justify-between mb-6">
<div class="mb-6 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-green-500 to-green-600 shadow-lg ring-2 ring-green-500/20">
<div
class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-green-500 to-green-600 shadow-lg ring-2 ring-green-500/20"
>
<Users class="h-6 w-6 text-white" strokeWidth={2.5} />
</div>
<div>
<h2 class="text-2xl font-bold text-base-content flex items-center gap-2">
<h2 class="text-base-content flex items-center gap-2 text-2xl font-bold">
Solicitações da Equipe
</h2>
<p class="text-sm text-base-content/60 mt-0.5">
<p class="text-base-content/60 mt-0.5 text-sm">
Gerencie as solicitações de férias da sua equipe
</p>
</div>
@@ -1996,29 +2073,31 @@
</div>
{#if solicitacoesSubordinados.length === 0}
<div class="alert alert-success shadow-lg border border-success/20">
<div class="alert alert-success border-success/20 border shadow-lg">
<CheckCircle2 class="h-6 w-6 shrink-0 stroke-current" strokeWidth={2} />
<span class="font-semibold">Nenhuma solicitação pendente no momento.</span>
</div>
{:else}
<div class="overflow-x-auto rounded-lg border border-base-300 shadow-inner">
<table class="table table-zebra">
<div class="border-base-300 overflow-x-auto rounded-lg border shadow-inner">
<table class="table-zebra table">
<thead>
<tr class="bg-gradient-to-r from-base-200 to-base-300">
<th class="font-bold text-base-content">Funcionário</th>
<th class="font-bold text-base-content">Time</th>
<th class="font-bold text-base-content">Ano</th>
<th class="font-bold text-base-content">Período</th>
<th class="font-bold text-base-content">Dias</th>
<th class="font-bold text-base-content">Status</th>
<th class="font-bold text-base-content text-center">Ações</th>
<tr class="from-base-200 to-base-300 bg-gradient-to-r">
<th class="text-base-content font-bold">Funcionário</th>
<th class="text-base-content font-bold">Time</th>
<th class="text-base-content font-bold">Ano</th>
<th class="text-base-content font-bold">Período</th>
<th class="text-base-content font-bold">Dias</th>
<th class="text-base-content font-bold">Status</th>
<th class="text-base-content text-center font-bold">Ações</th>
</tr>
</thead>
<tbody>
{#each solicitacoesSubordinados as periodo (periodo._id)}
<tr class="hover:bg-base-200/50 transition-all duration-200 border-b border-base-300">
<tr
class="hover:bg-base-200/50 border-base-300 border-b transition-all duration-200"
>
<td>
<div class="font-semibold text-base-content">
<div class="text-base-content font-semibold">
{periodo.funcionario?.nome}
</div>
</td>
@@ -2033,13 +2112,18 @@
</div>
{/if}
</td>
<td class="font-semibold text-base-content/80">{periodo.anoReferencia}</td>
<td class="font-medium text-base-content/70">
<td class="text-base-content/80 font-semibold">{periodo.anoReferencia}</td>
<td class="text-base-content/70 font-medium">
<div class="flex items-center gap-1.5">
<CalendarDays class="h-3.5 w-3.5 text-base-content/50" strokeWidth={2} />
<span>{formatarDataString(periodo.dataInicio)} - {formatarDataString(
periodo.dataFim
)}</span>
<CalendarDays
class="text-base-content/50 h-3.5 w-3.5"
strokeWidth={2}
/>
<span
>{formatarDataString(periodo.dataInicio)} - {formatarDataString(
periodo.dataFim
)}</span
>
</div>
</td>
<td>
@@ -2068,7 +2152,7 @@
{:else}
<button
type="button"
class="btn btn-ghost btn-sm gap-2 hover:bg-base-300 transition-all duration-200"
class="btn btn-ghost btn-sm hover:bg-base-300 gap-2 transition-all duration-200"
onclick={() => selecionarPeriodo(periodo._id)}
>
<Eye class="h-4 w-4" strokeWidth={2} />
@@ -2087,18 +2171,22 @@
</div>
{:else if abaAtiva === 'aprovar-ausencias'}
<!-- Aprovar Ausências (Gestores) -->
<div class="card bg-gradient-to-br from-base-100 to-base-200 border-t-4 border-orange-500 shadow-2xl overflow-hidden">
<div
class="card from-base-100 to-base-200 overflow-hidden border-t-4 border-orange-500 bg-gradient-to-br shadow-2xl"
>
<div class="card-body p-6">
<div class="flex items-center justify-between mb-6">
<div class="mb-6 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-orange-500 to-orange-600 shadow-lg ring-2 ring-orange-500/20">
<div
class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-orange-500 to-orange-600 shadow-lg ring-2 ring-orange-500/20"
>
<Clock class="h-6 w-6 text-white" strokeWidth={2.5} />
</div>
<div>
<h2 class="text-2xl font-bold text-base-content flex items-center gap-2">
<h2 class="text-base-content flex items-center gap-2 text-2xl font-bold">
Solicitações de Ausências da Equipe
</h2>
<p class="text-sm text-base-content/60 mt-0.5">
<p class="text-base-content/60 mt-0.5 text-sm">
Gerencie as solicitações de ausências da sua equipe
</p>
</div>
@@ -2110,28 +2198,30 @@
</div>
{#if ausenciasSubordinados.length === 0}
<div class="alert alert-success shadow-lg border border-success/20">
<div class="alert alert-success border-success/20 border shadow-lg">
<CheckCircle2 class="h-6 w-6 shrink-0 stroke-current" strokeWidth={2} />
<span class="font-semibold">Nenhuma solicitação pendente no momento.</span>
</div>
{:else}
<div class="overflow-x-auto rounded-lg border border-base-300 shadow-inner">
<table class="table table-zebra">
<div class="border-base-300 overflow-x-auto rounded-lg border shadow-inner">
<table class="table-zebra table">
<thead>
<tr class="bg-gradient-to-r from-base-200 to-base-300">
<th class="font-bold text-base-content">Funcionário</th>
<th class="font-bold text-base-content">Time</th>
<th class="font-bold text-base-content">Período</th>
<th class="font-bold text-base-content">Dias</th>
<th class="font-bold text-base-content">Status</th>
<th class="font-bold text-base-content text-center">Ações</th>
<tr class="from-base-200 to-base-300 bg-gradient-to-r">
<th class="text-base-content font-bold">Funcionário</th>
<th class="text-base-content font-bold">Time</th>
<th class="text-base-content font-bold">Período</th>
<th class="text-base-content font-bold">Dias</th>
<th class="text-base-content font-bold">Status</th>
<th class="text-base-content text-center font-bold">Ações</th>
</tr>
</thead>
<tbody>
{#each ausenciasSubordinados as ausencia (ausencia._id)}
<tr class="hover:bg-base-200/50 transition-all duration-200 border-b border-base-300">
<tr
class="hover:bg-base-200/50 border-base-300 border-b transition-all duration-200"
>
<td>
<div class="font-semibold text-base-content">
<div class="text-base-content font-semibold">
{ausencia.funcionario?.nome || 'N/A'}
</div>
</td>
@@ -2147,9 +2237,12 @@
</div>
{/if}
</td>
<td class="font-medium text-base-content/70">
<td class="text-base-content/70 font-medium">
<div class="flex items-center gap-1.5">
<CalendarDays class="h-3.5 w-3.5 text-base-content/50" strokeWidth={2} />
<CalendarDays
class="text-base-content/50 h-3.5 w-3.5"
strokeWidth={2}
/>
<span>
{new Date(ausencia.dataInicio).toLocaleDateString('pt-BR')} até
{new Date(ausencia.dataFim).toLocaleDateString('pt-BR')}
@@ -2186,7 +2279,7 @@
{:else}
<button
type="button"
class="btn btn-ghost btn-sm gap-2 hover:bg-base-300 transition-all duration-200"
class="btn btn-ghost btn-sm hover:bg-base-300 gap-2 transition-all duration-200"
onclick={() => (solicitacaoAusenciaAprovar = ausencia._id)}
>
<Eye class="h-4 w-4" strokeWidth={2} />
@@ -2465,6 +2558,34 @@
</form>
</dialog>
{/if}
{#if abaAtiva === 'meu-ponto'}
<!-- Meu Ponto -->
<div
class="card from-base-100 to-base-200 overflow-hidden border-t-4 border-blue-500 bg-gradient-to-br shadow-2xl"
>
<div class="card-body p-6">
<div class="mb-6 flex items-center justify-between">
<div class="flex items-center gap-3">
<div
class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-blue-500 to-blue-600 shadow-lg ring-2 ring-blue-500/20"
>
<Fingerprint class="h-6 w-6 text-white" strokeWidth={2.5} />
</div>
<div>
<h2 class="text-base-content flex items-center gap-2 text-2xl font-bold">
Meu Ponto
</h2>
<p class="text-base-content/60 mt-0.5 text-sm">
Registre sua entrada, saída e intervalos de trabalho
</p>
</div>
</div>
</div>
<RegistroPonto />
</div>
</div>
{/if}
</main>
</ProtectedRoute>