2026-08-19 17:28:16 -04:00

262 lines
6.5 KiB
JavaScript

const { app, BrowserWindow, ipcMain, dialog, Menu } = require("electron");
const path = require("path");
const fs = require("fs");
// Módulos locales
const { generatePDF } = require("./pdfGenerator");
const { processExcelFile } = require("./excelProcessor");
const {
getTop10,
getRanking,
getNoRecomendados,
insertProfesionales,
} = require("./database");
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1000,
height: 800,
minWidth: 800,
minHeight: 600,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
enableRemoteModule: false,
devTools: true,
sandbox: true,
preload: path.join(__dirname, "preload.js"),
webSecurity: true,
allowRunningInsecureContent: false,
},
title: "Sistema de Orden de Mérito",
icon: path.join(
__dirname,
"assets",
process.platform === "win32" ? "sami_icon.ico" : "imagen1.png"
),
});
mainWindow.loadFile(path.join(__dirname, "src", "views", "main.html"));
mainWindow.maximize();
if (process.env.NODE_ENV === "development") {
mainWindow.webContents.openDevTools();
}
setupMenu(); // Menú para desarrollo
}
function setupMenu() {
const isMac = process.platform === "darwin";
const template = [
...(isMac
? [
{
label: app.name,
submenu: [
{ role: "about" },
{ type: "separator" },
{ role: "services" },
{ type: "separator" },
{ role: "hide" },
{ role: "hideothers" },
{ role: "unhide" },
{ type: "separator" },
{ role: "quit" },
],
},
]
: []),
{
label: "Archivo",
submenu: [{ role: "quit" }],
},
{
label: "Ver",
submenu: [
{ role: "reload", label: "Recargar" },
{ role: "forceReload", label: "Recarga Forzada" },
{ role: "toggleDevTools", label: "Herramientas de Desarrollador" },
{ type: "separator" },
{ role: "resetZoom" },
{ role: "zoomIn" },
{ role: "zoomOut" },
{ type: "separator" },
{ role: "togglefullscreen" },
],
},
{
label: "Ventana",
submenu: [
{ role: "minimize" },
{ role: "zoom" },
...(isMac
? [
{ type: "separator" },
{ role: "front" },
{ type: "separator" },
{ role: "window" },
]
: [{ role: "close" }]),
],
},
{
label: "Ayuda",
submenu: [
{
label: "Más información",
click: async () => {
await require("electron").shell.openExternal("https://electronjs.org");
},
},
],
},
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
}
function setupIPCHandlers() {
const handlers = [
"dialog:openFile",
"excel:process",
"ranking:generate",
"pdf:generate",
"getDownloadsPath",
"ranking:get",
"ranking:getTop10",
"nonrecommended:get",
"fs:exists",
"get:assetsPath",
];
handlers.forEach((handler) => ipcMain.removeHandler(handler));
ipcMain.handle("dialog:openFile", async () => {
const result = await dialog.showOpenDialog({
title: "Seleccionar archivo de Excel",
properties: ["openFile"],
filters: [
{ name: "Archivos de Excel", extensions: ["xlsx", "xls"] },
{ name: "Todos los archivos", extensions: ["*"] },
],
});
return result.canceled ? null : result.filePaths[0];
});
ipcMain.handle("excel:process", async (_, filePath) => {
try {
const profesionales = await processExcelFile(filePath);
await insertProfesionales(profesionales);
return profesionales;
} catch (error) {
console.error(error);
throw new Error(`Error procesando Excel: ${error.message}`);
}
});
ipcMain.handle("ranking:get", async () => {
try {
return await getRanking();
} catch (error) {
throw new Error(`Error obteniendo ranking: ${error.message}`);
}
});
ipcMain.handle("ranking:getTop10", async () => {
try {
return await getTop10();
} catch (error) {
throw new Error(`Error obteniendo Top 10: ${error.message}`);
}
});
ipcMain.handle('generate-pdf', async (event, data) => {
try {
const resultado = await generatePDF(data);
return resultado;
} catch (error) {
console.error("Error al generar PDF:", error);
throw error;
}
});
ipcMain.handle("getDownloadsPath", () => app.getPath("downloads"));
ipcMain.handle("nonrecommended:get", async () => {
try {
return await getNoRecomendados();
} catch (error) {
throw new Error(`Error obteniendo no recomendados: ${error.message}`);
}
});
ipcMain.handle("fs:exists", async (_, filePath) => {
try {
await fs.promises.access(filePath, fs.constants.F_OK);
return true;
} catch {
return false;
}
});
ipcMain.handle("get:assetsPath", () => {
return path.join(__dirname, "assets");
});
ipcMain.handle("getAudioPath", (_, audioName) => {
const audioDir = path.join(__dirname, "src", "audios");
const audioPath = path.join(audioDir, `${audioName}.mp3`);
if (fs.existsSync(audioPath)) {
const finalPath = `file://${audioPath.replace(/\\/g, '/')}`;
console.log("✅ Devolviendo ruta de audio:", finalPath);
return finalPath;
} else {
console.warn("❌ Audio no encontrado:", audioPath);
return null;
}
});
}
app.whenReady().then(() => {
app.commandLine.appendSwitch('--enable-speech-dispatcher');
app.commandLine.appendSwitch('--enable-speech-synthesis');
app.commandLine.appendSwitch('--enable-features=WinRTComVoiceActivation'); // Para Windows
createWindow();
setupIPCHandlers();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
setupIPCHandlers();
}
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});
process.on("unhandledRejection", (error) => {
console.error("Unhandled Rejection:", error);
dialog.showErrorBox("Error no manejado", error.message || "Error desconocido");
});
process.on("uncaughtException", (error) => {
console.error("Uncaught Exception:", error);
dialog.showErrorBox("Excepción no capturada", error.message || "Error crítico");
app.quit();
});