Browse Source

Añadi las acciones completas

edita, elimina, agrega fotos, lo guarda en una tabla, genera el reporte en pdf con sus respectivas imagenes, ya quedo perron jsjsjs
main
Rubi 3 weeks ago
parent
commit
0c56ac8291
  1. 219
      resources/views/user-dashboard/cuestionario.blade.php
  2. 2
      resources/views/user-dashboard/index.blade.php

219
resources/views/user-dashboard/cuestionario.blade.php

@ -1,7 +1,9 @@
@extends('layouts.app')
@section('title', 'Reporte de Usuario - PrestamosTecmm')
@push('head')
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}">
@endpush
@section('content')
<link rel="stylesheet" href="{{ asset('css/user-dashboard.css') }}">
@ -100,6 +102,7 @@
<th>Fecha salida</th>
<th>Fecha regreso</th>
<th>Motivo</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
@ -108,7 +111,24 @@
</table>
</div>
</div>
<!-- jsPDF y autoTable -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.7.0/jspdf.plugin.autotable.min.js"></script>
<script>
// Iconos SVG para editar, eliminar y PDF
const iconoEditar = `<button type='button' class='btn-accion editar' title='Editar' style='background:none;border:none;cursor:pointer;'><i class="fas fa-edit" style="color:#3182ce;font-size:20px;"></i></button>`;
const iconoEliminar = `<button type='button' class='btn-accion eliminar' title='Eliminar' style='background:none;border:none;cursor:pointer;'><i class="fas fa-trash-alt" style="color:#e53e3e;font-size:20px;"></i></button>`;
const iconoPDF = `<button type='button' class='btn-accion pdf' title='Generar PDF' style='background:none;border:none;cursor:pointer;'><i class="fas fa-file-pdf" style="color:#e53e3e;font-size:20px;"></i></button>`;
let filaEditando = null;
// Agregar SweetAlert2 CDN si no está
if (!window.Swal) {
var script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/sweetalert2@11';
document.head.appendChild(script);
}
document.getElementById('form-reporte').addEventListener('submit', function(e) {
e.preventDefault();
// Obtener los archivos y datos
@ -119,14 +139,37 @@
const fechaRegreso = document.getElementById('fecha_regreso').value;
const motivo = document.getElementById('motivo').value;
// Función para crear miniatura o mostrar nombre si no hay archivo
function crearMiniatura(archivo) {
if (!archivo) return '';
const url = URL.createObjectURL(archivo);
return `<div><img src="${url}" class='miniatura-img img-clickable' data-img-url="${url}" alt="${archivo.name}"><br><span>${archivo.name}</span></div>`;
return `<div><img src="${url}" class='miniatura-img img-clickable' data-img-url="${url}" alt="${archivo ? archivo.name : ''}"><br><span>${archivo.name}</span></div>`;
}
// Insertar fila en la tabla
// Si estamos editando una fila, actualizamos esa fila y no agregamos una nueva
if (filaEditando) {
filaEditando.innerHTML = `
<td>${crearMiniatura(fotoGasIni)}</td>
<td>${crearMiniatura(fotoVehiculo)}</td>
<td>${crearMiniatura(fotoGasFin)}</td>
<td>${fechaSalida ? fechaSalida.replace('T', ' ') : ''}</td>
<td>${fechaRegreso ? fechaRegreso.replace('T', ' ') : ''}</td>
<td>${motivo}</td>
<td>${iconoEditar}${iconoEliminar}${iconoPDF}</td>
`;
filaEditando = null;
document.getElementById('form-reporte').reset();
asignarEventosMiniaturas();
asignarEventosAcciones();
Swal.fire({
icon: 'success',
title: '¡Editado correctamente!',
showConfirmButton: false,
timer: 1500
});
return;
}
// Si no estamos editando, agregamos una nueva fila
const tabla = document.getElementById('tabla-reporte').querySelector('tbody');
const fila = document.createElement('tr');
fila.innerHTML = `
@ -136,14 +179,18 @@
<td>${fechaSalida ? fechaSalida.replace('T', ' ') : ''}</td>
<td>${fechaRegreso ? fechaRegreso.replace('T', ' ') : ''}</td>
<td>${motivo}</td>
<td>${iconoEditar}${iconoEliminar}${iconoPDF}</td>
`;
tabla.appendChild(fila);
// Limpiar formulario
document.getElementById('form-reporte').reset();
// Volver a asignar eventos a todas las miniaturas
asignarEventosMiniaturas();
asignarEventosAcciones();
Swal.fire({
icon: 'success',
title: '¡Guardado correctamente!',
showConfirmButton: false,
timer: 1500
});
});
// Modal para mostrar imagen grande
@ -157,7 +204,7 @@
modal.style.width = '100vw';
modal.style.height = '100vh';
modal.style.background = 'rgba(0,0,0,0.7)';
modal.style.display = 'flex';
modal.style.display = 'none';
modal.style.alignItems = 'center';
modal.style.justifyContent = 'center';
modal.style.zIndex = 9999;
@ -169,7 +216,6 @@
</div>
`;
document.body.appendChild(modal);
// Cerrar modal al hacer clic fuera de la imagen o en la X
modal.addEventListener('click', function(e) {
if (e.target === modal || e.target.id === 'cerrar-modal-img') {
modal.style.display = 'none';
@ -177,7 +223,6 @@
});
}
// Asignar evento a miniaturas
function asignarEventosMiniaturas() {
crearModalImagen();
document.querySelectorAll('.img-clickable').forEach(img => {
@ -191,8 +236,158 @@
});
}
// Inicializar eventos para miniaturas existentes (por si acaso)
window.onload = asignarEventosMiniaturas;
// Asignar eventos a los botones de editar, eliminar y PDF
function asignarEventosAcciones() {
document.querySelectorAll('.btn-accion.eliminar').forEach(btn => {
btn.onclick = function() {
Swal.fire({
title: '¿Estás seguro?',
text: 'Esta acción no se puede deshacer',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Sí, eliminar',
cancelButtonText: 'Cancelar'
}).then((result) => {
if (result.isConfirmed) {
const fila = btn.closest('tr');
fila.remove();
Swal.fire({
icon: 'success',
title: '¡Eliminado correctamente!',
showConfirmButton: false,
timer: 1500
});
}
});
};
});
document.querySelectorAll('.btn-accion.editar').forEach(btn => {
btn.onclick = function() {
const fila = btn.closest('tr');
const celdas = fila.querySelectorAll('td');
document.getElementById('foto_gasolina_inicio').value = '';
document.getElementById('foto_vehiculo').value = '';
document.getElementById('foto_gasolina_fin').value = '';
document.getElementById('fecha_salida').value = celdas[3].innerText.replace(' ', 'T');
document.getElementById('fecha_regreso').value = celdas[4].innerText.replace(' ', 'T');
document.getElementById('motivo').value = celdas[5].innerText;
filaEditando = fila;
window.scrollTo({top:0, behavior:'smooth'});
};
});
document.querySelectorAll('.btn-accion.pdf').forEach(btn => {
btn.onclick = function() {
const fila = btn.closest('tr');
const celdas = fila.querySelectorAll('td');
generarPDFPersonalizado({
motivo: celdas[5].innerText.trim(),
fechaSalida: celdas[3].innerText.trim(),
fechaRegreso: celdas[4].innerText.trim(),
imagenes: [
fila.querySelectorAll('img.miniatura-img')[0]?.src,
fila.querySelectorAll('img.miniatura-img')[1]?.src,
fila.querySelectorAll('img.miniatura-img')[2]?.src
].filter(Boolean),
callback: function() {
Swal.fire({
icon: 'success',
title: '¡PDF generado!',
showConfirmButton: false,
timer: 1500
});
}
});
};
});
}
// Generar PDF con la estructura solicitada, sin recuadros y fechas bien alineadas
function generarPDFPersonalizado(data) {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'letter' });
const pageWidth = doc.internal.pageSize.getWidth();
const pageHeight = doc.internal.pageSize.getHeight();
// Título
doc.setFont('helvetica', 'bold');
doc.setFontSize(30);
doc.text('PRESTAMOS TECMM', pageWidth / 2, 60, { align: 'center' });
// REPORTE
doc.setFontSize(13);
doc.setFont('helvetica', 'bold');
doc.text('REPORTE', 40, 110);
doc.setFont('helvetica', 'normal');
doc.setFontSize(12);
doc.text(data.motivo || '', 40, 130, { maxWidth: 250 });
// FECHA Y HORA (alineado a la derecha, una debajo de otra)
doc.setFont('helvetica', 'bold');
doc.setFontSize(13);
doc.text('FECHA Y HORA', 320, 110);
doc.setFont('helvetica', 'normal');
doc.setFontSize(12);
doc.text(`Salida: ${data.fechaSalida || ''}`, 320, 130);
doc.text(`Regreso: ${data.fechaRegreso || ''}`, 320, 150);
// LAS 3 IMÁGENES
doc.setFont('helvetica', 'bold');
doc.setFontSize(13);
doc.text('LAS 3 IMÁGENES', 320, 190);
let yImg = 210;
let xImg = 320;
const imagenes = (data.imagenes || []).filter(Boolean);
let cargadas = 0;
if (imagenes.length > 0) {
imagenes.forEach((src, idx) => {
if (src && src.startsWith('blob:')) {
const img = new window.Image();
img.crossOrigin = '';
img.onload = function() {
doc.addImage(img, 'PNG', xImg, yImg, 60, 60);
xImg += 70;
cargadas++;
if (cargadas === imagenes.length) {
// Firma
doc.setFont('helvetica', 'normal');
doc.setFontSize(15);
doc.line(150, 500, 350, 500);
doc.text('FIRMA', pageWidth / 2, 520, { align: 'center' });
doc.save('reporte_prestamo.pdf');
if (typeof data.callback === 'function') data.callback();
}
};
img.onerror = function() {
cargadas++;
if (cargadas === imagenes.length) {
doc.setFont('helvetica', 'normal');
doc.setFontSize(15);
doc.line(150, 500, 350, 500);
doc.text('FIRMA', pageWidth / 2, 520, { align: 'center' });
doc.save('reporte_prestamo.pdf');
if (typeof data.callback === 'function') data.callback();
}
};
img.src = src;
}
});
} else {
// Firma
doc.setFont('helvetica', 'normal');
doc.setFontSize(15);
doc.line(150, 500, 350, 500);
doc.text('FIRMA', pageWidth / 2, 520, { align: 'center' });
doc.save('reporte_prestamo.pdf');
if (typeof data.callback === 'function') data.callback();
}
}
window.onload = function() {
asignarEventosMiniaturas();
asignarEventosAcciones();
};
</script>
</body>
@endsection

2
resources/views/user-dashboard/index.blade.php

@ -1,7 +1,9 @@
@extends('layouts.app')
@section('title', 'Dashboard - PrestamosTecmm')
@push('head')
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}">
@endpush
@section('content')
<!-- Enlazamos el CSS personalizado solo para este dashboard -->

Loading…
Cancel
Save