Browse Source
aqui implemnete mi dasbord de usuarios, el cual puede agregar fotos y visualizarlas en la misma tabla, ahi esta la tabla y puede hacer las fotos mas grandes para que pueda verlas, hace un reporte y agrega fechasmain
8 changed files with 385 additions and 3 deletions
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Http\Controllers; |
||||
|
|
||||
|
use Illuminate\Http\Request; |
||||
|
|
||||
|
class UserDashboardController extends Controller |
||||
|
{ |
||||
|
public function __construct() |
||||
|
{ |
||||
|
$this->middleware('auth'); |
||||
|
} |
||||
|
|
||||
|
public function index() |
||||
|
{ |
||||
|
// Verificar si el usuario tiene el correo específico |
||||
|
if (auth()->user()->email !== 'usuarios@usuariosgmail.com') { |
||||
|
return redirect('/')->with('error', 'No tienes permiso para acceder a esta sección'); |
||||
|
} |
||||
|
|
||||
|
return view('user-dashboard.index'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Database\Migrations\Migration; |
||||
|
use Illuminate\Database\Schema\Blueprint; |
||||
|
use Illuminate\Support\Facades\Schema; |
||||
|
use Illuminate\Support\Facades\DB; |
||||
|
use Illuminate\Support\Facades\Hash; |
||||
|
|
||||
|
return new class extends Migration |
||||
|
{ |
||||
|
public function up() |
||||
|
{ |
||||
|
// Verificar si el usuario ya existe |
||||
|
$user = DB::table('users')->where('email', 'usuarios@usuariosgmail.com')->first(); |
||||
|
|
||||
|
if (!$user) { |
||||
|
DB::table('users')->insert([ |
||||
|
'name' => 'Usuario Dashboard', |
||||
|
'email' => 'usuarios@usuariosgmail.com', |
||||
|
'password' => Hash::make('usuario123'), |
||||
|
'created_at' => now(), |
||||
|
'updated_at' => now(), |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function down() |
||||
|
{ |
||||
|
DB::table('users')->where('email', 'usuarios@usuariosgmail.com')->delete(); |
||||
|
} |
||||
|
}; |
@ -0,0 +1,85 @@ |
|||||
|
body.user-dashboard-bg { |
||||
|
background: linear-gradient(120deg, #4158D0 0%, #5068c8 46%, #70e7ff 100%); |
||||
|
min-height: 100vh; |
||||
|
} |
||||
|
|
||||
|
.user-dashboard-header { |
||||
|
font-size: 2.2rem; |
||||
|
font-weight: 900; |
||||
|
color: #fff; |
||||
|
letter-spacing: 1px; |
||||
|
margin-top: 32px; |
||||
|
margin-left: 60px; |
||||
|
margin-bottom: 30px; |
||||
|
text-shadow: 0 2px 8px rgba(65,88,208,0.15); |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
.user-dashboard-card { |
||||
|
background: #fff; |
||||
|
border-radius: 24px; |
||||
|
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15); |
||||
|
padding: 48px 32px; |
||||
|
max-width: 480px; |
||||
|
margin: 60px auto; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.user-dashboard-title { |
||||
|
font-size: 2.5rem; |
||||
|
font-weight: 800; |
||||
|
color: #2d3748; |
||||
|
margin-bottom: 18px; |
||||
|
} |
||||
|
|
||||
|
.user-dashboard-desc { |
||||
|
color: #6b7280; |
||||
|
font-size: 1.2rem; |
||||
|
margin-bottom: 32px; |
||||
|
} |
||||
|
|
||||
|
.user-dashboard-btn { |
||||
|
background: #4158D0; |
||||
|
color: #fff; |
||||
|
border: none; |
||||
|
border-radius: 8px; |
||||
|
padding: 14px 36px; |
||||
|
font-size: 1.1rem; |
||||
|
font-weight: 600; |
||||
|
box-shadow: 0 2px 8px rgba(65,88,208,0.15); |
||||
|
transition: background 0.2s; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.user-dashboard-btn:hover { |
||||
|
background: #C850C0; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
.user-dashboard-logout { |
||||
|
position: absolute; |
||||
|
top: 32px; |
||||
|
right: 60px; |
||||
|
z-index: 10; |
||||
|
} |
||||
|
.user-dashboard-logout-btn { |
||||
|
background: #e53e3e; |
||||
|
color: #fff; |
||||
|
border: none; |
||||
|
border-radius: 8px; |
||||
|
padding: 10px 22px; |
||||
|
font-size: 1rem; |
||||
|
font-weight: 600; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8px; |
||||
|
box-shadow: 0 2px 8px rgba(229,62,62,0.15); |
||||
|
transition: background 0.2s; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.user-dashboard-logout-btn:hover { |
||||
|
background: #c53030; |
||||
|
color: #fff; |
||||
|
} |
||||
|
.user-dashboard-logout-btn i { |
||||
|
font-size: 1.2rem; |
||||
|
} |
@ -0,0 +1,198 @@ |
|||||
|
@extends('layouts.app') |
||||
|
|
||||
|
@section('title', 'Reporte de Usuario - PrestamosTecmm') |
||||
|
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}"> |
||||
|
|
||||
|
@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> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<!-- Aquí se agregarán los registros --> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<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; |
||||
|
|
||||
|
// 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>`; |
||||
|
} |
||||
|
|
||||
|
// Insertar fila en la tabla |
||||
|
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> |
||||
|
`; |
||||
|
tabla.appendChild(fila); |
||||
|
|
||||
|
// Limpiar formulario |
||||
|
document.getElementById('form-reporte').reset(); |
||||
|
|
||||
|
// Volver a asignar eventos a todas las miniaturas |
||||
|
asignarEventosMiniaturas(); |
||||
|
}); |
||||
|
|
||||
|
// 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 = 'flex'; |
||||
|
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); |
||||
|
// 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'; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// Asignar evento a miniaturas |
||||
|
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'; |
||||
|
}; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// Inicializar eventos para miniaturas existentes (por si acaso) |
||||
|
window.onload = asignarEventosMiniaturas; |
||||
|
</script> |
||||
|
</body> |
||||
|
@endsection |
@ -0,0 +1,29 @@ |
|||||
|
@extends('layouts.app') |
||||
|
|
||||
|
@section('title', 'Dashboard - PrestamosTecmm') |
||||
|
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}"> |
||||
|
|
||||
|
@section('content') |
||||
|
<!-- Enlazamos el CSS personalizado solo para este dashboard --> |
||||
|
<link rel="stylesheet" href="{{ asset('css/user-dashboard.css') }}"> |
||||
|
<!-- Cargamos Font Awesome para el ícono --> |
||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
||||
|
|
||||
|
<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="user-dashboard-card"> |
||||
|
<h1 class="user-dashboard-title">Bienvenido a los Préstamos TecMM</h1> |
||||
|
<p class="user-dashboard-desc">Gestiona tus préstamos de manera fácil y rápida</p> |
||||
|
<a href="{{ url('/user-dashboard/cuestionario') }}" class="user-dashboard-btn">Ir a la siguiente sección</a> |
||||
|
</div> |
||||
|
</body> |
||||
|
@endsection |
Loading…
Reference in new issue