refactor: enhance vacation management components and add status update functionality

- Improved the vacation request component with better loading states and error handling.
- Added a new mutation to update the status of vacation requests, allowing transitions between different states.
- Enhanced the calendar display for vacation periods and integrated a 3D bar chart for visualizing vacation data.
- Refactored the code for better readability and maintainability, ensuring a smoother user experience.
This commit is contained in:
2025-11-13 05:51:55 -03:00
parent 0b7f1ad621
commit ebde59c6d2
6 changed files with 1503 additions and 721 deletions

View File

@@ -509,6 +509,89 @@ export const marcarComoLida = mutation({
},
});
// Mutation: Atualizar status da solicitação (para voltar para aguardando_aprovacao)
export const atualizarStatus = mutation({
args: {
solicitacaoId: v.id("solicitacoesFerias"),
novoStatus: v.union(
v.literal("aguardando_aprovacao"),
v.literal("aprovado"),
v.literal("reprovado"),
v.literal("data_ajustada_aprovada")
),
usuarioId: v.id("usuarios"),
},
returns: v.null(),
handler: async (ctx, args) => {
const solicitacao = await ctx.db.get(args.solicitacaoId);
if (!solicitacao) throw new Error("Solicitação não encontrada");
// Se está mudando de aprovado para aguardando_aprovacao, precisa liberar os dias
if (solicitacao.status === "aprovado" || solicitacao.status === "data_ajustada_aprovada") {
if (args.novoStatus === "aguardando_aprovacao") {
// Liberar dias de volta ao saldo
await ctx.runMutation(internal.saldoFerias.liberarDias, {
solicitacaoId: args.solicitacaoId,
});
}
}
// Se está mudando de reprovado para aguardando_aprovacao, os dias já foram liberados anteriormente
// Mas precisamos reservar novamente
if (solicitacao.status === "reprovado" && args.novoStatus === "aguardando_aprovacao") {
// Calcular total de dias
let totalDias = 0;
for (const p of solicitacao.periodos) {
totalDias += p.diasCorridos;
}
// Reservar dias novamente
await ctx.runMutation(internal.saldoFerias.reservarDias, {
funcionarioId: solicitacao.funcionarioId,
anoReferencia: solicitacao.anoReferencia,
totalDias,
});
}
// Atualizar status e histórico
const acao = `Status alterado de ${solicitacao.status} para ${args.novoStatus}`;
// Preparar dados de atualização
const updateData: {
status: typeof args.novoStatus;
historicoAlteracoes: Array<{
data: number;
usuarioId: Id<"usuarios">;
acao: string;
}>;
} = {
status: args.novoStatus,
historicoAlteracoes: [
...(solicitacao.historicoAlteracoes || []),
{
data: Date.now(),
usuarioId: args.usuarioId,
acao,
},
],
};
// Se voltar para aguardando_aprovacao, limpar campos relacionados usando replace
if (args.novoStatus === "aguardando_aprovacao") {
// Usar replace para limpar campos opcionais - omitir os campos que queremos limpar
const { gestorId, dataAprovacao, dataReprovacao, motivoReprovacao, ...solicitacaoLimpa } = solicitacao;
await ctx.db.replace(args.solicitacaoId, {
...solicitacaoLimpa,
...updateData,
});
} else {
await ctx.db.patch(args.solicitacaoId, updateData);
}
return null;
},
});
// Internal Mutation: Atualizar status de todos os funcionários
export const atualizarStatusTodosFuncionarios = internalMutation({
args: {},