Files
sgse-app/packages/backend/convex/dashboard.ts

128 lines
3.3 KiB
TypeScript

import { query } from './_generated/server';
import { v } from 'convex/values';
// Obter estatísticas gerais do sistema
export const getStats = query({
args: {},
returns: v.object({
totalFuncionarios: v.number(),
totalSimbolos: v.number(),
totalUsuarios: v.number(),
funcionariosAtivos: v.number(),
funcionariosDesligados: v.number(),
cargoComissionado: v.number(),
funcaoGratificada: v.number(),
totalCadastros: v.number()
}),
handler: async (ctx) => {
// Contar funcionários
const funcionarios = await ctx.db.query('funcionarios').collect();
const totalFuncionarios = funcionarios.length;
// Funcionários ativos (sem data de desligamento)
const funcionariosAtivos = funcionarios.filter((f) => !f.desligamentoData).length;
// Funcionários desligados
const funcionariosDesligados = funcionarios.filter((f) => f.desligamentoData).length;
// Contar por tipo de símbolo
const cargoComissionado = funcionarios.filter(
(f) => f.simboloTipo === 'cargo_comissionado'
).length;
const funcaoGratificada = funcionarios.filter(
(f) => f.simboloTipo === 'funcao_gratificada'
).length;
// Contar símbolos
const simbolos = await ctx.db.query('simbolos').collect();
const totalSimbolos = simbolos.length;
// Contar usuários cadastrados
const usuarios = await ctx.db.query('usuarios').collect();
const totalUsuarios = usuarios.length;
// Calcular total de cadastros (funcionários + símbolos + usuários)
const totalCadastros = totalFuncionarios + totalSimbolos + totalUsuarios;
return {
totalFuncionarios,
totalSimbolos,
totalUsuarios,
funcionariosAtivos,
funcionariosDesligados,
cargoComissionado,
funcaoGratificada,
totalCadastros
};
}
});
// Obter distribuição de funcionários por cidade
export const getFuncionariosPorCidade = query({
args: {},
returns: v.array(
v.object({
cidade: v.string(),
quantidade: v.number()
})
),
handler: async (ctx) => {
const funcionarios = await ctx.db.query('funcionarios').collect();
const cidadesMap: Record<string, number> = {};
for (const func of funcionarios) {
if (!func.desligamentoData) {
cidadesMap[func.cidade] = (cidadesMap[func.cidade] || 0) + 1;
}
}
const result = Object.entries(cidadesMap)
.map(([cidade, quantidade]) => ({ cidade, quantidade }))
.sort((a, b) => b.quantidade - a.quantidade)
.slice(0, 5); // Top 5 cidades
return result;
}
});
// Obter evolução de cadastros por mês
export const getEvolucaoCadastros = query({
args: {},
returns: v.array(
v.object({
mes: v.string(),
funcionarios: v.number()
})
),
handler: async (ctx) => {
const funcionarios = await ctx.db.query('funcionarios').collect();
const now = new Date();
const meses: Array<{ mes: string; funcionarios: number }> = [];
// Últimos 6 meses
for (let i = 5; i >= 0; i--) {
const date = new Date(now.getFullYear(), now.getMonth() - i, 1);
const nextDate = new Date(now.getFullYear(), now.getMonth() - i + 1, 1);
const mesNome = date.toLocaleDateString('pt-BR', {
month: 'short',
year: '2-digit'
});
const funcCount = funcionarios.filter(
(f) => f._creationTime >= date.getTime() && f._creationTime < nextDate.getTime()
).length;
meses.push({
mes: mesNome,
funcionarios: funcCount
});
}
return meses;
}
});