262 lines
6.5 KiB
JavaScript
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();
|
|
});
|