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:
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user