refactor: enhance employee management with regime de trabalho integration

- Added regime de trabalho selection to employee forms for better categorization.
- Updated backend validation to include regime de trabalho options for employees.
- Enhanced employee data handling by integrating regime de trabalho into various components.
- Removed the print modal for financial data to streamline the employee profile interface.
- Improved overall code clarity and maintainability across multiple files.
This commit is contained in:
2025-11-11 16:10:08 -03:00
parent 3cc774d7df
commit 8a0a4552f7
12 changed files with 3213 additions and 1802 deletions

View File

@@ -7,8 +7,7 @@
import AprovarAusencias from '$lib/components/AprovarAusencias.svelte';
import CalendarioAusencias from '$lib/components/ausencias/CalendarioAusencias.svelte';
import { generateAvatarGallery } from '$lib/utils/avatars';
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
import { page } from '$app/stores';
import type { Doc, Id } from '@sgse-app/backend/convex/_generated/dataModel';
import { X, Calendar } from 'lucide-svelte';
const client = useConvexClient();
@@ -17,7 +16,7 @@
let abaAtiva = $state<
'meu-perfil' | 'minhas-ferias' | 'minhas-ausencias' | 'aprovar-ferias' | 'aprovar-ausencias'
>('meu-perfil');
let solicitacaoSelecionada = $state<any>(null);
let solicitacaoSelecionada = $state<Doc<'solicitacoesFerias'> | null>(null);
let mostrarModalFoto = $state(false);
let uploadandoFoto = $state(false);
let erroUpload = $state('');
@@ -37,7 +36,6 @@
// 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);
@@ -294,8 +292,9 @@
`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 3000);
} catch (e: any) {
erroUpload = e.message || 'Erro ao fazer upload da foto';
} catch (e: unknown) {
const errorMessage = e instanceof Error ? e.message : String(e);
erroUpload = errorMessage || 'Erro ao fazer upload da foto';
// Reverter mudança local se houver erro
fotoPerfilLocal = currentUser?.data?.fotoPerfil || null;
avatarLocal = currentUser?.data?.avatar || null;
@@ -344,8 +343,9 @@
`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 3000);
} catch (e: any) {
erroUpload = e.message || 'Erro ao salvar avatar';
} catch (e: unknown) {
const errorMessage = e instanceof Error ? e.message : String(e);
erroUpload = errorMessage || 'Erro ao salvar avatar';
// Reverter mudança local se houver erro
avatarLocal = currentUser?.data?.avatar || null;
fotoPerfilLocal = currentUser?.data?.fotoPerfil || null;
@@ -632,11 +632,10 @@
/>
</svg>
Aprovar Férias
{#if (solicitacoesSubordinados || []).filter((s: any) => s.status === 'aguardando_aprovacao').length > 0}
{#if (solicitacoesSubordinados || []).filter((s) => s.status === 'aguardando_aprovacao').length > 0}
<span class="badge badge-error badge-sm ml-2 animate-pulse">
{(solicitacoesSubordinados || []).filter(
(s: any) => s.status === 'aguardando_aprovacao'
).length}
{(solicitacoesSubordinados || []).filter((s) => s.status === 'aguardando_aprovacao')
.length}
</span>
{/if}
</button>
@@ -662,9 +661,9 @@
/>
</svg>
Aprovar Ausências
{#if (ausenciasSubordinados || []).filter((a: any) => a.status === 'aguardando_aprovacao').length > 0}
{#if (ausenciasSubordinados || []).filter((a) => 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')
{(ausenciasSubordinados || []).filter((a) => a.status === 'aguardando_aprovacao')
.length}
</span>
{/if}
@@ -1113,7 +1112,7 @@
</div>
{:else}
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{#each meusTimesGestor as time}
{#each meusTimesGestor as time (time._id)}
<div
class="card dark:bg-base-100 border-l-4 bg-white shadow-xl transition-all hover:scale-105 hover:shadow-2xl"
style="border-color: {time.cor}"
@@ -1378,13 +1377,13 @@
</tr>
</thead>
<tbody>
{#each solicitacoesFiltradas as solicitacao}
{#each solicitacoesFiltradas as solicitacao (solicitacao._id)}
<tr>
<td>{solicitacao.anoReferencia}</td>
<td>{solicitacao.periodos.length} período(s)</td>
<td class="font-bold"
>{solicitacao.periodos.reduce(
(acc: number, p: any) => acc + p.diasCorridos,
(acc: number, p: { diasCorridos: number }) => acc + p.diasCorridos,
0
)} dias</td
>
@@ -1660,7 +1659,7 @@
</tr>
</thead>
<tbody>
{#each ausenciasFiltradas as ausencia}
{#each ausenciasFiltradas as ausencia (ausencia._id)}
<tr>
<td>
{new Date(ausencia.dataInicio).toLocaleDateString('pt-BR')} até {new Date(
@@ -1751,7 +1750,7 @@
</tr>
</thead>
<tbody>
{#each solicitacoesSubordinados as solicitacao}
{#each solicitacoesSubordinados as solicitacao (solicitacao._id)}
<tr class="hover:bg-base-200 transition-colors">
<td>
<div class="font-bold">
@@ -1774,7 +1773,7 @@
<td class="font-semibold">{solicitacao.periodos.length}</td>
<td class="text-lg font-bold"
>{solicitacao.periodos.reduce(
(acc: number, p: any) => acc + p.diasCorridos,
(acc: number, p: { diasCorridos: number }) => acc + p.diasCorridos,
0
)}</td
>
@@ -1902,7 +1901,7 @@
</tr>
</thead>
<tbody>
{#each ausenciasSubordinados as ausencia}
{#each ausenciasSubordinados as ausencia (ausencia._id)}
<tr class="hover:bg-base-200 transition-colors">
<td>
<div class="font-bold">
@@ -1921,7 +1920,7 @@
{/if}
</td>
<td class="font-semibold">
{new Date(ausencia.dataInicio).toLocaleDateString('pt-BR')} até{' '}
{new Date(ausencia.dataInicio).toLocaleDateString('pt-BR')} até
{new Date(ausencia.dataFim).toLocaleDateString('pt-BR')}
</td>
<td class="text-lg font-bold">
@@ -2121,7 +2120,7 @@
<div
class="bg-base-200 grid max-h-[500px] grid-cols-3 gap-4 overflow-y-auto rounded-2xl p-6 shadow-inner md:grid-cols-5 lg:grid-cols-6"
>
{#each avatarGallery as avatar}
{#each avatarGallery as avatar (avatar.url)}
<button
type="button"
class={`flex cursor-pointer flex-col items-center rounded-xl p-2 transition-all hover:scale-110 ${avatarSelecionado === avatar.url ? 'ring-primary bg-primary/10 scale-105 ring-4' : 'hover:ring-primary/50 hover:bg-base-100 hover:ring-2'}`}
@@ -2262,13 +2261,13 @@
</main>
<!-- Modal Wizard Solicitação de Férias -->
{#if mostrarWizard && funcionario}
{#if mostrarWizard && funcionarioIdDisponivel}
<dialog class="modal modal-open">
<div class="modal-box max-h-[90vh] max-w-4xl overflow-hidden">
<h3 class="mb-6 text-center text-2xl font-bold">Nova Solicitação de Férias</h3>
<div class="max-h-[80vh] overflow-y-auto">
<WizardSolicitacaoFerias
funcionarioId={funcionario._id}
funcionarioId={funcionarioIdDisponivel}
onSucesso={() => {
mostrarWizard = false;
}}