feat: implement absence management features in the dashboard
- Added functionality for managing absence requests, including listing, approving, and rejecting requests. - Enhanced the user interface to display statistics and pending requests for better oversight. - Updated backend schema to support absence requests and notifications, ensuring data integrity and efficient handling. - Integrated new components for absence request forms and approval workflows, improving user experience and administrative efficiency.
This commit is contained in:
@@ -4,13 +4,15 @@
|
||||
import { authStore } from "$lib/stores/auth.svelte";
|
||||
import AprovarFerias from "$lib/components/AprovarFerias.svelte";
|
||||
import WizardSolicitacaoFerias from "$lib/components/ferias/WizardSolicitacaoFerias.svelte";
|
||||
import WizardSolicitacaoAusencia from "$lib/components/ausencias/WizardSolicitacaoAusencia.svelte";
|
||||
import AprovarAusencias from "$lib/components/AprovarAusencias.svelte";
|
||||
import { generateAvatarGallery, type Avatar } from "$lib/utils/avatars";
|
||||
import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
|
||||
import { page } from "$app/stores";
|
||||
|
||||
const client = useConvexClient();
|
||||
|
||||
let abaAtiva = $state<"meu-perfil" | "minhas-ferias" | "aprovar-ferias">(
|
||||
let abaAtiva = $state<"meu-perfil" | "minhas-ferias" | "minhas-ausencias" | "aprovar-ferias" | "aprovar-ausencias">(
|
||||
"meu-perfil"
|
||||
);
|
||||
let solicitacaoSelecionada = $state<any>(null);
|
||||
@@ -29,6 +31,14 @@
|
||||
let mostrarWizard = $state(false);
|
||||
let filtroStatusFerias = $state<string>("todos");
|
||||
|
||||
// Estados para Minhas Ausências
|
||||
let mostrarWizardAusencia = $state(false);
|
||||
let filtroStatusAusencias = $state<string>("todos");
|
||||
let solicitacaoAusenciaSelecionada = $state<Id<"solicitacoesAusencias"> | null>(null);
|
||||
|
||||
// Estados para Aprovar Ausências (Gestores)
|
||||
let solicitacaoAusenciaAprovar = $state<Id<"solicitacoesAusencias"> | null>(null);
|
||||
|
||||
// Galeria de avatares (30 avatares profissionais 3D realistas)
|
||||
const avatarGallery = generateAvatarGallery(30);
|
||||
|
||||
@@ -42,10 +52,15 @@
|
||||
}
|
||||
});
|
||||
|
||||
// FuncionarioId disponível diretamente do authStore
|
||||
const funcionarioIdDisponivel = $derived(authStore.usuario?.funcionarioId ?? null);
|
||||
|
||||
// Debug: Verificar funcionarioId
|
||||
$effect(() => {
|
||||
console.log("🔍 [Perfil] funcionarioId:", authStore.usuario?.funcionarioId);
|
||||
console.log("🔍 [Perfil] Usuário completo:", authStore.usuario);
|
||||
console.log("🔍 [Perfil] funcionarioIdDisponivel:", funcionarioIdDisponivel);
|
||||
console.log("🔍 [Perfil] Botão habilitado?", !!funcionarioIdDisponivel);
|
||||
});
|
||||
|
||||
// Queries
|
||||
@@ -65,6 +80,14 @@
|
||||
: { data: [] }
|
||||
);
|
||||
|
||||
const ausenciasSubordinadosQuery = $derived(
|
||||
authStore.usuario?._id
|
||||
? useQuery(api.ausencias.listarSolicitacoesSubordinados, {
|
||||
gestorId: authStore.usuario._id as Id<"usuarios">,
|
||||
})
|
||||
: { data: [] }
|
||||
);
|
||||
|
||||
const minhasSolicitacoesQuery = $derived(
|
||||
funcionarioQuery.data
|
||||
? useQuery(api.ferias.listarMinhasSolicitacoes, {
|
||||
@@ -73,6 +96,14 @@
|
||||
: { data: [] }
|
||||
);
|
||||
|
||||
const minhasAusenciasQuery = $derived(
|
||||
funcionarioQuery.data
|
||||
? useQuery(api.ausencias.listarMinhasSolicitacoes, {
|
||||
funcionarioId: funcionarioQuery.data._id,
|
||||
})
|
||||
: { data: [] }
|
||||
);
|
||||
|
||||
const meuTimeQuery = $derived(
|
||||
funcionarioQuery.data
|
||||
? useQuery(api.times.obterTimeFuncionario, {
|
||||
@@ -93,7 +124,11 @@
|
||||
const solicitacoesSubordinados = $derived(
|
||||
solicitacoesSubordinadosQuery?.data || []
|
||||
);
|
||||
const ausenciasSubordinados = $derived(
|
||||
ausenciasSubordinadosQuery?.data || []
|
||||
);
|
||||
const minhasSolicitacoes = $derived(minhasSolicitacoesQuery?.data || []);
|
||||
const minhasAusencias = $derived(minhasAusenciasQuery?.data || []);
|
||||
const meuTime = $derived(meuTimeQuery?.data);
|
||||
const meusTimesGestor = $derived(meusTimesGestorQuery?.data || []);
|
||||
|
||||
@@ -108,6 +143,14 @@
|
||||
})
|
||||
);
|
||||
|
||||
// Filtrar minhas ausências
|
||||
const ausenciasFiltradas = $derived(
|
||||
minhasAusencias.filter((a) => {
|
||||
if (filtroStatusAusencias !== "todos" && a.status !== filtroStatusAusencias) return false;
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
// Estatísticas das minhas férias
|
||||
const statsMinhasFerias = $derived({
|
||||
total: minhasSolicitacoes.length,
|
||||
@@ -117,6 +160,14 @@
|
||||
emFerias: funcionario?.statusFerias === "em_ferias" ? 1 : 0,
|
||||
});
|
||||
|
||||
// Estatísticas das minhas ausências
|
||||
const statsMinhasAusencias = $derived({
|
||||
total: minhasAusencias.length,
|
||||
aguardando: minhasAusencias.filter((a) => a.status === "aguardando_aprovacao").length,
|
||||
aprovadas: minhasAusencias.filter((a) => a.status === "aprovado").length,
|
||||
reprovadas: minhasAusencias.filter((a) => a.status === "reprovado").length,
|
||||
});
|
||||
|
||||
async function recarregar() {
|
||||
solicitacaoSelecionada = null;
|
||||
}
|
||||
@@ -512,6 +563,29 @@
|
||||
Minhas Férias
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
class={`tab tab-lg font-semibold transition-all duration-300 ${abaAtiva === "minhas-ausencias" ? "tab-active bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg scale-105" : "hover:bg-base-100"}`}
|
||||
onclick={() => (abaAtiva = "minhas-ausencias")}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5 mr-2"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
Minhas Ausências
|
||||
</button>
|
||||
|
||||
{#if ehGestor}
|
||||
<button
|
||||
type="button"
|
||||
@@ -542,6 +616,36 @@
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
class={`tab tab-lg font-semibold transition-all duration-300 ${abaAtiva === "aprovar-ausencias" ? "tab-active bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg scale-105" : "hover:bg-base-100"}`}
|
||||
onclick={() => (abaAtiva = "aprovar-ausencias")}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5 mr-2"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
Aprovar Ausências
|
||||
{#if (ausenciasSubordinados || []).filter((a: any) => a.status === "aguardando_aprovacao").length > 0}
|
||||
<span class="badge badge-error badge-sm ml-2 animate-pulse">
|
||||
{(ausenciasSubordinados || []).filter(
|
||||
(a: any) => a.status === "aguardando_aprovacao"
|
||||
).length}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1221,6 +1325,151 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else if abaAtiva === "minhas-ausencias"}
|
||||
<!-- Minhas Ausências -->
|
||||
<div class="space-y-6">
|
||||
<!-- Estatísticas -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-base-300">
|
||||
<div class="stat-figure text-orange-500">
|
||||
<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="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Total</div>
|
||||
<div class="stat-value text-orange-500">{statsMinhasAusencias.total}</div>
|
||||
<div class="stat-desc">Solicitações</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-warning/30">
|
||||
<div class="stat-figure text-warning">
|
||||
<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="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Aguardando</div>
|
||||
<div class="stat-value text-warning">{statsMinhasAusencias.aguardando}</div>
|
||||
<div class="stat-desc">Pendentes</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-success/30">
|
||||
<div class="stat-figure text-success">
|
||||
<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="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Aprovadas</div>
|
||||
<div class="stat-value text-success">{statsMinhasAusencias.aprovadas}</div>
|
||||
<div class="stat-desc">Deferidas</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-error/30">
|
||||
<div class="stat-figure text-error">
|
||||
<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="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Reprovadas</div>
|
||||
<div class="stat-value text-error">{statsMinhasAusencias.reprovadas}</div>
|
||||
<div class="stat-desc">Indeferidas</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtros e Botão Nova Solicitação -->
|
||||
<div class="card bg-base-100 shadow-lg">
|
||||
<div class="card-body">
|
||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
|
||||
<h2 class="card-title text-lg">Filtros</h2>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-warning gap-2"
|
||||
onclick={() => {
|
||||
const funcionarioId = authStore.usuario?.funcionarioId;
|
||||
console.log("🔍 [Perfil] Click no botão - funcionarioId:", funcionarioId);
|
||||
if (funcionarioId) {
|
||||
mostrarWizardAusencia = true;
|
||||
} else {
|
||||
alert(`Não foi possível identificar seu funcionário.\n\nVerifique no console (F12) o objeto usuario:\n${JSON.stringify(authStore.usuario, null, 2)}\n\nEntre em contato com o suporte se o problema persistir.`);
|
||||
}
|
||||
}}
|
||||
disabled={!funcionarioIdDisponivel}
|
||||
title={funcionarioIdDisponivel ? "Clique para solicitar uma ausência" : "Funcionário não identificado. Entre em contato com o suporte."}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
Solicitar Ausência
|
||||
</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-1 gap-4 mt-4">
|
||||
<div class="form-control">
|
||||
<label class="label" for="status-ausencias">
|
||||
<span class="label-text">Status</span>
|
||||
</label>
|
||||
<select id="status-ausencias" class="select select-bordered" bind:value={filtroStatusAusencias}>
|
||||
<option value="todos">Todos</option>
|
||||
<option value="aguardando_aprovacao">Aguardando Aprovação</option>
|
||||
<option value="aprovado">Aprovado</option>
|
||||
<option value="reprovado">Reprovado</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Lista de Solicitações -->
|
||||
<div class="card bg-base-100 shadow-lg">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-lg mb-4">
|
||||
Minhas Solicitações ({ausenciasFiltradas.length})
|
||||
</h2>
|
||||
|
||||
{#if ausenciasFiltradas.length === 0}
|
||||
<div class="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-info 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>Nenhuma solicitação encontrada com os filtros aplicados.</span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-zebra">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Período</th>
|
||||
<th>Dias</th>
|
||||
<th>Motivo</th>
|
||||
<th>Status</th>
|
||||
<th>Solicitado em</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each ausenciasFiltradas as ausencia}
|
||||
<tr>
|
||||
<td>
|
||||
{new Date(ausencia.dataInicio).toLocaleDateString("pt-BR")} até {new Date(ausencia.dataFim).toLocaleDateString("pt-BR")}
|
||||
</td>
|
||||
<td class="font-bold">
|
||||
{Math.ceil((new Date(ausencia.dataFim).getTime() - new Date(ausencia.dataInicio).getTime()) / (1000 * 60 * 60 * 24)) + 1} dias
|
||||
</td>
|
||||
<td class="max-w-xs truncate" title={ausencia.motivo}>
|
||||
{ausencia.motivo}
|
||||
</td>
|
||||
<td>
|
||||
<div class={`badge ${getStatusBadge(ausencia.status)}`}>
|
||||
{getStatusTexto(ausencia.status)}
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-xs">{new Date(ausencia.criadoEm).toLocaleDateString("pt-BR")}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else if abaAtiva === "aprovar-ferias"}
|
||||
<!-- Aprovar Férias (Gestores) PREMIUM -->
|
||||
<div class="card bg-base-100 shadow-2xl border-t-4 border-green-500">
|
||||
@@ -1379,10 +1628,162 @@
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else if abaAtiva === "aprovar-ausencias"}
|
||||
<!-- Aprovar Ausências (Gestores) -->
|
||||
<div class="card bg-base-100 shadow-2xl border-t-4 border-orange-500">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-2xl mb-6 flex items-center gap-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-7 w-7 text-orange-600"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
Solicitações de Ausências da Equipe
|
||||
<div class="badge badge-lg badge-warning ml-2">
|
||||
{ausenciasSubordinados.length}
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
{#if ausenciasSubordinados.length === 0}
|
||||
<div class="alert alert-success">
|
||||
<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="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<span class="font-semibold"
|
||||
>Nenhuma solicitação pendente no momento.</span
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-zebra table-lg">
|
||||
<thead>
|
||||
<tr class="bg-base-200">
|
||||
<th class="font-bold">Funcionário</th>
|
||||
<th class="font-bold">Time</th>
|
||||
<th class="font-bold">Período</th>
|
||||
<th class="font-bold">Dias</th>
|
||||
<th class="font-bold">Status</th>
|
||||
<th class="font-bold">Ações</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each ausenciasSubordinados as ausencia}
|
||||
<tr class="hover:bg-base-200 transition-colors">
|
||||
<td>
|
||||
<div class="font-bold">
|
||||
{ausencia.funcionario?.nome || "N/A"}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{#if ausencia.time}
|
||||
<div
|
||||
class="badge badge-lg font-semibold"
|
||||
style="background-color: {ausencia.time.cor}20; border-color: {ausencia.time.cor}; color: {ausencia.time.cor}"
|
||||
>
|
||||
{ausencia.time.nome}
|
||||
</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="font-semibold">
|
||||
{new Date(ausencia.dataInicio).toLocaleDateString("pt-BR")} até{" "}
|
||||
{new Date(ausencia.dataFim).toLocaleDateString("pt-BR")}
|
||||
</td>
|
||||
<td class="font-bold text-lg">
|
||||
{Math.ceil((new Date(ausencia.dataFim).getTime() - new Date(ausencia.dataInicio).getTime()) / (1000 * 60 * 60 * 24)) + 1} dias
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
class={`badge badge-lg font-semibold ${getStatusBadge(ausencia.status)}`}
|
||||
>
|
||||
{getStatusTexto(ausencia.status)}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{#if ausencia.status === "aguardando_aprovacao"}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-warning btn-sm gap-2 shadow-lg hover:scale-105 transition-transform"
|
||||
onclick={() =>
|
||||
(solicitacaoAusenciaAprovar = ausencia._id)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
|
||||
/>
|
||||
</svg>
|
||||
Analisar
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-ghost btn-sm gap-2"
|
||||
onclick={() =>
|
||||
(solicitacaoAusenciaAprovar = ausencia._id)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4"
|
||||
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>
|
||||
Detalhes
|
||||
</button>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Modal de Aprovação -->
|
||||
<!-- Modal de Aprovação de Férias -->
|
||||
{#if solicitacaoSelecionada}
|
||||
<dialog class="modal modal-open">
|
||||
<div class="modal-box max-w-4xl">
|
||||
@@ -1716,3 +2117,56 @@
|
||||
<div class="modal-backdrop" onclick={() => (mostrarWizard = false)}></div>
|
||||
</dialog>
|
||||
{/if}
|
||||
|
||||
<!-- Modal Wizard Solicitação de Ausência -->
|
||||
{#if mostrarWizardAusencia && funcionarioIdDisponivel}
|
||||
<dialog class="modal modal-open">
|
||||
<div class="modal-box max-w-4xl max-h-[90vh] overflow-hidden">
|
||||
<h3 class="font-bold text-2xl mb-6 text-center">
|
||||
Nova Solicitação de Ausência
|
||||
</h3>
|
||||
<div class="max-h-[80vh] overflow-y-auto">
|
||||
<WizardSolicitacaoAusencia
|
||||
funcionarioId={funcionarioIdDisponivel}
|
||||
onSucesso={() => {
|
||||
mostrarWizardAusencia = false;
|
||||
}}
|
||||
onCancelar={() => (mostrarWizardAusencia = false)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div class="modal-backdrop" onclick={() => (mostrarWizardAusencia = false)}></div>
|
||||
</dialog>
|
||||
{/if}
|
||||
|
||||
<!-- Modal de Aprovação de Ausências -->
|
||||
{#if solicitacaoAusenciaAprovar && authStore.usuario}
|
||||
{#await client.query(api.ausencias.obterDetalhes, {
|
||||
solicitacaoId: solicitacaoAusenciaAprovar,
|
||||
}) then detalhes}
|
||||
{#if detalhes}
|
||||
<dialog class="modal modal-open">
|
||||
<div class="modal-box max-w-4xl">
|
||||
<AprovarAusencias
|
||||
solicitacao={detalhes}
|
||||
gestorId={authStore.usuario._id}
|
||||
onSucesso={() => {
|
||||
solicitacaoAusenciaAprovar = null;
|
||||
}}
|
||||
onCancelar={() => (solicitacaoAusenciaAprovar = null)}
|
||||
/>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (solicitacaoAusenciaAprovar = null)}
|
||||
aria-label="Fechar modal"
|
||||
>Fechar</button
|
||||
>
|
||||
</form>
|
||||
</dialog>
|
||||
{/if}
|
||||
{/await}
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user