feat: enhance RegistroPonto and WebcamCapture components for improved data handling and user experience
- Added a refresh mechanism in the RegistroPonto component to ensure queries are updated after point registration, improving data accuracy. - Expanded the WebcamCapture component to prevent multiple simultaneous play calls, enhancing video playback reliability. - Updated the registro-pontos page to default the date range to the last 30 days for better visibility and user convenience. - Introduced debug logging for queries and data handling to assist in development and troubleshooting.
This commit is contained in:
@@ -791,6 +791,7 @@ export const registrarPonto = mutation({
|
||||
export const listarRegistrosDia = query({
|
||||
args: {
|
||||
data: v.optional(v.string()), // YYYY-MM-DD, se não fornecido usa hoje
|
||||
_refresh: v.optional(v.number()), // Parâmetro usado pelo frontend para forçar refresh
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const usuario = await getCurrentUserFunction(ctx);
|
||||
@@ -801,12 +802,22 @@ export const listarRegistrosDia = query({
|
||||
const funcionarioId = usuario.funcionarioId; // Garantir que não é undefined
|
||||
const data = args.data || new Date().toISOString().split('T')[0]!;
|
||||
|
||||
console.log('[listarRegistrosDia] Buscando registros:', { funcionarioId, data });
|
||||
|
||||
const registros = await ctx.db
|
||||
.query('registrosPonto')
|
||||
.withIndex('by_funcionario_data', (q) => q.eq('funcionarioId', funcionarioId).eq('data', data))
|
||||
.order('asc')
|
||||
.collect();
|
||||
|
||||
console.log('[listarRegistrosDia] Registros encontrados:', registros.length, registros.map(r => ({
|
||||
_id: r._id,
|
||||
tipo: r.tipo,
|
||||
data: r.data,
|
||||
hora: r.hora,
|
||||
minuto: r.minuto
|
||||
})));
|
||||
|
||||
return registros;
|
||||
},
|
||||
});
|
||||
@@ -862,7 +873,7 @@ export const listarRegistrosPeriodo = query({
|
||||
handler: async (ctx, args) => {
|
||||
const usuario = await getCurrentUserFunction(ctx);
|
||||
if (!usuario) {
|
||||
// Retornar array vazio quando não autenticado
|
||||
console.warn('[listarRegistrosPeriodo] Usuário não autenticado');
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -872,15 +883,27 @@ export const listarRegistrosPeriodo = query({
|
||||
|
||||
// Validar formato das datas
|
||||
if (!args.dataInicio || !args.dataFim) {
|
||||
console.warn('[listarRegistrosPeriodo] Datas não fornecidas');
|
||||
return [];
|
||||
}
|
||||
|
||||
// Validar formato YYYY-MM-DD
|
||||
const dataInicioRegex = /^\d{4}-\d{2}-\d{2}$/;
|
||||
if (!dataInicioRegex.test(args.dataInicio) || !dataInicioRegex.test(args.dataFim)) {
|
||||
console.warn('[listarRegistrosPeriodo] Formato de data inválido', {
|
||||
dataInicio: args.dataInicio,
|
||||
dataFim: args.dataFim
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
console.log('[listarRegistrosPeriodo] Buscando registros', {
|
||||
dataInicio: args.dataInicio,
|
||||
dataFim: args.dataFim,
|
||||
funcionarioId: args.funcionarioId,
|
||||
usuarioId: usuario._id
|
||||
});
|
||||
|
||||
let registrosFiltrados;
|
||||
|
||||
// Se funcionário foi especificado, usar índice por funcionário e data (mais eficiente)
|
||||
@@ -901,21 +924,41 @@ export const listarRegistrosPeriodo = query({
|
||||
});
|
||||
} else {
|
||||
// Se não há funcionário especificado, buscar todos e filtrar (menos eficiente, mas necessário)
|
||||
// Usar comparação de strings diretamente para datas no formato YYYY-MM-DD
|
||||
const registros = await ctx.db
|
||||
.query('registrosPonto')
|
||||
.withIndex('by_data', (q) =>
|
||||
q.gte('data', args.dataInicio).lte('data', args.dataFim)
|
||||
)
|
||||
.collect();
|
||||
|
||||
// Garantir que as datas estão no formato correto e filtrar novamente para garantir
|
||||
registrosFiltrados = registros.filter((r) => {
|
||||
// Comparação de strings funciona para formato YYYY-MM-DD
|
||||
return r.data >= args.dataInicio && r.data <= args.dataFim;
|
||||
});
|
||||
try {
|
||||
// Tentar usar índice por data primeiro
|
||||
const registros = await ctx.db
|
||||
.query('registrosPonto')
|
||||
.withIndex('by_data', (q) =>
|
||||
q.gte('data', args.dataInicio).lte('data', args.dataFim)
|
||||
)
|
||||
.collect();
|
||||
|
||||
console.log('[listarRegistrosPeriodo] Registros do índice by_data:', registros.length);
|
||||
|
||||
// Garantir que as datas estão no formato correto e filtrar novamente para garantir
|
||||
registrosFiltrados = registros.filter((r) => {
|
||||
// Comparação de strings funciona para formato YYYY-MM-DD
|
||||
return r.data >= args.dataInicio && r.data <= args.dataFim;
|
||||
});
|
||||
|
||||
console.log('[listarRegistrosPeriodo] Registros após filtro:', registrosFiltrados.length);
|
||||
} catch (error) {
|
||||
console.error('[listarRegistrosPeriodo] Erro ao buscar registros:', error);
|
||||
// Fallback: buscar todos e filtrar manualmente
|
||||
const todosRegistros = await ctx.db
|
||||
.query('registrosPonto')
|
||||
.collect();
|
||||
|
||||
registrosFiltrados = todosRegistros.filter((r) => {
|
||||
return r.data >= args.dataInicio && r.data <= args.dataFim;
|
||||
});
|
||||
|
||||
console.log('[listarRegistrosPeriodo] Fallback - registros encontrados:', registrosFiltrados.length);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[listarRegistrosPeriodo] Registros encontrados antes de buscar funcionários:', registrosFiltrados.length);
|
||||
|
||||
// Buscar informações dos funcionários
|
||||
const funcionariosIds = new Set(registrosFiltrados.map((r) => r.funcionarioId));
|
||||
const funcionarios = await Promise.all(
|
||||
@@ -940,6 +983,8 @@ export const listarRegistrosPeriodo = query({
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[listarRegistrosPeriodo] Total de registros a retornar:', registrosFiltrados.length);
|
||||
|
||||
return registrosFiltrados.map((registro) => {
|
||||
const funcionario = funcionarios.find((f) => f?._id === registro.funcionarioId);
|
||||
const chave = `${registro.funcionarioId}-${registro.data}`;
|
||||
@@ -1225,11 +1270,19 @@ export const obterHistoricoESaldoDia = query({
|
||||
args: {
|
||||
funcionarioId: v.id('funcionarios'),
|
||||
data: v.string(), // YYYY-MM-DD
|
||||
_refresh: v.optional(v.number()), // Parâmetro usado pelo frontend para forçar refresh
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const usuario = await getCurrentUserFunction(ctx);
|
||||
if (!usuario || !usuario.funcionarioId) {
|
||||
throw new Error('Usuário não autenticado');
|
||||
console.warn('[obterHistoricoESaldoDia] Usuário não autenticado ou sem funcionarioId');
|
||||
// Retornar dados vazios em vez de lançar erro
|
||||
return {
|
||||
registros: [],
|
||||
cargaHorariaDiaria: 0,
|
||||
horasTrabalhadas: 0,
|
||||
saldoMinutos: 0,
|
||||
};
|
||||
}
|
||||
|
||||
// Verificar se é o próprio funcionário ou tem permissão
|
||||
@@ -1245,6 +1298,11 @@ export const obterHistoricoESaldoDia = query({
|
||||
)
|
||||
.order('asc')
|
||||
.collect();
|
||||
|
||||
console.log('[obterHistoricoESaldoDia] Registros encontrados:', registros.length, {
|
||||
funcionarioId: args.funcionarioId,
|
||||
data: args.data
|
||||
});
|
||||
|
||||
// Buscar configuração de ponto
|
||||
const config = await ctx.db
|
||||
|
||||
Reference in New Issue
Block a user