refactor: enhance role management UI and integrate profile management features

- Introduced a modal for managing user profiles, allowing for the creation and editing of profiles with improved state management.
- Updated the role filtering logic to enhance type safety and readability.
- Refactored UI components for better user experience, including improved button states and loading indicators.
- Removed outdated code related to permissions and streamlined the overall structure for maintainability.
This commit is contained in:
2025-11-03 15:14:33 -03:00
parent c1d9958c9f
commit 0d011b8f42
38 changed files with 2664 additions and 4919 deletions

View File

@@ -0,0 +1,99 @@
"use node";
import { action } from "../_generated/server";
import { v } from "convex/values";
import { internal } from "../_generated/api";
export const enviar = action({
args: {
emailId: v.id("notificacoesEmail"),
},
returns: v.object({ sucesso: v.boolean(), erro: v.optional(v.string()) }),
handler: async (ctx, args) => {
"use node";
const nodemailer = await import("nodemailer");
try {
// Buscar email da fila
const email = await ctx.runQuery(internal.email.getEmailById, {
emailId: args.emailId,
});
if (!email) {
return { sucesso: false, erro: "Email não encontrado" };
}
// Buscar configuração SMTP ativa
const config = await ctx.runQuery(internal.email.getActiveEmailConfig, {});
if (!config) {
return {
sucesso: false,
erro: "Configuração de email não encontrada ou inativa",
};
}
if (!config.testadoEm) {
return {
sucesso: false,
erro: "Configuração SMTP não foi testada. Teste a conexão primeiro!",
};
}
// Marcar como enviando
await ctx.runMutation(internal.email.markEmailEnviando, {
emailId: args.emailId,
});
// Criar transporter do nodemailer
const transporter = nodemailer.createTransport({
host: config.servidor,
port: config.porta,
secure: config.usarSSL,
auth: {
user: config.usuario,
// Em produção deve ser armazenado com criptografia reversível
pass: config.senhaHash,
},
tls: {
// Permitir certificados autoassinados
rejectUnauthorized: false,
},
});
// Enviar email
const info = await transporter.sendMail({
from: `"${config.nomeRemetente}" <${config.emailRemetente}>`,
to: email.destinatario,
subject: email.assunto,
html: email.corpo,
});
console.log("✅ Email enviado com sucesso!", {
para: email.destinatario,
assunto: email.assunto,
messageId: (info as { messageId?: string }).messageId,
});
// Marcar como enviado
await ctx.runMutation(internal.email.markEmailEnviado, {
emailId: args.emailId,
});
return { sucesso: true };
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error("❌ Erro ao enviar email:", errorMessage);
// Marcar como falha
await ctx.runMutation(internal.email.markEmailFalha, {
emailId: args.emailId,
erro: errorMessage,
});
return { sucesso: false, erro: errorMessage };
}
},
});

View File

@@ -0,0 +1,60 @@
"use node";
import { action } from "../_generated/server";
import { v } from "convex/values";
export const testarConexao = action({
args: {
servidor: v.string(),
porta: v.number(),
usuario: v.string(),
senha: v.string(),
usarSSL: v.boolean(),
usarTLS: v.boolean(),
},
returns: v.union(
v.object({ sucesso: v.literal(true) }),
v.object({ sucesso: v.literal(false), erro: v.string() })
),
handler: async (ctx, args) => {
"use node";
const nodemailer = await import("nodemailer");
try {
// Validações básicas
if (!args.servidor || args.servidor.trim() === "") {
return {
sucesso: false as const,
erro: "Servidor SMTP não pode estar vazio",
};
}
if (args.porta < 1 || args.porta > 65535) {
return { sucesso: false as const, erro: "Porta inválida" };
}
const transporter = nodemailer.createTransport({
host: args.servidor,
port: args.porta,
secure: args.usarSSL,
auth: {
user: args.usuario,
pass: args.senha,
},
tls: {
rejectUnauthorized: !args.usarTLS ? false : false,
},
});
// Verificar conexão
await transporter.verify();
return { sucesso: true as const };
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
return { sucesso: false as const, erro: errorMessage };
}
},
});