You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
393 lines
19 KiB
393 lines
19 KiB
@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') }}">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
|
|
<style>
|
|
.contenedor-flex {
|
|
display: flex;
|
|
gap: 32px;
|
|
align-items: flex-start;
|
|
justify-content: center;
|
|
flex-wrap: nowrap;
|
|
height: 100%;
|
|
}
|
|
.tabla-reporte {
|
|
font-family: 'Century Gothic', sans-serif;
|
|
font-size: 12px;
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
min-width: 500px;
|
|
max-width: 800px;
|
|
background: #fff;
|
|
box-shadow: 0 2px 8px #0001;
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
margin: 0 auto;
|
|
}
|
|
.tabla-reporte th, .tabla-reporte td {
|
|
border: 1px solid #e2e8f0;
|
|
padding: 8px;
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
}
|
|
.tabla-reporte th {
|
|
background: #f7fafc;
|
|
font-weight: bold;
|
|
}
|
|
.miniatura-img {
|
|
width: 50px;
|
|
height: 50px;
|
|
object-fit: cover;
|
|
border-radius: 6px;
|
|
border: 1px solid #ccc;
|
|
}
|
|
</style>
|
|
|
|
<body class="user-dashboard-bg">
|
|
<!-- Botón de cerrar sesión -->
|
|
<div class="user-dashboard-logout">
|
|
<form method="POST" action="{{ route('logout') }}">
|
|
@csrf
|
|
<button type="submit" class="user-dashboard-logout-btn">
|
|
<i class="fas fa-sign-out-alt"></i> Cerrar Sesión
|
|
</button>
|
|
</form>
|
|
</div>
|
|
<div class="user-dashboard-header">PrestamosTecmm</div>
|
|
<div class="contenedor-flex">
|
|
<div class="user-dashboard-card" style="min-width:350px;max-width:400px;flex:1; margin-top:40px;">
|
|
<h1 class="user-dashboard-title">Reporte de Usuario</h1>
|
|
<form id="form-reporte" style="font-family: 'Century Gothic', sans-serif; font-size: 12px;">
|
|
<div style="margin-bottom: 18px; text-align:left;">
|
|
<label for="foto_gasolina_inicio" style="font-weight:600; color:#2d3748;">Foto de la gasolina (antes de salir):</label><br><br>
|
|
<input type="file" id="foto_gasolina_inicio" name="foto_gasolina_inicio" accept="image/*" style="width:100%;">
|
|
</div>
|
|
<div style="margin-bottom: 18px; text-align:left;">
|
|
<label for="foto_vehiculo" style="font-weight:600; color:#2d3748;">Foto del vehículo:</label><br><br>
|
|
<input type="file" id="foto_vehiculo" name="foto_vehiculo" accept="image/*" style="width:100%;">
|
|
</div>
|
|
<div style="margin-bottom: 18px; text-align:left;">
|
|
<label for="foto_gasolina_fin" style="font-weight:600; color:#2d3748;">Foto de la gasolina (después de regresar):</label><br><br>
|
|
<input type="file" id="foto_gasolina_fin" name="foto_gasolina_fin" accept="image/*" style="width:100%;">
|
|
</div>
|
|
<div style="margin-bottom: 18px; text-align:left;">
|
|
<label for="fecha_salida" style="font-weight:600; color:#2d3748;">Fecha y hora de salida:</label><br><br>
|
|
<input type="datetime-local" id="fecha_salida" name="fecha_salida" style="width:100%; padding:8px; border-radius:6px; border:1px solid #ccc;">
|
|
</div>
|
|
<div style="margin-bottom: 18px; text-align:left;">
|
|
<label for="fecha_regreso" style="font-weight:600; color:#2d3748;">Fecha y hora de regreso:</label><br><br>
|
|
<input type="datetime-local" id="fecha_regreso" name="fecha_regreso" style="width:100%; padding:8px; border-radius:6px; border:1px solid #ccc;">
|
|
</div>
|
|
<div style="margin-bottom: 18px; text-align:left;">
|
|
<label for="motivo" style="font-weight:600; color:#2d3748;">Motivo del préstamo:</label><br><br>
|
|
<textarea id="motivo" name="motivo" style="width:100%; padding:8px; border-radius:6px; border:1px solid #ccc; min-height:100px;" placeholder="Especifique el motivo del préstamo del vehículo..."></textarea>
|
|
</div>
|
|
<button type="submit" class="user-dashboard-btn" style="width:100%; margin-top:10px;">Guardar</button>
|
|
</form>
|
|
</div>
|
|
<div style="flex:1; min-width:350px; max-width:800px;">
|
|
<table class="tabla-reporte" id="tabla-reporte">
|
|
<thead>
|
|
<tr>
|
|
<th>Gasolina (salida)</th>
|
|
<th>Vehículo</th>
|
|
<th>Gasolina (regreso)</th>
|
|
<th>Fecha salida</th>
|
|
<th>Fecha regreso</th>
|
|
<th>Motivo</th>
|
|
<th>Acciones</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Aquí se agregarán los registros -->
|
|
</tbody>
|
|
</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
|
|
const fotoGasIni = document.getElementById('foto_gasolina_inicio').files[0];
|
|
const fotoVehiculo = document.getElementById('foto_vehiculo').files[0];
|
|
const fotoGasFin = document.getElementById('foto_gasolina_fin').files[0];
|
|
const fechaSalida = document.getElementById('fecha_salida').value;
|
|
const fechaRegreso = document.getElementById('fecha_regreso').value;
|
|
const motivo = document.getElementById('motivo').value;
|
|
|
|
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 ? archivo.name : ''}"><br><span>${archivo.name}</span></div>`;
|
|
}
|
|
|
|
// 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 = `
|
|
<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>
|
|
`;
|
|
tabla.appendChild(fila);
|
|
document.getElementById('form-reporte').reset();
|
|
asignarEventosMiniaturas();
|
|
asignarEventosAcciones();
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: '¡Guardado correctamente!',
|
|
showConfirmButton: false,
|
|
timer: 1500
|
|
});
|
|
});
|
|
|
|
// Modal para mostrar imagen grande
|
|
function crearModalImagen() {
|
|
if (document.getElementById('modal-img-grande')) return;
|
|
const modal = document.createElement('div');
|
|
modal.id = 'modal-img-grande';
|
|
modal.style.position = 'fixed';
|
|
modal.style.top = 0;
|
|
modal.style.left = 0;
|
|
modal.style.width = '100vw';
|
|
modal.style.height = '100vh';
|
|
modal.style.background = 'rgba(0,0,0,0.7)';
|
|
modal.style.display = 'none';
|
|
modal.style.alignItems = 'center';
|
|
modal.style.justifyContent = 'center';
|
|
modal.style.zIndex = 9999;
|
|
modal.style.cursor = 'pointer';
|
|
modal.innerHTML = `
|
|
<div style="position:relative; max-width:90vw; max-height:90vh;">
|
|
<span id="cerrar-modal-img" style="position:absolute;top:-30px;right:0;font-size:2rem;color:white;cursor:pointer;font-weight:bold;">×</span>
|
|
<img id="img-modal-grande" src="" alt="Imagen grande" style="max-width:90vw; max-height:80vh; border-radius:10px; box-shadow:0 2px 16px #0008; background:#fff;">
|
|
</div>
|
|
`;
|
|
document.body.appendChild(modal);
|
|
modal.addEventListener('click', function(e) {
|
|
if (e.target === modal || e.target.id === 'cerrar-modal-img') {
|
|
modal.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
function asignarEventosMiniaturas() {
|
|
crearModalImagen();
|
|
document.querySelectorAll('.img-clickable').forEach(img => {
|
|
img.onclick = function(e) {
|
|
e.stopPropagation();
|
|
const modal = document.getElementById('modal-img-grande');
|
|
const imgModal = document.getElementById('img-modal-grande');
|
|
imgModal.src = img.getAttribute('data-img-url');
|
|
modal.style.display = 'flex';
|
|
};
|
|
});
|
|
}
|
|
|
|
// 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
|
|
|