mejora en la apriencia del cloud.

This commit is contained in:
Pablinux
2025-06-18 02:17:58 -05:00
parent 9e3e170db5
commit 12b032b859
5 changed files with 662 additions and 253 deletions

View File

@@ -1,3 +1,4 @@
const path = require('path');
const config = { const config = {
db:{ db:{
host: '192.168.10.150', host: '192.168.10.150',
@@ -9,8 +10,9 @@ const config = {
sock: '/' sock: '/'
}, },
dir:{ dir:{
root_dir: '/home/pablinux/Projects/Node/APP-SIGMA-WEB/src/public/files/', //root_dir: '/home/pablinux/Projects/Node/APP-SIGMA-WEB/src/public/files/',
path_dir: process.cwd(), // usa el path del ejecutable real //path_dir: process.cwd(), // usa el path del ejecutable real
path_dir: path.join(__dirname, 'public', 'files'),
}, },
sesion:{ sesion:{
id:"", id:"",

View File

@@ -2,21 +2,25 @@ const controlador = {};
//const dirPath = "/home/pablinux/Projects/Node/APP-SIGMA-WEB/src/public/files/"; //const dirPath = "/home/pablinux/Projects/Node/APP-SIGMA-WEB/src/public/files/";
//const var_locals = ; //const var_locals = ;
//********* APP-panel control ********// //********* APP-panel control ********//
const path = require('path');
controlador.upload = (req, res) => { controlador.upload = (req, res) => {
if (!req.files || Object.keys(req.files).lenght === 0) { if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send({ message: 'archivos no cargados' }); return res.status(400).json({ status: 'error', message: 'Archivos no cargados' });
} else { } else {
const file = req.files.file_toUpload; const file = req.files.file_toUpload;
const path = req.app.locals.dir.path_dir + '/public/files/' + file.name; const destinationPath = path.join(req.app.locals.dir.path_dir, file.name);
console.log(path);
file.mv(path, (err) => { file.mv(destinationPath, (err) => {
if (err) { if (err) {
return res.status(500).send(err); console.error("Error al mover el archivo:", err);
return res.status(500).json({ status: 'error', message: 'Error al subir el archivo', error: err.message });
} }
return res.send({ status: "success", path: path }); // *** Mantener la respuesta JSON ***
return res.json({ status: "success", message: `Archivo '${file.name}' subido exitosamente.` });
}); });
} }
}; };
controlador.upload_video = (req, res) => { controlador.upload_video = (req, res) => {
if (!req.files || Object.keys(req.files).lenght === 0) { if (!req.files || Object.keys(req.files).lenght === 0) {
return res.status(400).send({ message: 'archivos no cargados' }); return res.status(400).send({ message: 'archivos no cargados' });
@@ -34,18 +38,16 @@ controlador.upload_video = (req, res) => {
}; };
//ruta actual //ruta actual
const procesarPath = (path) => { const fs = require('fs'); // Asegúrate de que esta línea esté al principio del archivo si no lo está
return path ? path.replace(/-/g, '/') : '/';
}
const fs = require('fs');
function leer_dir(dir) { function leer_dir(dir) {
var json = []; var json = [];
var files = fs.readdirSync(dir + '/public/files/', { withFileTypes: true }); // ¡CORRECCIÓN AQUÍ! Usa 'dir' directamente, sin añadir '/public/files/'
var files = fs.readdirSync(dir, { withFileTypes: true });
files.forEach(function (arch, idx) { files.forEach(function (arch, idx) {
json.push({ "indice": idx, "archivo": arch.name, "link": "files/" + arch }); // Si el link para la interfaz web debe ser relativo a 'files/', esto es correcto.
//console.log(arch.name); json.push({ "indice": idx, "archivo": arch.name, "link": "files/" + arch.name });
//console.log(req); // Nota: 'arch' es un objeto dirent, necesitas 'arch.name' para el nombre del archivo.
}); });
return json; return json;
} }
@@ -69,8 +71,8 @@ controlador.cloud_panel = (req, res, next) => {
} else { } else {
try { try {
if (rows.length > 0) { if (rows.length > 0) {
let dir = procesarPath(req.params.path); //let dir = procesarPath(req.params.path);
console.log(req.app.locals.dir); //console.log(req.app.locals.dir);
var files = leer_dir(req.app.locals.dir.path_dir); var files = leer_dir(req.app.locals.dir.path_dir);
res.render('cloud', { res.render('cloud', {
data: files data: files
@@ -83,7 +85,7 @@ controlador.cloud_panel = (req, res, next) => {
} }
} catch (e) { } catch (e) {
res.render('login_cloud',{msg:e.toString()}); res.render('login_cloud',{msg:e.toString()});
//next(e); next(e);
} }
} }
}); });

View File

@@ -1,106 +1,402 @@
body{ /* Cloud SIGMA - Estilos Personalizados */
background:rgb(10, 10, 10);
color: rgb(255, 255, 255);
}
.files{
}
.info{
font-family: sigma_font;
font-size: 20px;
}
.upload{
:root {
--primary-gradient: linear-gradient(135deg, #4a5897 0%, #001833 100%);
--secondary-gradient: linear-gradient(135deg, #486ccf 0%, #f5576c 100%);
--dark-gradient: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
--success-gradient: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
--glass-bg: rgba(255, 255, 255, 0.1);
--glass-border: rgba(255, 255, 255, 0.2);
} }
.icon { body {
width: 2em; background: linear-gradient(135deg, #667eea 0%, #4b58a2 50%, #93bdfb 100%);
height: 2em; min-height: 100vh;
} font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
#titulo{
color: rgb(0, 0, 0);
}
#rep-video{
width: 600;
height:400;
}
#ctr.l_audio{
margin-top: -60px;
} }
/* MENU USUARIO DESPLEGABLE */ /* Navbar Improvements */
.dropdown-menu { .navbar-custom {
position: absolute; background: rgba(0, 0, 0, 0.9) !important;
left: 5%; backdrop-filter: blur(10px);
left: auto; border-bottom: 1px solid rgba(104, 101, 158, 0.1);
border: 1px solid #ddd; box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
background: #fff;
padding: 0px; /* --- CAMBIO CLAVE AQUÍ --- */
position: relative; /* O 'fixed', o 'sticky' dependiendo de tu necesidad, pero debe ser no-static */
z-index: 1060; /* Un z-index más alto que el dropdown para que el dropdown esté dentro de su contexto */
/* --- FIN CAMBIO CLAVE --- */
} }
.dropdown-menu ul{
list-style-type: none; .navbar-brand {
color: aliceblue; transition: all 0.3s ease;
padding: 0px;
} }
.dropdown-menu ul li{
list-style-type: none; .navbar-brand:hover {
color: aliceblue; transform: scale(1.1);
} }
.dropdown-menu ul li img{
z-index: 5; .navbar-brand img {
height: 90px;
width: 90px;
border: 3px solid;
border-color: transparent;
border-color: rgba(255,255,255,0.2);
}
.img-circle {
border-radius: 50%; border-radius: 50%;
box-shadow: 0 0 20px rgba(102, 126, 234, 0.5);
transition: all 0.3s ease;
} }
.dropdown-menu ul li.user-header {
height: 175px; .navbar-brand img:hover {
padding: 10px; box-shadow: 0 0 30px rgba(102, 126, 234, 0.8);
}
/* Search Bar */
.search-container {
position: relative;
}
.form-control {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 25px;
color: white;
backdrop-filter: blur(10px);
transition: all 0.3s ease;
}
.form-control:focus {
background: rgba(255, 255, 255, 0.2);
border-color: #667eea;
box-shadow: 0 0 20px rgba(102, 126, 234, 0.3);
color: white;
}
.form-control::placeholder {
color: rgba(255, 255, 255, 0.7);
}
.btn-search {
background: var(--primary-gradient);
border: none;
border-radius: 25px;
color: white;
font-weight: 600;
transition: all 0.3s ease;
}
.btn-search:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4);
color: white;
}
/* Container Improvements */
.main-container {
margin-top: 30px;
padding: 0 20px;
}
/* Upload Section */
.upload-card {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
padding: 30px;
margin-bottom: 30px;
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
transition: all 0.3s ease;
/* --- CONSIDERACIÓN: Si estas tarjetas siguen por encima, podrías darles un z-index más bajo
Pero primero prueba el cambio en navbar-custom */
/* z-index: 1; */
}
.upload-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px 0 rgba(31, 38, 135, 0.5);
}
.upload-title {
color: white;
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 25px;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
background: linear-gradient(45deg, #fff, #667eea);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.file-input-container {
position: relative;
overflow: hidden;
display: inline-block;
width: 100%;
}
.file-input {
background: rgba(255, 255, 255, 0.1);
border: 2px dashed rgba(255, 255, 255, 0.3);
border-radius: 15px;
padding: 20px;
transition: all 0.3s ease;
color: white;
}
.file-input:hover {
border-color: #667eea;
background: rgba(255, 255, 255, 0.2);
}
.btn-upload {
background: var(--success-gradient);
border: none;
border-radius: 15px;
color: white;
font-weight: 600;
padding: 12px 30px;
transition: all 0.3s ease;
text-transform: uppercase;
letter-spacing: 1px;
}
.btn-upload:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(56, 239, 125, 0.4);
color: white;
}
/* Files Table */
.files-card {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
transition: all 0.3s ease;
/* --- CONSIDERACIÓN: Si estas tarjetas siguen por encima, podrías darles un z-index más bajo
Pero primero prueba el cambio en navbar-custom */
/* z-index: 1; */
}
.table-custom {
background: rgba(0, 0, 0, 0.3);
border-radius: 15px;
overflow: hidden;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}
.table-custom th {
background: rgba(0, 0, 0, 0.6);
color: white;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
padding: 20px 15px;
border: none;
}
.table-custom td {
background: rgba(255, 255, 255, 0.05);
color: white;
padding: 15px;
border: 1px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
}
.table-custom tr:hover td {
background: rgba(255, 255, 255, 0.1);
transform: scale(1.02);
}
/* Action Button */
.btn-action {
background: var(--secondary-gradient);
border: none;
border-radius: 50%;
color: white;
width: 45px;
height: 45px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
cursor: pointer;
}
.btn-action:hover {
transform: scale(1.2) rotate(360deg);
box-shadow: 0 8px 20px rgba(147, 189, 251, 0.4);
}
/* Modal Improvements */
.modal-content {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.modal-header {
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding: 25px 30px;
}
.modal-title {
color: white;
font-weight: 600;
}
.modal-body {
padding: 30px;
}
.modal-footer {
border-top: 1px solid rgba(255, 255, 255, 0.2);
padding: 20px 30px;
gap: 10px;
}
.modal-footer .btn {
border-radius: 50%;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
border: none;
transition: all 0.3s ease;
color: white;
}
.modal-footer .btn:nth-child(1) {
background: linear-gradient(135deg, #6bff72, #52ee6c);
}
.modal-footer .btn:nth-child(2) {
background: linear-gradient(135deg, #4ecdc4, #44a08d);
}
.modal-footer .btn:nth-child(3) {
background: linear-gradient(135deg, #45b7d1, #96c93d);
}
.modal-footer .btn:nth-child(4) {
background: linear-gradient(135deg, #79a3ff, #ff0022);
border-radius: 25px;
width: auto;
padding: 10px 25px;
}
.modal-footer .btn:hover {
transform: translateY(-3px) scale(1.1);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
}
/* --- CAMBIO CLAVE AQUÍ --- */
/* Dropdown Menu */
.dropdown-menu {
/* Asegúrate de que position no sea 'static' */
position: absolute;
/* Necesita ser un z-index mayor que la navbar si el dropdown está fuera del flujo normal de la navbar (Bootstrap lo suele manejar),
o si el navbar tiene un z-index. Un valor como 1050 es un buen punto de partida, pero podemos subirlo. */
z-index: 1070; /* Mayor que el z-index de la navbar-custom */
background: rgba(0, 0, 0, 0.9);
backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
color: white;
padding: 20px;
min-width: 300px;
}
/* --- FIN CAMBIO CLAVE --- */
.user-header {
text-align: center; text-align: center;
padding: 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
margin-bottom: 15px;
} }
.user-header{
background-color: #255977; .user-header img {
color: white width: 80px;
height: 80px;
border-radius: 50%;
border: 3px solid #667eea;
box-shadow: 0 0 20px rgba(102, 126, 234, 0.5);
}
.user-header p {
margin-top: 15px;
color: white;
} }
.user-body { .user-body {
padding: 15px; margin: 15px 0;
border-bottom: 1px solid #f4f4f4;
border-top: 1px solid #dddddd;
background-color: #255977;
} }
.user-body a {
color: #667eea;
text-decoration: none;
transition: all 0.3s ease;
}
.user-body a:hover {
color: #75acff;
}
.user-footer { .user-footer {
display: flex; display: flex;
background-color: #8d8d8d; justify-content: space-between;
padding: 10px; margin-top: 20px;
padding-top: 15px;
border-top: 1px solid rgba(255, 255, 255, 0.2);
} }
.pull-left{
box-sizing: border-box; .user-footer .btn {
width: 50%; background: var(--primary-gradient);
border: none;
border-radius: 20px;
color: white;
padding: 8px 20px;
font-size: 14px;
transition: all 0.3s ease;
} }
.pull-right{
box-sizing: border-box; .user-footer .btn:hover {
width: 50%; transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
} }
#id_usuario{
/* Animations */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fadeInUp {
animation: fadeInUp 0.6s ease-out;
}
/* Responsive */
@media (max-width: 768px) {
.upload-title {
font-size: 2rem;
}
} .upload-card, .files-card {
/*#TEST_COLORS{ padding: 20px;
#98BFDA }
#FEDE58
#98D8A5 .main-container {
#FE9898 padding: 0 10px;
#FE98FE }
#FFFFFF }
#FFEEEC
#FEFDED
#EAFFE5
#ECFDFF
#F0F1FE
#FFEBFA
}*/

View File

@@ -29,11 +29,11 @@
function modal(url) { function modal(url) {
var array = url.split("."); var array = url.split(".");
var tipo = array.pop(); var tipo = array.pop();
var contentHTML = ''; // Variable para almacenar el HTML a inyectar
if (modo_img(tipo)) { if (modo_img(tipo)) {
//$("#img").attr("src","files/"+url); contentHTML = `<img class="img-fluid rounded" src="files/${url}" style="border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3);">`;
document.getElementById("data").innerHTML = `<img class="img-fluid rounded" src="files/${url}">`;
} else if (modo_video(tipo)) { } else if (modo_video(tipo)) {
//var alto = window.innerHeight;
var anch = window.innerWidth; var anch = window.innerWidth;
var porc = 10; var porc = 10;
if (anch > 1400) { if (anch > 1400) {
@@ -47,192 +47,301 @@
} else if (anch > 576) { } else if (anch > 576) {
porc = 35; porc = 35;
} }
//console.log("Ancho Original: "+anch+", Alto Original: "+alto); contentHTML = `
//console.log("Ancho -10%: "+(anch-(anch * porc/100))+", Alto: "+alto); <video id="rep-video" width="${anch - (anch * porc / 100)}" controls preload="auto" style="border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3);">
var ctrl_video = `
<video id="rep-video" width="${anch - (anch * porc / 100)}" controls preload="auto">
<source src="files/${url}" type="video/${tipo}"> <source src="files/${url}" type="video/${tipo}">
</video>`; </video>`;
document.getElementById("data").innerHTML = ctrl_video;
} else if (modo_music(tipo)) { } else if (modo_music(tipo)) {
var ctrl_audio = `<div class="text-center "><img src="img/Music-icon.png"> contentHTML = `<div class="text-center">
<video controls preload="auto" id="ctrl_audio"> <img src="img/Music-icon.png" style="width: 100px; height: 100px; border-radius: 50%; box-shadow: 0 10px 30px rgba(0,0,0,0.3); margin-bottom: 20px;">
<video controls preload="auto" id="ctrl_audio" style="width: 100%; border-radius: 15px;">
<source src="files/${url}" type="audio/${tipo}"> <source src="files/${url}" type="audio/${tipo}">
</video></div>`; </video></div>`;
document.getElementById("data").innerHTML = ctrl_audio; } else if (modo_pdf(tipo)) { // *** NUEVA LÓGICA PARA PDF ***
// Usamos un iframe para incrustar el PDF. El navegador lo renderizará.
// Se añade estilo para que el iframe ocupe el espacio disponible y tenga un buen aspecto.
contentHTML = `
<div style="width: 100%; height: 60vh;"> <iframe src="files/${url}" style="width: 100%; height: 100%; border: none; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3);">
Este navegador no soporta PDFs incrustados. Puedes descargarlo <a href="files/${url}">aquí</a>.
</iframe>
</div>
`;
} else { } else {
document.getElementById("data").innerHTML = `<img class="img-fluid rounded" src="img/desc256.png">`; contentHTML = `<img class="img-fluid rounded" src="img/desc256.png" style="border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3);">`;
} }
document.getElementById("titulo").innerHTML = `Descargar: <a href="files/${url}">${url}</a>`;
document.getElementById("data").innerHTML = contentHTML; // Inyecta el HTML generado
document.getElementById("titulo").innerHTML = `<i class="fas fa-download me-2"></i>Descargar: <a href="files/${url}" style="color: #667eea; text-decoration: none;">${url}</a>`;
$("#myModal").modal({ backdrop: true }); $("#myModal").modal({ backdrop: true });
} }
function modo_img(file) { function modo_img(file) {
var tipoImg = ["jpg", "jpeg", "png","gif", "bmp", "tiff", "svg", "webp", "ico", "psd", "ai", "eps", "raw", "cr2", "nef", "orf", "sr2", "rw2", "dng", "arw", "3fr", "dcr", "kdc", "erf", "mrw", "pef", "raf", "x3f", "srw", "rwl", "r3d", "rwz", "z6ii", "z5", "drf", "k25", "bay", "cap", "iiq", "fff", "mef", "mos", "crw", "erf", "kdc", "dcs", "gpr", "mef", "mos", "nef", "nrw", "orf", "raw", "rw2", "rwl", "sr2", "srf", "x3f"]; var tipoImg = ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "svg", "webp", "ico", "psd", "ai", "eps", "raw", "cr2", "nef", "orf", "sr2", "rw2", "dng", "arw", "3fr", "dcr", "kdc", "erf", "mrw", "pef", "raf", "x3f", "srw", "rwl", "r3d", "rwz", "z6ii", "z5", "drf", "k25", "bay", "cap", "iiq", "fff", "mef", "mos", "crw", "erf", "kdc", "dcs", "gpr", "mef", "mos", "nef", "nrw", "orf", "raw", "rw2", "rwl", "sr2", "srf", "x3f"];
var std = false; return tipoImg.includes(file.toLowerCase());
tipoImg.forEach((item, i) => {
if (file == item) {
console.log(item);
std = true;
}
});
return std;
} }
function modo_video(file) { function modo_video(file) {
var tipoImg = ["mp4", "mpg", "webm","avi", "mkv", "mov", "wmv", "flv", "3gp", "m4v"]; var tipoVideo = ["mp4", "mpg", "webm", "avi", "mkv", "mov", "wmv", "flv", "3gp", "m4v"];
var std = false; return tipoVideo.includes(file.toLowerCase());
tipoImg.forEach((item, i) => {
console.log(item);
if (file == item) {
//console.log(item);
std = true;
}
});
return std;
} }
function modo_music(file) { function modo_music(file) {
var tipoImg = ["mp3", "acc", "wav", "wma", "ogg", "m4a"]; var tipoMusic = ["mp3", "acc", "wav", "wma", "ogg", "m4a"];
var std = false; return tipoMusic.includes(file.toLowerCase());
tipoImg.forEach((item, i) => {
if (file == item) {
console.log(item);
std = true;
}
});
return std;
} }
// *** NUEVA FUNCIÓN PARA IDENTIFICAR PDF ***
function modo_pdf(file) {
var tipoPdf = ["pdf"];
return tipoPdf.includes(file.toLowerCase());
}
// --- CÓDIGO DE BÚSQUEDA ---
$(document).ready(function() {
$('form.search-container').submit(function(event) {
event.preventDefault();
});
$('#searchInput').on('keyup', function() {
var searchText = $(this).val().toLowerCase();
$('#filesTableBody tr').each(function() {
var fileName = $(this).find('.file-name').text().toLowerCase();
if (fileName.includes(searchText)) {
$(this).show();
} else {
$(this).hide();
}
});
});
// --- CÓDIGO PARA LA SUBIDA AJAX Y MODAL ---
const uploadForm = document.getElementById('uploadForm');
const fileInput = document.getElementById('fileInput');
const messageModal = document.getElementById('messageModal');
const modalTitle = document.getElementById('modalTitleMessage');
const modalMessage = document.getElementById('modalBodyMessage');
const modalCloseButton = document.getElementById('modalCloseButton');
uploadForm.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const submitButton = this.querySelector('input[type="submit"]');
submitButton.disabled = true;
submitButton.value = 'Subiendo...';
fetch(this.action, {
method: this.method,
body: formData
})
.then(response => {
if (!response.ok) {
return response.json().then(errorData => {
throw new Error(errorData.message || 'Error en la respuesta del servidor');
});
}
return response.json();
})
.then(data => {
if (data.status === 'success') {
modalTitle.textContent = '¡Subida Exitosa!';
modalMessage.textContent = data.message;
} else {
modalTitle.textContent = 'Error en la Subida';
modalMessage.textContent = data.message || 'Ocurrió un error desconocido al subir el archivo.';
}
$('#messageModal').modal('show');
})
.catch(error => {
console.error('Error al subir el archivo:', error);
modalTitle.textContent = 'Error de Conexión';
modalMessage.textContent = 'No se pudo conectar con el servidor o hubo un error inesperado: ' + error.message;
$('#messageModal').modal('show');
})
.finally(() => {
submitButton.disabled = false;
submitButton.value = '📤 SUBIR ARCHIVO';
fileInput.value = '';
});
});
$('#messageModal').on('hidden.bs.modal', function (e) {
// Puedes agregar lógica aquí, por ejemplo, recargar la página
// para que la lista de archivos se actualice automáticamente.
// window.location.reload();
// O mejor: realizar otra solicitud AJAX para obtener la lista actualizada de archivos.
});
});
document.addEventListener('DOMContentLoaded', function() {
const elements = document.querySelectorAll('.upload-card, .files-card');
elements.forEach((el, index) => {
el.style.animationDelay = `${index * 0.2}s`;
el.classList.add('animate-fadeInUp');
});
});
</script> </script>
</head> </head>
<body> <body>
<!-- ENCABEZADO O MENU ---> <nav class="navbar navbar-expand navbar-dark navbar-custom">
<nav class="navbar navbar-expand navbar-dark bg-dark">
<div class="container-fluid"> <div class="container-fluid">
<div id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <div id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<a class="navbar-brand dropdown-toggle" href="#"> <a class="navbar-brand dropdown-toggle" href="#">
<img src="img/favicon_sigma/android-chrome-192x192.png" alt="" width="36" height="36"> <img src="img/favicon_sigma/android-chrome-192x192.png" alt="Cloud SIGMA" width="36" height="36">
</a> </a>
<div class="dropdown-menu" aria-labelledby="dropdownMenu2"> <div class="dropdown-menu" aria-labelledby="dropdownMenu2">
<ul> <div class="user-header">
<li class="user-header"> <img src="img/usuario.jpeg" class="img-circle" alt="User Image">
<img src="img/usuario.jpeg" class="img-circle" alt="User Image"> <p>
<p> <strong>ID# <span id="usr_id">8</span></strong><br>
ID# <span id="usr_id">8</span> - <strong>Usuario: <span id="usr_nom">PABLO FARIAS</span></strong><br>
Usuario: <span id="usr_nom">PABLO FARIAS</span><br> <small>Miembro desde: <span id="usr_reg">2022-02-18 23:39:00</span></small>
<small>Miembro desde: <span id="usr_reg">2022-02-18 23:39:00</span></small> </p>
</p> </div>
<li class="user-body"> <div class="user-body">
<div class="row"> <div class="row text-center">
<div class="col-xs-4 text-center"> <div class="col-4">
<a href="#">Seguidores</a> <a href="#"><i class="fas fa-users me-1"></i>Seguidores</a>
</div>
<div class="col-xs-4 text-center">
<a href="#">UID: 64b06b022c7b9</a>
</div>
<div class="col-xs-4 text-center">
<a href="#">Amigos</a>
</div>
</div>
<!-- /.row -->
</li>
<li class="user-footer">
<div class="pull-left">
<a href="#" class="btn btn-default btn-flat">Perfil</a>
</div> </div>
<div class="pull-right"> <div class="col-4">
<a href="../cloud" class="btn btn-default btn-flat">Cerrar Session</a> <a href="#"><i class="fas fa-id-card me-1"></i>UID: 64b06b022c7b9</a>
</div> </div>
</li> <div class="col-4">
</ul> <a href="#"><i class="fas fa-user-friends me-1"></i>Amigos</a>
</div>
</div>
</div>
<div class="user-footer">
<a href="#" class="btn"><i class="fas fa-user me-1"></i>Perfil</a>
<a href="../cloud" class="btn"><i class="fas fa-sign-out-alt me-1"></i>Cerrar Sesión</a>
</div>
</div> </div>
</div> </div>
<form class="d-flex"> <form class="d-flex search-container">
<input class="form-control me-2" type="search" placeholder="Buscar Archivo" aria-label="Search"> <input class="form-control me-2" type="search" placeholder="🔍 Buscar Archivo" aria-label="Search" id="searchInput">
<button class="btn btn-outline-success" type="submit">Buscar</button> <button class="btn btn-search" type="submit">
<i class="fas fa-search"></i>
</button>
</form> </form>
</div> </div>
</nav> </nav>
<!-- formulario para subir archivos ---> <div class="container main-container">
<div class="container"> <div class="row">
<div class="row upload"> <div class="col-lg-12">
<div class="col-lg mt-2"> <div class="upload-card">
<label for="basic-url" class="form-label info">SIGMA Cloud</label> <h1 class="upload-title">
<form class="d-flex" method="POST" action="/upload" enctype="multipart/form-data"> <i class="fas fa-cloud-upload-alt me-3"></i>SIGMA Cloud
<div class="input-group"> </h1>
<input type="file" name="file_toUpload" class="form-control" /> <form id="uploadForm" class="d-flex" method="POST" action="/upload" enctype="multipart/form-data">
<input type="submit" class="btn btn-outline-secondary" /> <div class="input-group">
</div> <input type="file" name="file_toUpload" class="form-control file-input" id="fileInput" />
</form> <input type="submit" class="btn btn-upload" value="📤 SUBIR ARCHIVO" />
</div> </div>
<!-- RENDER formulario para subir archivos ---> </form>
<div class="col-lg mt-2 files">
<div class="row">
<table class="table table-dark">
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Fecha</th>
<th>Accion</th>
</tr>
<% for (i in data) { %>
<tr>
<td><span>
<%= data[i].indice%>
</span></td>
<td>
<!--a href="<%= data[i].link %>"><%= data[i].archivo %></a-->
<span>
<%= data[i].archivo %>
</span>
</td>
<td>fecha</td>
<td>
<button type="button" name="button" onclick="modal('<%= data[i].archivo %>')">
<i class="fas fa-play"></i>
</button>
</td>
</tr>
<% } %>
</table>
</div> </div>
</div> </div>
</div>
<!-- EDITAR DATOS Y VISUALIZAR archivos ---> <div class="col-lg-12">
<div class="modal fade" tabindex="-1" id="myModal"> <div class="files-card">
<div class="modal-dialog modal-lg" role="document"> <div class="row">
<div class="modal-content"> <div class="col-12">
<div class="modal-header"> <table class="table table-custom">
<div id="titulo">URL</div> <thead>
<button class="close" data-dismiss="modal" aria-label="cerar"> <tr>
<span aria-hidden="true">&times;</span> <th><i class="fas fa-hashtag me-2"></i>ID</th>
</button> <th><i class="fas fa-file me-2"></i>Nombre</th>
</div> <th><i class="fas fa-calendar me-2"></i>Fecha</th>
<div class="modal-body"> <th><i class="fas fa-cogs me-2"></i>Acción</th>
<div id="data"> </tr>
<!--img class="img-fluid rounded" id="img" src="" alt=""--> </thead>
<tbody id="filesTableBody"> <% for (i in data) { %>
<tr>
<td>
<span class="badge bg-primary rounded-pill">
<%= data[i].indice %>
</span>
</td>
<td>
<span class="file-name">
<i class="fas fa-file-alt me-2"></i>
<%= data[i].archivo %>
</span>
</td>
<td>
<span class="text-muted">
<i class="fas fa-clock me-1"></i>
fecha
</span>
</td>
<td>
<button type="button" class="btn-action" onclick="modal('<%= data[i].archivo %>')" title="Ver archivo">
<i class="fas fa-play"></i>
</button>
</td>
</tr>
<% } %>
</tbody>
</table>
</div> </div>
</div> </div>
<div class="modal-footer">
<button class="btn" type="button">
<i data-fa-symbol="delete" class="fas fa-trash fa-fw"></i>
</button>
<button class="btn" type="button">
<i data-fa-symbol="edit" class="fas fa-pencil fa-fw"></i>
</button>
<button class="btn" type="button">
<i data-fa-symbol="compartir" class="fa-solid fa-share-nodes"></i>
</button>
<button class="btn btn-warnigb" type="button" data-dismiss="modal"> Aceptar</button>
</div>
</div> </div>
</div> </div>
</div> </div>
</body> </div>
<div class="modal fade" tabindex="-1" id="myModal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="titulo">Archivo</h5>
<button type="button" class="btn-close btn-close-white" data-dismiss="modal" aria-label="Cerrar">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="data" class="text-center">
</div>
</div>
<div class="modal-footer">
<button class="btn" type="button" title="Eliminar">
<i class="fas fa-trash"></i>
</button>
<button class="btn" type="button" title="Editar">
<i class="fas fa-edit"></i>
</button>
<button class="btn" type="button" title="Compartir">
<i class="fas fa-share-nodes"></i>
</button>
<button class="btn" type="button" data-dismiss="modal">
<i class="fas fa-check me-2"></i>Aceptar
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" id="messageModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalTitleMessage"></h5>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Cerrar">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p id="modalBodyMessage"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" id="modalCloseButton">Cerrar</button>
</div>
</div>
</div>
</div>
</body>
</html> </html>