feat: enhance dispensa management with modal confirmation and time input improvements
- Introduced a modal for confirming the removal of dispensas, improving user interaction and preventing accidental deletions. - Updated time input fields to use a more user-friendly format, allowing for direct time selection. - Refactored state management for dispensa creation, ensuring better handling of time and date inputs. - Enhanced UI elements for better feedback and clarity during the dispensa creation process.
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { useQuery, useConvexClient } from 'convex-svelte';
|
import { useQuery, useConvexClient } from 'convex-svelte';
|
||||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||||
import { Clock, Plus, X, Trash2 } from 'lucide-svelte';
|
import { Clock, Plus, X, Trash2, AlertTriangle } from 'lucide-svelte';
|
||||||
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
|
|
||||||
@@ -11,21 +10,32 @@
|
|||||||
// Estados
|
// Estados
|
||||||
let funcionariosSelecionados = $state<Id<'funcionarios'>[]>([]);
|
let funcionariosSelecionados = $state<Id<'funcionarios'>[]>([]);
|
||||||
let modoCriacao = $state(false);
|
let modoCriacao = $state(false);
|
||||||
|
let mostrandoModalExcluir = $state(false);
|
||||||
|
let dispensaParaExcluir = $state<Id<'dispensasRegistro'> | null>(null);
|
||||||
|
|
||||||
// Formulário
|
// Formulário
|
||||||
let dataInicio = $state(new Date().toISOString().split('T')[0]!);
|
let dataInicio = $state(new Date().toISOString().split('T')[0]!);
|
||||||
let horaInicio = $state(8);
|
let horaInicioTime = $state('08:00');
|
||||||
let minutoInicio = $state(0);
|
|
||||||
let dataFim = $state(new Date().toISOString().split('T')[0]!);
|
let dataFim = $state(new Date().toISOString().split('T')[0]!);
|
||||||
let horaFim = $state(18);
|
let horaFimTime = $state('18:00');
|
||||||
let minutoFim = $state(0);
|
|
||||||
let motivo = $state('');
|
let motivo = $state('');
|
||||||
let isento = $state(false);
|
let isento = $state(false);
|
||||||
|
|
||||||
|
// Computed para converter time string para hora/minuto
|
||||||
|
const horaInicio = $derived.by(() => {
|
||||||
|
const [hora, minuto] = horaInicioTime.split(':').map(Number);
|
||||||
|
return { hora: hora || 8, minuto: minuto || 0 };
|
||||||
|
});
|
||||||
|
|
||||||
|
const horaFim = $derived.by(() => {
|
||||||
|
const [hora, minuto] = horaFimTime.split(':').map(Number);
|
||||||
|
return { hora: hora || 18, minuto: minuto || 0 };
|
||||||
|
});
|
||||||
|
|
||||||
// Queries
|
// Queries
|
||||||
const subordinadosQuery = useQuery(api.times.listarSubordinadosDoGestorAtual, {});
|
const subordinadosQuery = useQuery(api.times.listarSubordinadosDoGestorAtual, {});
|
||||||
const dispensasQuery = useQuery(api.pontos.listarDispensas, {
|
const dispensasQuery = useQuery(api.pontos.listarDispensas, {
|
||||||
apenasAtivas: false, // Mostrar todas para o gestor ver histórico
|
apenasAtivas: true, // Mostrar apenas dispensas ativas
|
||||||
});
|
});
|
||||||
|
|
||||||
const subordinados = $derived(subordinadosQuery?.data || []);
|
const subordinados = $derived(subordinadosQuery?.data || []);
|
||||||
@@ -52,11 +62,9 @@
|
|||||||
modoCriacao = true;
|
modoCriacao = true;
|
||||||
funcionariosSelecionados = [];
|
funcionariosSelecionados = [];
|
||||||
dataInicio = new Date().toISOString().split('T')[0]!;
|
dataInicio = new Date().toISOString().split('T')[0]!;
|
||||||
horaInicio = 8;
|
horaInicioTime = '08:00';
|
||||||
minutoInicio = 0;
|
|
||||||
dataFim = new Date().toISOString().split('T')[0]!;
|
dataFim = new Date().toISOString().split('T')[0]!;
|
||||||
horaFim = 18;
|
horaFimTime = '18:00';
|
||||||
minutoFim = 0;
|
|
||||||
motivo = '';
|
motivo = '';
|
||||||
isento = false;
|
isento = false;
|
||||||
}
|
}
|
||||||
@@ -99,11 +107,11 @@
|
|||||||
client.mutation(api.pontos.criarDispensaRegistro, {
|
client.mutation(api.pontos.criarDispensaRegistro, {
|
||||||
funcionarioId,
|
funcionarioId,
|
||||||
dataInicio,
|
dataInicio,
|
||||||
horaInicio,
|
horaInicio: horaInicio.hora,
|
||||||
minutoInicio,
|
minutoInicio: horaInicio.minuto,
|
||||||
dataFim,
|
dataFim,
|
||||||
horaFim,
|
horaFim: horaFim.hora,
|
||||||
minutoFim,
|
minutoFim: horaFim.minuto,
|
||||||
motivo,
|
motivo,
|
||||||
isento,
|
isento,
|
||||||
})
|
})
|
||||||
@@ -121,15 +129,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removerDispensa(dispensaId: Id<'dispensasRegistro'>) {
|
function abrirModalExcluir(dispensaId: Id<'dispensasRegistro'>) {
|
||||||
if (!confirm('Deseja realmente remover esta dispensa?')) return;
|
dispensaParaExcluir = dispensaId;
|
||||||
|
mostrandoModalExcluir = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fecharModalExcluir() {
|
||||||
|
mostrandoModalExcluir = false;
|
||||||
|
dispensaParaExcluir = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmarRemoverDispensa() {
|
||||||
|
if (!dispensaParaExcluir) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.mutation(api.pontos.removerDispensaRegistro, {
|
await client.mutation(api.pontos.removerDispensaRegistro, {
|
||||||
dispensaId,
|
dispensaId: dispensaParaExcluir,
|
||||||
});
|
});
|
||||||
|
|
||||||
toast.success('Dispensa removida com sucesso');
|
toast.success('Dispensa removida com sucesso');
|
||||||
|
fecharModalExcluir();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||||
toast.error(`Erro ao remover dispensa: ${errorMessage}`);
|
toast.error(`Erro ao remover dispensa: ${errorMessage}`);
|
||||||
@@ -164,19 +183,27 @@
|
|||||||
<!-- Formulário de Criação -->
|
<!-- Formulário de Criação -->
|
||||||
{#if modoCriacao}
|
{#if modoCriacao}
|
||||||
<div class="card bg-base-100 shadow-xl mb-6">
|
<div class="card bg-base-100 shadow-xl mb-6">
|
||||||
<div class="card-body">
|
<div class="card-body space-y-6">
|
||||||
<h2 class="card-title mb-4">Criar Dispensa de Registro</h2>
|
<h2 class="card-title border-b pb-3 text-xl">Criar Dispensa de Registro</h2>
|
||||||
|
|
||||||
<!-- Seleção de Funcionários -->
|
<!-- Seleção de Funcionários -->
|
||||||
<div class="form-control mb-4">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">Funcionários</span>
|
<span class="label-text font-medium">Funcionários</span>
|
||||||
|
{#if funcionariosSelecionados.length > 0}
|
||||||
|
<span class="label-text-alt text-primary">
|
||||||
|
{funcionariosSelecionados.length} selecionado(s)
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
</label>
|
</label>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 max-h-60 overflow-y-auto border border-base-300 rounded-lg p-4">
|
<div class="max-h-60 overflow-y-auto border border-base-300 rounded-lg p-4 space-y-2">
|
||||||
{#each funcionarios as funcionario}
|
{#each funcionarios as funcionario}
|
||||||
<label class="label cursor-pointer">
|
<label class="flex items-center justify-between p-3 rounded-lg hover:bg-base-200 transition-colors cursor-pointer">
|
||||||
<span class="label-text">
|
<span class="label-text font-medium">
|
||||||
{funcionario.nome} {funcionario.matricula ? `(${funcionario.matricula})` : ''}
|
{funcionario.nome}
|
||||||
|
{#if funcionario.matricula}
|
||||||
|
<span class="text-base-content/60 ml-2">({funcionario.matricula})</span>
|
||||||
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@@ -186,90 +213,74 @@
|
|||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
{/each}
|
{/each}
|
||||||
|
{#if funcionarios.length === 0}
|
||||||
|
<div class="text-center py-4 text-base-content/60">
|
||||||
|
Nenhum funcionário disponível
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Período -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">Data Início</span>
|
<span class="label-text font-medium">Data Início</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="date" class="input input-bordered" bind:value={dataInicio} />
|
<input type="date" class="input input-bordered w-full" bind:value={dataInicio} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">Hora Início</span>
|
<span class="label-text font-medium">Hora Início</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="flex gap-2">
|
<input type="time" class="input input-bordered w-full" bind:value={horaInicioTime} />
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
min="0"
|
|
||||||
max="23"
|
|
||||||
class="input input-bordered flex-1"
|
|
||||||
bind:value={horaInicio}
|
|
||||||
/>
|
|
||||||
<span class="self-center">:</span>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
min="0"
|
|
||||||
max="59"
|
|
||||||
class="input input-bordered flex-1"
|
|
||||||
bind:value={minutoInicio}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">Data Fim</span>
|
<span class="label-text font-medium">Data Fim</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="date" class="input input-bordered" bind:value={dataFim} />
|
<input type="date" class="input input-bordered w-full" bind:value={dataFim} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">Hora Fim</span>
|
<span class="label-text font-medium">Hora Fim</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="flex gap-2">
|
<input type="time" class="input input-bordered w-full" bind:value={horaFimTime} />
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
min="0"
|
|
||||||
max="23"
|
|
||||||
class="input input-bordered flex-1"
|
|
||||||
bind:value={horaFim}
|
|
||||||
/>
|
|
||||||
<span class="self-center">:</span>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
min="0"
|
|
||||||
max="59"
|
|
||||||
class="input input-bordered flex-1"
|
|
||||||
bind:value={minutoFim}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-control md:col-span-2">
|
<!-- Motivo -->
|
||||||
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">Motivo</span>
|
<span class="label-text font-medium">Motivo</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea class="textarea textarea-bordered" bind:value={motivo} rows="3"></textarea>
|
<textarea
|
||||||
|
class="textarea textarea-bordered"
|
||||||
|
bind:value={motivo}
|
||||||
|
rows="3"
|
||||||
|
placeholder="Descreva o motivo da dispensa de registro de ponto"
|
||||||
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-control md:col-span-2">
|
<!-- Isento -->
|
||||||
<label class="label cursor-pointer">
|
<div class="form-control">
|
||||||
<span class="label-text font-medium">Isento de Registro (caso excepcional - sem expiração)</span>
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={isento} />
|
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={isento} />
|
||||||
</label>
|
<div>
|
||||||
|
<span class="label-text font-medium">Isento de Registro</span>
|
||||||
<p class="text-sm text-base-content/70 mt-1">
|
<p class="text-sm text-base-content/70 mt-1">
|
||||||
Se marcado, o funcionário ficará permanentemente dispensado de registrar ponto
|
Caso excepcional - sem expiração. O funcionário ficará permanentemente dispensado de registrar ponto.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-2 mt-4">
|
<!-- Ações -->
|
||||||
<button class="btn btn-primary gap-2" onclick={salvarDispensa}>
|
<div class="flex gap-2 pt-4 border-t">
|
||||||
|
<button class="btn btn-primary gap-2 flex-1" onclick={salvarDispensa}>
|
||||||
<Plus class="h-4 w-4" />
|
<Plus class="h-4 w-4" />
|
||||||
Criar Dispensa
|
Criar Dispensa
|
||||||
</button>
|
</button>
|
||||||
@@ -342,7 +353,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-error gap-2"
|
class="btn btn-sm btn-error gap-2"
|
||||||
onclick={() => removerDispensa(dispensa._id)}
|
onclick={() => abrirModalExcluir(dispensa._id)}
|
||||||
>
|
>
|
||||||
<Trash2 class="h-4 w-4" />
|
<Trash2 class="h-4 w-4" />
|
||||||
Remover
|
Remover
|
||||||
@@ -356,5 +367,32 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal de Confirmação de Remoção -->
|
||||||
|
{#if mostrandoModalExcluir && dispensaParaExcluir}
|
||||||
|
<dialog class="modal modal-open">
|
||||||
|
<div class="modal-box">
|
||||||
|
<div class="flex items-center gap-3 mb-4">
|
||||||
|
<div class="p-2 bg-error/10 rounded-lg">
|
||||||
|
<AlertTriangle class="h-6 w-6 text-error" strokeWidth={2} />
|
||||||
|
</div>
|
||||||
|
<h3 class="font-bold text-lg">Confirmar Remoção</h3>
|
||||||
|
</div>
|
||||||
|
<p class="text-base-content mb-6">
|
||||||
|
Deseja realmente remover esta dispensa? Esta ação não pode ser desfeita.
|
||||||
|
</p>
|
||||||
|
<div class="modal-action">
|
||||||
|
<button class="btn btn-ghost" onclick={fecharModalExcluir}>Cancelar</button>
|
||||||
|
<button class="btn btn-error gap-2" onclick={confirmarRemoverDispensa}>
|
||||||
|
<Trash2 class="h-4 w-4" />
|
||||||
|
Remover
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form method="dialog" class="modal-backdrop" onclick={fecharModalExcluir}>
|
||||||
|
<button type="button">fechar</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,11 @@
|
|||||||
let mostrandoModalDetalhes = $state(false);
|
let mostrandoModalDetalhes = $state(false);
|
||||||
let mostrandoModalExcluir = $state(false);
|
let mostrandoModalExcluir = $state(false);
|
||||||
|
|
||||||
|
// Monitorar mudanças em funcionarioSelecionado
|
||||||
|
$effect(() => {
|
||||||
|
console.log('🔄 [DEBUG] funcionarioSelecionado mudou:', funcionarioSelecionado, typeof funcionarioSelecionado);
|
||||||
|
});
|
||||||
|
|
||||||
// Formulário de edição
|
// Formulário de edição
|
||||||
let horaNova = $state(8);
|
let horaNova = $state(8);
|
||||||
let minutoNova = $state(0);
|
let minutoNova = $state(0);
|
||||||
@@ -102,10 +107,21 @@
|
|||||||
const homologacoesParams = $derived({
|
const homologacoesParams = $derived({
|
||||||
funcionarioId: funcionarioSelecionado || undefined,
|
funcionarioId: funcionarioSelecionado || undefined,
|
||||||
});
|
});
|
||||||
const registrosQueryParams = $derived({
|
|
||||||
funcionarioId: funcionarioSelecionado || undefined,
|
// Parâmetros para query de registros - só executa quando há funcionário selecionado
|
||||||
|
const registrosQueryParams = $derived.by(() => {
|
||||||
|
// Verificar se funcionarioSelecionado não é string vazia
|
||||||
|
if (!funcionarioSelecionado || funcionarioSelecionado === '') {
|
||||||
|
console.log('⏭️ [DEBUG] registrosQueryParams: skip (sem funcionário selecionado)');
|
||||||
|
return 'skip';
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
funcionarioId: funcionarioSelecionado as Id<'funcionarios'>,
|
||||||
dataInicio: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]!,
|
dataInicio: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]!,
|
||||||
dataFim: new Date().toISOString().split('T')[0]!,
|
dataFim: new Date().toISOString().split('T')[0]!,
|
||||||
|
};
|
||||||
|
console.log('📤 [DEBUG] registrosQueryParams:', params);
|
||||||
|
return params;
|
||||||
});
|
});
|
||||||
|
|
||||||
const homologacoesQuery = useQuery(api.pontos.listarHomologacoes, homologacoesParams);
|
const homologacoesQuery = useQuery(api.pontos.listarHomologacoes, homologacoesParams);
|
||||||
@@ -114,7 +130,26 @@
|
|||||||
const subordinados = $derived(subordinadosQuery?.data || []);
|
const subordinados = $derived(subordinadosQuery?.data || []);
|
||||||
const motivos = $derived(motivosQuery?.data);
|
const motivos = $derived(motivosQuery?.data);
|
||||||
const homologacoes = $derived(homologacoesQuery?.data || []);
|
const homologacoes = $derived(homologacoesQuery?.data || []);
|
||||||
const registros = $derived(registrosQuery?.data || []);
|
|
||||||
|
// Registros já filtrados pela query no backend
|
||||||
|
const registros = $derived.by(() => {
|
||||||
|
if (!funcionarioSelecionado || funcionarioSelecionado === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const dados = registrosQuery?.data;
|
||||||
|
console.log('🔍 [DEBUG] funcionarioSelecionado:', funcionarioSelecionado);
|
||||||
|
console.log('🔍 [DEBUG] registrosQuery?.data:', dados);
|
||||||
|
console.log('🔍 [DEBUG] registrosQuery?.status:', registrosQuery?.status);
|
||||||
|
if (!dados || !Array.isArray(dados)) {
|
||||||
|
console.log('⚠️ [DEBUG] Dados não são array ou estão vazios');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
// A query do backend já filtra pelo funcionário, mas adicionamos verificação extra
|
||||||
|
// Converter ambos para string para garantir comparação correta
|
||||||
|
const filtrados = dados.filter((r) => String(r.funcionarioId) === String(funcionarioSelecionado));
|
||||||
|
console.log('✅ [DEBUG] Registros filtrados:', filtrados.length, filtrados);
|
||||||
|
return filtrados;
|
||||||
|
});
|
||||||
|
|
||||||
// Verificar se é gestor (tem subordinados)
|
// Verificar se é gestor (tem subordinados)
|
||||||
const isGestor = $derived(subordinados.length > 0);
|
const isGestor = $derived(subordinados.length > 0);
|
||||||
@@ -342,7 +377,7 @@
|
|||||||
>
|
>
|
||||||
<option value="">Selecione um funcionário</option>
|
<option value="">Selecione um funcionário</option>
|
||||||
{#each funcionarios as funcionario}
|
{#each funcionarios as funcionario}
|
||||||
<option value={funcionario._id}>
|
<option value={funcionario._id as string}>
|
||||||
{funcionario.nome} {funcionario.matricula ? `(${funcionario.matricula})` : ''}
|
{funcionario.nome} {funcionario.matricula ? `(${funcionario.matricula})` : ''}
|
||||||
</option>
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -384,15 +384,32 @@ export const listarRegistrosPeriodo = query({
|
|||||||
const dataFim = new Date(args.dataFim);
|
const dataFim = new Date(args.dataFim);
|
||||||
dataFim.setHours(23, 59, 59, 999);
|
dataFim.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
|
let registrosFiltrados;
|
||||||
|
|
||||||
|
// Se funcionário foi especificado, usar índice por funcionário e data (mais eficiente)
|
||||||
|
if (args.funcionarioId) {
|
||||||
|
// Garantir que funcionarioId não é undefined para TypeScript
|
||||||
|
const funcionarioId = args.funcionarioId;
|
||||||
|
|
||||||
|
// Buscar todos os registros do funcionário
|
||||||
|
const todosRegistrosFuncionario = await ctx.db
|
||||||
|
.query('registrosPonto')
|
||||||
|
.withIndex('by_funcionario_data', (q) => q.eq('funcionarioId', funcionarioId))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Filtrar por período de data
|
||||||
|
registrosFiltrados = todosRegistrosFuncionario.filter((r) => {
|
||||||
|
const dataRegistro = new Date(r.data);
|
||||||
|
return dataRegistro >= new Date(args.dataInicio) && dataRegistro <= dataFim;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Se não há funcionário especificado, buscar todos e filtrar (menos eficiente, mas necessário)
|
||||||
const registros = await ctx.db
|
const registros = await ctx.db
|
||||||
.query('registrosPonto')
|
.query('registrosPonto')
|
||||||
.withIndex('by_data', (q) => q.gte('data', args.dataInicio).lte('data', args.dataFim))
|
.withIndex('by_data', (q) => q.gte('data', args.dataInicio).lte('data', args.dataFim))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Filtrar por funcionário se especificado
|
registrosFiltrados = registros;
|
||||||
let registrosFiltrados = registros;
|
|
||||||
if (args.funcionarioId) {
|
|
||||||
registrosFiltrados = registros.filter((r) => r.funcionarioId === args.funcionarioId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buscar informações dos funcionários
|
// Buscar informações dos funcionários
|
||||||
|
|||||||
Reference in New Issue
Block a user