Merge remote-tracking branch 'origin' into feat-pedidos
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { CheckCircle2, Clock, XCircle } from 'lucide-svelte';
|
||||
import { Clock, CheckCircle2, XCircle, ChevronRight, TrendingUp } from 'lucide-svelte';
|
||||
import { resolve } from '$app/paths';
|
||||
</script>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Grid de Cards -->
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||||
<!-- Card 1: Gestão de Pontos -->
|
||||
<a
|
||||
href={resolve('/(dashboard)/recursos-humanos/registro-pontos')}
|
||||
@@ -27,20 +27,7 @@
|
||||
<div class="rounded-2xl bg-blue-500/20 p-4">
|
||||
<Clock class="h-8 w-8 text-blue-600" strokeWidth={2} />
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="text-base-content/30 h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 5l7 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
<ChevronRight class="text-base-content/30 h-5 w-5" strokeWidth={2} />
|
||||
</div>
|
||||
<h2 class="card-title mb-2 text-xl">Gestão de Pontos</h2>
|
||||
<p class="text-base-content/70">
|
||||
@@ -59,20 +46,7 @@
|
||||
<div class="rounded-2xl bg-green-500/20 p-4">
|
||||
<CheckCircle2 class="h-8 w-8 text-green-600" strokeWidth={2} />
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="text-base-content/30 h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 5l7 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
<ChevronRight class="text-base-content/30 h-5 w-5" strokeWidth={2} />
|
||||
</div>
|
||||
<h2 class="card-title mb-2 text-xl">Homologação de Registro</h2>
|
||||
<p class="text-base-content/70">
|
||||
@@ -92,20 +66,7 @@
|
||||
<div class="rounded-2xl bg-orange-500/20 p-4">
|
||||
<XCircle class="h-8 w-8 text-orange-600" strokeWidth={2} />
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="text-base-content/30 h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 5l7 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
<ChevronRight class="text-base-content/30 h-5 w-5" strokeWidth={2} />
|
||||
</div>
|
||||
<h2 class="card-title mb-2 text-xl">Dispensa de Registro</h2>
|
||||
<p class="text-base-content/70">
|
||||
@@ -113,5 +74,24 @@
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Card 4: Banco de Horas -->
|
||||
<a
|
||||
href={resolve('/(dashboard)/recursos-humanos/controle-ponto/banco-horas')}
|
||||
class="card bg-base-100 transform shadow-xl transition-all duration-300 hover:-translate-y-1 hover:shadow-2xl"
|
||||
>
|
||||
<div class="card-body">
|
||||
<div class="mb-4 flex items-start justify-between">
|
||||
<div class="rounded-2xl bg-purple-500/20 p-4">
|
||||
<TrendingUp class="h-8 w-8 text-purple-600" strokeWidth={2} />
|
||||
</div>
|
||||
<ChevronRight class="text-base-content/30 h-5 w-5" strokeWidth={2} />
|
||||
</div>
|
||||
<h2 class="card-title mb-2 text-xl">Banco de Horas</h2>
|
||||
<p class="text-base-content/70">
|
||||
Visão gerencial do banco de horas dos funcionários, com filtros, estatísticas e relatórios
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
import { useConvexClient, useQuery } from 'convex-svelte';
|
||||
import { AlertTriangle, Clock, Plus, Trash2, X } from 'lucide-svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import UserAvatar from '$lib/components/chat/UserAvatar.svelte';
|
||||
|
||||
const client = useConvexClient();
|
||||
|
||||
@@ -47,6 +48,7 @@
|
||||
_id: Id<'funcionarios'>;
|
||||
nome: string;
|
||||
matricula?: string;
|
||||
fotoPerfilUrl?: string | null;
|
||||
}> = [];
|
||||
for (const time of subordinados) {
|
||||
for (const membro of time.membros) {
|
||||
@@ -54,7 +56,8 @@
|
||||
funcs.push({
|
||||
_id: membro.funcionario._id,
|
||||
nome: membro.funcionario.nome,
|
||||
matricula: membro.funcionario.matricula
|
||||
matricula: membro.funcionario.matricula,
|
||||
fotoPerfilUrl: membro.funcionario.fotoPerfilUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -201,16 +204,23 @@
|
||||
{/if}
|
||||
</label>
|
||||
<div class="border-base-300 max-h-60 space-y-2 overflow-y-auto rounded-lg border p-4">
|
||||
{#each funcionarios as funcionario}
|
||||
{#each funcionarios as funcionario (funcionario._id)}
|
||||
<label
|
||||
class="hover:bg-base-200 flex cursor-pointer items-center justify-between rounded-lg p-3 transition-colors"
|
||||
>
|
||||
<span class="label-text font-medium">
|
||||
{funcionario.nome}
|
||||
{#if funcionario.matricula}
|
||||
<span class="text-base-content/60 ml-2">({funcionario.matricula})</span>
|
||||
{/if}
|
||||
</span>
|
||||
<div class="flex items-center gap-3">
|
||||
<UserAvatar
|
||||
fotoPerfilUrl={funcionario.fotoPerfilUrl}
|
||||
nome={funcionario.nome}
|
||||
size="sm"
|
||||
/>
|
||||
<span class="label-text font-medium">
|
||||
{funcionario.nome}
|
||||
{#if funcionario.matricula}
|
||||
<span class="text-base-content/60 ml-2">({funcionario.matricula})</span>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-primary"
|
||||
@@ -321,16 +331,24 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each dispensas as dispensa}
|
||||
{#each dispensas as dispensa (dispensa._id)}
|
||||
<tr>
|
||||
<td>
|
||||
{dispensa.funcionario?.nome || '-'}
|
||||
{#if dispensa.funcionario?.matricula}
|
||||
<br />
|
||||
<span class="text-base-content/70 text-sm">
|
||||
Mat: {dispensa.funcionario.matricula}
|
||||
</span>
|
||||
{/if}
|
||||
<div class="flex items-center gap-3">
|
||||
<UserAvatar
|
||||
fotoPerfilUrl={dispensa.fotoPerfilUrl}
|
||||
nome={dispensa.funcionario?.nome || 'Funcionário'}
|
||||
size="sm"
|
||||
/>
|
||||
<div>
|
||||
<div class="font-medium">{dispensa.funcionario?.nome || '-'}</div>
|
||||
{#if dispensa.funcionario?.matricula}
|
||||
<span class="text-base-content/70 text-sm">
|
||||
Mat: {dispensa.funcionario.matricula}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-sm">
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||
import { Clock, Edit, TrendingUp, Save, X, Trash2, Eye } from 'lucide-svelte';
|
||||
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
import { useConvexClient, useQuery } from 'convex-svelte';
|
||||
import {
|
||||
Clock,
|
||||
Edit,
|
||||
Eye,
|
||||
MoreVertical,
|
||||
Save,
|
||||
Trash2,
|
||||
TrendingDown,
|
||||
TrendingUp,
|
||||
X
|
||||
} from 'lucide-svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import UserAvatar from '$lib/components/chat/UserAvatar.svelte';
|
||||
import { formatarHoraPonto, getTipoRegistroLabel } from '$lib/utils/ponto';
|
||||
|
||||
const client = useConvexClient();
|
||||
@@ -45,8 +35,6 @@
|
||||
});
|
||||
|
||||
// Formulário de edição
|
||||
let horaNova = $state(8);
|
||||
let minutoNova = $state(0);
|
||||
let motivoId = $state('');
|
||||
let motivoTipo = $state('');
|
||||
let motivoDescricao = $state('');
|
||||
@@ -141,6 +129,7 @@
|
||||
};
|
||||
});
|
||||
|
||||
// svelte-ignore state_referenced_locally
|
||||
const homologacoesQuery = useQuery(api.pontos.listarHomologacoes, homologacoesParams);
|
||||
let registrosQuery = $derived(
|
||||
registrosQueryParams ? useQuery(api.pontos.listarRegistrosPeriodo, registrosQueryParams) : null
|
||||
@@ -172,6 +161,7 @@
|
||||
_id: Id<'funcionarios'>;
|
||||
nome: string;
|
||||
matricula?: string;
|
||||
fotoPerfilUrl?: string | null;
|
||||
}> = [];
|
||||
for (const time of subordinados) {
|
||||
for (const membro of time.membros) {
|
||||
@@ -179,7 +169,8 @@
|
||||
funcs.push({
|
||||
_id: membro.funcionario._id,
|
||||
nome: membro.funcionario.nome,
|
||||
matricula: membro.funcionario.matricula
|
||||
matricula: membro.funcionario.matricula,
|
||||
fotoPerfilUrl: membro.funcionario.fotoPerfilUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -187,29 +178,11 @@
|
||||
return funcs;
|
||||
});
|
||||
|
||||
function abrirEdicao(registroId: Id<'registrosPonto'>) {
|
||||
const registro = registros.find((r) => r._id === registroId);
|
||||
if (!registro) return;
|
||||
|
||||
registroSelecionado = registroId;
|
||||
horaNova = registro.hora;
|
||||
minutoNova = registro.minuto;
|
||||
novaHoraFormatada = horaMinutoParaTime(registro.hora, registro.minuto);
|
||||
motivoId = '';
|
||||
motivoTipo = '';
|
||||
motivoDescricao = '';
|
||||
observacoes = '';
|
||||
modoEdicao = true;
|
||||
abaAtiva = 'editar';
|
||||
}
|
||||
|
||||
function abrirEdicaoComAjuste(registroId: Id<'registrosPonto'>) {
|
||||
const registro = registros.find((r) => r._id === registroId);
|
||||
if (!registro) return;
|
||||
|
||||
registroSelecionado = registroId;
|
||||
horaNova = registro.hora;
|
||||
minutoNova = registro.minuto;
|
||||
novaHoraFormatada = horaMinutoParaTime(registro.hora, registro.minuto);
|
||||
motivoId = '';
|
||||
motivoTipo = '';
|
||||
@@ -390,16 +363,17 @@
|
||||
<h2 class="card-title mb-4">Selecionar Funcionário</h2>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="funcionario-select">
|
||||
<span class="label-text font-medium">Funcionário</span>
|
||||
</label>
|
||||
<select
|
||||
class="select select-bordered w-full"
|
||||
id="funcionario-select"
|
||||
bind:value={funcionarioSelecionado}
|
||||
disabled={modoEdicao}
|
||||
>
|
||||
<option value="">Selecione um funcionário</option>
|
||||
{#each funcionarios as funcionario}
|
||||
{#each funcionarios as funcionario (funcionario._id)}
|
||||
<option value={funcionario._id as string}>
|
||||
{funcionario.nome}
|
||||
{funcionario.matricula ? `(${funcionario.matricula})` : ''}
|
||||
@@ -408,24 +382,26 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="data-inicio-filtro">
|
||||
<span class="label-text font-medium">Data Início</span>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
class="input input-bordered w-full"
|
||||
id="data-inicio-filtro"
|
||||
bind:value={dataInicioFiltro}
|
||||
disabled={modoEdicao}
|
||||
max={dataFimFiltro}
|
||||
/>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="data-fim-filtro">
|
||||
<span class="label-text font-medium">Data Fim</span>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
class="input input-bordered w-full"
|
||||
id="data-fim-filtro"
|
||||
bind:value={dataFimFiltro}
|
||||
disabled={modoEdicao}
|
||||
min={dataInicioFiltro}
|
||||
@@ -488,7 +464,7 @@
|
||||
<div class="space-y-8">
|
||||
<!-- Card: Nova Hora -->
|
||||
<div
|
||||
class="card from-primary/5 to-primary/10 border-primary/20 border bg-gradient-to-br shadow-sm"
|
||||
class="card from-primary/5 to-primary/10 border-primary/20 border bg-linear-to-br shadow-sm"
|
||||
>
|
||||
<div class="card-body p-6">
|
||||
<div class="mb-4 flex items-center gap-3">
|
||||
@@ -521,17 +497,18 @@
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="motivo-tipo-edicao">
|
||||
<span class="label-text font-semibold">Tipo de Motivo</span>
|
||||
<span class="label-text-alt text-error font-bold">*</span>
|
||||
</label>
|
||||
<select
|
||||
class="select select-bordered select-primary w-full"
|
||||
id="motivo-tipo-edicao"
|
||||
bind:value={motivoTipo}
|
||||
>
|
||||
<option value="">Selecione um tipo</option>
|
||||
{#if motivos?.opcoesPadrao}
|
||||
{#each motivos.opcoesPadrao as opcao}
|
||||
{#each motivos.opcoesPadrao as opcao (opcao)}
|
||||
<option value={opcao}>{opcao}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
@@ -539,12 +516,13 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="motivo-descricao-edicao">
|
||||
<span class="label-text font-semibold">Descrição do Motivo</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
class="input input-bordered input-primary w-full"
|
||||
id="motivo-descricao-edicao"
|
||||
bind:value={motivoDescricao}
|
||||
placeholder="Informe detalhes adicionais sobre o motivo"
|
||||
/>
|
||||
@@ -590,7 +568,7 @@
|
||||
<div class="space-y-8">
|
||||
<!-- Card: Tipo de Ajuste -->
|
||||
<div
|
||||
class="card from-warning/5 to-warning/10 border-warning/20 border bg-gradient-to-br shadow-sm"
|
||||
class="card from-warning/5 to-warning/10 border-warning/20 border bg-linear-to-br shadow-sm"
|
||||
>
|
||||
<div class="card-body p-6">
|
||||
<div class="mb-4 flex items-center gap-3">
|
||||
@@ -645,25 +623,27 @@
|
||||
</h4>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="data-inicio-ajuste">
|
||||
<span class="label-text font-semibold">Data Início</span>
|
||||
<span class="label-text-alt text-error font-bold">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
class="input input-bordered input-primary w-full"
|
||||
id="data-inicio-ajuste"
|
||||
bind:value={dataInicioAjuste}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="hora-inicio-ajuste">
|
||||
<span class="label-text font-semibold">Hora Início</span>
|
||||
<span class="label-text-alt text-error font-bold">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="time"
|
||||
class="input input-bordered input-primary w-full"
|
||||
id="hora-inicio-ajuste"
|
||||
bind:value={horaInicioAjuste}
|
||||
/>
|
||||
</div>
|
||||
@@ -685,26 +665,28 @@
|
||||
</h4>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="data-fim-ajuste">
|
||||
<span class="label-text font-semibold">Data Fim</span>
|
||||
<span class="label-text-alt text-error font-bold">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
class="input input-bordered input-secondary w-full"
|
||||
id="data-fim-ajuste"
|
||||
bind:value={dataFimAjuste}
|
||||
min={dataInicioAjuste}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="hora-fim-ajuste">
|
||||
<span class="label-text font-semibold">Hora Fim</span>
|
||||
<span class="label-text-alt text-error font-bold">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="time"
|
||||
class="input input-bordered input-secondary w-full"
|
||||
id="hora-fim-ajuste"
|
||||
bind:value={horaFimAjuste}
|
||||
/>
|
||||
</div>
|
||||
@@ -751,17 +733,18 @@
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="motivo-tipo-ajuste">
|
||||
<span class="label-text font-semibold">Tipo de Motivo</span>
|
||||
<span class="label-text-alt text-error font-bold">*</span>
|
||||
</label>
|
||||
<select
|
||||
class="select select-bordered select-warning w-full"
|
||||
id="motivo-tipo-ajuste"
|
||||
bind:value={motivoTipo}
|
||||
>
|
||||
<option value="">Selecione um tipo</option>
|
||||
{#if motivos?.opcoesPadrao}
|
||||
{#each motivos.opcoesPadrao as opcao}
|
||||
{#each motivos.opcoesPadrao as opcao (opcao)}
|
||||
<option value={opcao}>{opcao}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
@@ -769,12 +752,13 @@
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<label class="label" for="motivo-descricao-ajuste">
|
||||
<span class="label-text font-semibold">Descrição do Motivo</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
class="input input-bordered input-warning w-full"
|
||||
id="motivo-descricao-ajuste"
|
||||
bind:value={motivoDescricao}
|
||||
placeholder="Informe detalhes adicionais sobre o motivo"
|
||||
/>
|
||||
@@ -824,7 +808,7 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4">Registros do Funcionário</h2>
|
||||
|
||||
{#if registrosQuery?.status === 'Loading'}
|
||||
{#if registrosQuery?.isLoading}
|
||||
<div class="flex items-center justify-center py-8">
|
||||
<span class="loading loading-spinner loading-lg"></span>
|
||||
</div>
|
||||
@@ -846,7 +830,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each registros as registro}
|
||||
{#each registros as registro (registro._id)}
|
||||
<tr>
|
||||
<td class="whitespace-nowrap">{registro.data}</td>
|
||||
<td class="whitespace-nowrap">
|
||||
@@ -896,7 +880,7 @@
|
||||
{/if}
|
||||
</h2>
|
||||
|
||||
{#if homologacoesQuery?.status === 'Loading'}
|
||||
{#if homologacoesQuery?.isLoading}
|
||||
<div class="flex items-center justify-center py-8">
|
||||
<span class="loading loading-spinner loading-lg"></span>
|
||||
</div>
|
||||
@@ -923,20 +907,28 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each homologacoes as homologacao}
|
||||
{#each homologacoes as homologacao (homologacao._id)}
|
||||
<tr>
|
||||
<td>
|
||||
{new Date(homologacao.criadoEm).toLocaleDateString('pt-BR')}
|
||||
</td>
|
||||
{#if !funcionarioSelecionado}
|
||||
<td>
|
||||
{homologacao.funcionario?.nome || '-'}
|
||||
{#if homologacao.funcionario?.matricula}
|
||||
<br />
|
||||
<span class="text-base-content/70 text-xs">
|
||||
Mat: {homologacao.funcionario.matricula}
|
||||
</span>
|
||||
{/if}
|
||||
<div class="flex items-center gap-3">
|
||||
<UserAvatar
|
||||
fotoPerfilUrl={homologacao.fotoPerfilUrl}
|
||||
nome={homologacao.funcionario?.nome || 'Funcionário'}
|
||||
size="sm"
|
||||
/>
|
||||
<div>
|
||||
<div class="font-medium">{homologacao.funcionario?.nome || '-'}</div>
|
||||
{#if homologacao.funcionario?.matricula}
|
||||
<span class="text-base-content/70 text-xs">
|
||||
Mat: {homologacao.funcionario.matricula}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
{/if}
|
||||
<td>
|
||||
@@ -957,7 +949,7 @@
|
||||
homologacao.minutoAnterior || 0
|
||||
)}
|
||||
</span>
|
||||
{' → '}
|
||||
<span aria-hidden="true" class="mx-1">→</span>
|
||||
<span>
|
||||
{formatarHoraPonto(
|
||||
homologacao.horaNova || 0,
|
||||
@@ -967,7 +959,7 @@
|
||||
</div>
|
||||
{:else if homologacao.ajusteMinutos}
|
||||
<div class="text-sm">
|
||||
{homologacao.periodoDias || 0}d {homologacao.periodoHoras || 0}h{' '}
|
||||
{homologacao.periodoDias || 0}d {homologacao.periodoHoras || 0}h
|
||||
{homologacao.periodoMinutos || 0}min
|
||||
</div>
|
||||
{/if}
|
||||
@@ -1033,7 +1025,7 @@
|
||||
<h4 class="mb-3 font-semibold">Informações Gerais</h4>
|
||||
<div class="grid grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<span class="font-medium">Data:</span>{' '}
|
||||
<span class="font-medium">Data: </span>
|
||||
{new Date(homologacaoSelecionada.criadoEm).toLocaleDateString('pt-BR', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
@@ -1043,21 +1035,31 @@
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">Funcionário:</span>{' '}
|
||||
{homologacaoSelecionada.funcionario?.nome || '-'}
|
||||
{#if homologacaoSelecionada.funcionario?.matricula}
|
||||
<br />
|
||||
<span class="text-base-content/70 text-xs">
|
||||
Mat: {homologacaoSelecionada.funcionario.matricula}
|
||||
</span>
|
||||
{/if}
|
||||
<span class="font-medium">Funcionário:</span>
|
||||
<div class="mt-2 flex items-center gap-3">
|
||||
<UserAvatar
|
||||
fotoPerfilUrl={homologacaoSelecionada.fotoPerfilUrl}
|
||||
nome={homologacaoSelecionada.funcionario?.nome || 'Funcionário'}
|
||||
size="sm"
|
||||
/>
|
||||
<div>
|
||||
<div class="font-medium">
|
||||
{homologacaoSelecionada.funcionario?.nome || '-'}
|
||||
</div>
|
||||
{#if homologacaoSelecionada.funcionario?.matricula}
|
||||
<span class="text-base-content/70 text-xs">
|
||||
Mat: {homologacaoSelecionada.funcionario.matricula}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">Gestor:</span>{' '}
|
||||
<span class="font-medium">Gestor: </span>
|
||||
{homologacaoSelecionada.gestor?.nome || '-'}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">Tipo:</span>{' '}
|
||||
<span class="font-medium">Tipo: </span>
|
||||
{#if homologacaoSelecionada.registroId}
|
||||
<span class="badge badge-info">Edição de Registro</span>
|
||||
{:else if homologacaoSelecionada.tipoAjuste}
|
||||
@@ -1077,7 +1079,7 @@
|
||||
<h4 class="mb-3 font-semibold">Edição de Registro</h4>
|
||||
<div class="space-y-2 text-sm">
|
||||
<div>
|
||||
<span class="font-medium">Horário Anterior:</span>{' '}
|
||||
<span class="font-medium">Horário Anterior: </span>
|
||||
<span class="line-through opacity-70">
|
||||
{formatarHoraPonto(
|
||||
homologacaoSelecionada.horaAnterior || 0,
|
||||
@@ -1086,7 +1088,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">Horário Novo:</span>{' '}
|
||||
<span class="font-medium">Horário Novo: </span>
|
||||
<span>
|
||||
{formatarHoraPonto(
|
||||
homologacaoSelecionada.horaNova || 0,
|
||||
@@ -1096,11 +1098,11 @@
|
||||
</div>
|
||||
{#if homologacaoSelecionada.registro}
|
||||
<div>
|
||||
<span class="font-medium">Data do Registro:</span>{' '}
|
||||
<span class="font-medium">Data do Registro: </span>
|
||||
{new Date(homologacaoSelecionada.registro.data).toLocaleDateString('pt-BR')}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">Tipo de Registro:</span>{' '}
|
||||
<span class="font-medium">Tipo de Registro: </span>
|
||||
{getTipoRegistroLabel(homologacaoSelecionada.registro.tipo)}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -1113,20 +1115,20 @@
|
||||
<h4 class="mb-3 font-semibold">Ajuste de Banco de Horas</h4>
|
||||
<div class="space-y-2 text-sm">
|
||||
<div>
|
||||
<span class="font-medium">Tipo de Ajuste:</span>{' '}
|
||||
<span class="font-medium">Tipo de Ajuste: </span>
|
||||
{homologacaoSelecionada.tipoAjuste}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">Período:</span>{' '}
|
||||
{homologacaoSelecionada.periodoDias || 0}d {homologacaoSelecionada.periodoHoras ||
|
||||
0}h{' '}
|
||||
<span class="font-medium">Período: </span>
|
||||
{homologacaoSelecionada.periodoDias || 0}d
|
||||
{homologacaoSelecionada.periodoHoras || 0}h
|
||||
{homologacaoSelecionada.periodoMinutos || 0}min
|
||||
</div>
|
||||
{#if homologacaoSelecionada.ajusteMinutos}
|
||||
<div>
|
||||
<span class="font-medium">Ajuste Total:</span>{' '}
|
||||
<span class="font-medium">Ajuste Total: </span>
|
||||
{homologacaoSelecionada.ajusteMinutos > 0 ? '+' : ''}
|
||||
{Math.floor(Math.abs(homologacaoSelecionada.ajusteMinutos) / 60)}h{' '}
|
||||
{Math.floor(Math.abs(homologacaoSelecionada.ajusteMinutos) / 60)}h
|
||||
{Math.abs(homologacaoSelecionada.ajusteMinutos) % 60}min
|
||||
</div>
|
||||
{/if}
|
||||
@@ -1141,11 +1143,11 @@
|
||||
<h4 class="mb-3 font-semibold">Motivo e Observações</h4>
|
||||
<div class="space-y-2 text-sm">
|
||||
<div>
|
||||
<span class="font-medium">Tipo de Motivo:</span>{' '}
|
||||
<span class="font-medium">Tipo de Motivo: </span>
|
||||
{homologacaoSelecionada.motivoTipo || '-'}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">Descrição:</span>{' '}
|
||||
<span class="font-medium">Descrição: </span>
|
||||
{homologacaoSelecionada.motivoDescricao || '-'}
|
||||
</div>
|
||||
{#if homologacaoSelecionada.observacoes}
|
||||
@@ -1165,7 +1167,12 @@
|
||||
<button class="btn" onclick={fecharDetalhes}>Fechar</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-backdrop" onclick={fecharDetalhes}></div>
|
||||
<button
|
||||
type="button"
|
||||
class="modal-backdrop"
|
||||
onclick={fecharDetalhes}
|
||||
aria-label="Fechar detalhes da homologação"
|
||||
></button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1185,7 +1192,12 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-backdrop" onclick={fecharModalExcluir}></div>
|
||||
<button
|
||||
type="button"
|
||||
class="modal-backdrop"
|
||||
onclick={fecharModalExcluir}
|
||||
aria-label="Fechar modal de confirmação de exclusão"
|
||||
></button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user