Browse Source

Vista de Profesor

restringi el acceso de las funciones de administrador para aceptar prestamos y que solo se pueda hacer un nuevo prestamo y ya
main
TheSilva7 3 days ago
parent
commit
7d35710331
  1. 49
      app/Http/Controllers/SolicitudVehiculoController.php
  2. 3
      app/Http/Kernel.php
  3. 19
      app/Http/Middleware/CheckAdminRole.php
  4. 19
      app/Http/Middleware/CheckProfesorRole.php
  5. 26
      app/Models/SolicitudVehiculo.php
  6. 1
      app/Models/User.php
  7. 5
      database/migrations/2014_10_12_000000_create_users_table.php
  8. 28
      database/migrations/2024_03_27_000000_create_solicitud_vehiculos_table.php
  9. 28
      database/migrations/2025_05_08_175205_add_estado_to_prestamos_table.php
  10. 4
      database/seeders/DatabaseSeeder.php
  11. 22
      database/seeders/ProfesorSeeder.php
  12. 78
      resources/views/profesor/solicitudes/create.blade.php
  13. 51
      resources/views/profesor/solicitudes/index.blade.php
  14. 20
      routes/web.php

49
app/Http/Controllers/SolicitudVehiculoController.php

@ -0,0 +1,49 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\SolicitudVehiculo;
class SolicitudVehiculoController extends Controller
{
public function __construct()
{
$this->middleware(['auth', 'profesor']);
}
public function index()
{
$solicitudes = SolicitudVehiculo::where('user_id', auth()->id())->get();
return view('profesor.solicitudes.index', compact('solicitudes'));
}
public function create()
{
return view('profesor.solicitudes.create');
}
public function store(Request $request)
{
$request->validate([
'fecha_solicitud' => 'required|date',
'hora_salida' => 'required',
'hora_regreso' => 'required',
'destino' => 'required|string',
'motivo' => 'required|string',
]);
$solicitud = new SolicitudVehiculo();
$solicitud->user_id = auth()->id();
$solicitud->fecha_solicitud = $request->fecha_solicitud;
$solicitud->hora_salida = $request->hora_salida;
$solicitud->hora_regreso = $request->hora_regreso;
$solicitud->destino = $request->destino;
$solicitud->motivo = $request->motivo;
$solicitud->estado = 'pendiente';
$solicitud->save();
return redirect()->route('profesor.solicitudes.index')
->with('success', 'Solicitud creada exitosamente');
}
}

3
app/Http/Kernel.php

@ -60,8 +60,11 @@ class Kernel extends HttpKernel
'can' => \Illuminate\Auth\Middleware\Authorize::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
'signed' => \App\Http\Middleware\ValidateSignature::class, 'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'profesor' => \App\Http\Middleware\CheckProfesorRole::class,
'admin' => \App\Http\Middleware\CheckAdminRole::class,
]; ];
} }

19
app/Http/Middleware/CheckAdminRole.php

@ -0,0 +1,19 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckAdminRole
{
public function handle(Request $request, Closure $next): Response
{
if (!auth()->check() || auth()->user()->rol !== 'admin') {
return redirect('/')->with('error', 'No tienes permisos de administrador para acceder a esta sección.');
}
return $next($request);
}
}

19
app/Http/Middleware/CheckProfesorRole.php

@ -0,0 +1,19 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckProfesorRole
{
public function handle(Request $request, Closure $next): Response
{
if (!auth()->check() || auth()->user()->rol !== 'profesor') {
return redirect('/')->with('error', 'No tienes permiso para acceder a esta sección.');
}
return $next($request);
}
}

26
app/Models/SolicitudVehiculo.php

@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SolicitudVehiculo extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'fecha_solicitud',
'hora_salida',
'hora_regreso',
'destino',
'motivo',
'estado'
];
public function user()
{
return $this->belongsTo(User::class);
}
}

1
app/Models/User.php

@ -27,6 +27,7 @@ class User extends Authenticatable
'departamento_id', 'departamento_id',
'telefono', 'telefono',
'password', 'password',
'rol',
]; ];

5
database/migrations/2014_10_12_000000_create_users_table.php

@ -3,6 +3,7 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
return new class extends Migration return new class extends Migration
{ {
@ -23,6 +24,7 @@ return new class extends Migration
$table->string('telefono')->nullable(); $table->string('telefono')->nullable();
$table->string('password'); $table->string('password');
$table->string('rol')->default('profesor');
$table->rememberToken(); $table->rememberToken();
$table->timestamps(); $table->timestamps();
$table->foreign('puesto_id')->references('id')->on('puestos'); $table->foreign('puesto_id')->references('id')->on('puestos');
@ -33,7 +35,8 @@ return new class extends Migration
DB::table('users')->insert([ DB::table('users')->insert([
'name'=> 'Administrador', 'name'=> 'Administrador',
'email'=> 'admin@admin.com', 'email'=> 'admin@admin.com',
'password'=> bcrypt('12345678') 'password'=> bcrypt('12345678'),
'rol' => 'admin'
]); ]);
} }

28
database/migrations/2024_03_27_000000_create_solicitud_vehiculos_table.php

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('solicitud_vehiculos', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->date('fecha_solicitud');
$table->time('hora_salida');
$table->time('hora_regreso');
$table->string('destino');
$table->text('motivo');
$table->enum('estado', ['pendiente', 'aprobada', 'rechazada'])->default('pendiente');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('solicitud_vehiculos');
}
};

28
database/migrations/2025_05_08_175205_add_estado_to_prestamos_table.php

@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('prestamos', function (Blueprint $table) {
$table->enum('estado', ['pendiente', 'aceptado', 'rechazado'])->default('pendiente')->after('chofer');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('prestamos', function (Blueprint $table) {
$table->dropColumn('estado');
});
}
};

4
database/seeders/DatabaseSeeder.php

@ -18,5 +18,9 @@ class DatabaseSeeder extends Seeder
// 'name' => 'Test User', // 'name' => 'Test User',
// 'email' => 'test@example.com', // 'email' => 'test@example.com',
// ]); // ]);
$this->call([
ProfesorSeeder::class,
]);
} }
} }

22
database/seeders/ProfesorSeeder.php

@ -0,0 +1,22 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class ProfesorSeeder extends Seeder
{
public function run(): void
{
User::create([
'name' => 'Profesor',
'email' => 'profesor@profesor.com',
'password' => Hash::make('12345678'),
'rol' => 'profesor',
'apellido' => 'Ejemplo',
'telefono' => '1234567890',
]);
}
}

78
resources/views/profesor/solicitudes/create.blade.php

@ -0,0 +1,78 @@
@extends('layouts.dashboard')
@section('content')
<div class="container mx-auto px-4 py-6">
<div class="max-w-2xl mx-auto">
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
<div class="p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-6">Nueva Solicitud de Vehículo</h2>
@if($errors->any())
<div class="mb-6 bg-red-50 border-l-4 border-red-500 p-4 rounded-r-lg">
<div class="flex items-center">
<div class="text-red-700">
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<form action="{{ route('profesor.solicitudes.store') }}" method="POST">
@csrf
<div class="space-y-6">
<div>
<label for="fecha_solicitud" class="block text-sm font-medium text-gray-700 mb-2">Fecha de Solicitud</label>
<input type="date" name="fecha_solicitud" id="fecha_solicitud"
class="block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
required>
</div>
<div>
<label for="hora_salida" class="block text-sm font-medium text-gray-700 mb-2">Hora de Salida</label>
<input type="time" name="hora_salida" id="hora_salida"
class="block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
required>
</div>
<div>
<label for="hora_regreso" class="block text-sm font-medium text-gray-700 mb-2">Hora de Regreso</label>
<input type="time" name="hora_regreso" id="hora_regreso"
class="block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
required>
</div>
<div>
<label for="destino" class="block text-sm font-medium text-gray-700 mb-2">Destino</label>
<input type="text" name="destino" id="destino"
class="block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
required>
</div>
<div>
<label for="motivo" class="block text-sm font-medium text-gray-700 mb-2">Motivo</label>
<textarea name="motivo" id="motivo" rows="4"
class="block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
required></textarea>
</div>
<div class="flex justify-end space-x-4">
<a href="{{ route('profesor.solicitudes.index') }}"
class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Cancelar
</a>
<button type="submit"
class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Enviar Solicitud
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection

51
resources/views/profesor/solicitudes/index.blade.php

@ -0,0 +1,51 @@
@extends('layouts.dashboard')
@section('content')
<div class="container mx-auto px-4 py-6">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold text-gray-800">Mis Solicitudes de Vehículo</h2>
<a href="{{ route('profesor.solicitudes.create') }}" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Nueva Solicitud
</a>
</div>
@if(session('success'))
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative mb-4" role="alert">
<span class="block sm:inline">{{ session('success') }}</span>
</div>
@endif
<div class="bg-white shadow-md rounded-lg overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Fecha</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Hora Salida</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Hora Regreso</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Destino</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Estado</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@foreach($solicitudes as $solicitud)
<tr>
<td class="px-6 py-4 whitespace-nowrap">{{ $solicitud->fecha_solicitud }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ $solicitud->hora_salida }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ $solicitud->hora_regreso }}</td>
<td class="px-6 py-4">{{ $solicitud->destino }}</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full
@if($solicitud->estado === 'aprobada') bg-green-100 text-green-800
@elseif($solicitud->estado === 'rechazada') bg-red-100 text-red-800
@else bg-yellow-100 text-yellow-800
@endif">
{{ ucfirst($solicitud->estado) }}
</span>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection

20
routes/web.php

@ -10,6 +10,7 @@ use App\Http\Controllers\TiposLicenciasController;
use App\Http\Controllers\CapacidadController; use App\Http\Controllers\CapacidadController;
use App\Http\Controllers\PrestamoController; use App\Http\Controllers\PrestamoController;
use App\Http\Controllers\DespartamentoController; use App\Http\Controllers\DespartamentoController;
use App\Http\Controllers\SolicitudVehiculoController;
/* /*
@ -55,18 +56,20 @@ use App\Http\Controllers\DespartamentoController;
Route::get('/despartamento/export/excel', [DespartamentoController::class, 'exportExcel'])->name('despartamentos.excel'); Route::get('/despartamento/export/excel', [DespartamentoController::class, 'exportExcel'])->name('despartamentos.excel');
Route::get('/despartamento/export/pdf', [DespartamentoController::class, 'exportPDF'])->name('despartamentos.pdf'); Route::get('/despartamento/export/pdf', [DespartamentoController::class, 'exportPDF'])->name('despartamentos.pdf');
// Primero las rutas de exportación (más específicas) // Rutas de préstamos protegidas para administradores
Route::get('/prestamos/excel', [PrestamoController::class, 'exportExcel'])->name('prestamos.excel'); Route::middleware(['auth', 'admin'])->group(function () {
Route::get('/prestamos/pdf', [PrestamoController::class, 'exportPDF'])->name('prestamos.pdf');
Route::get('/prestamos/export/{format}', [PrestamoController::class, 'export'])->name('prestamos.export');
Route::get('/prestamos/aceptados', [PrestamoController::class, 'aceptados'])->name('prestamos.aceptados'); Route::get('/prestamos/aceptados', [PrestamoController::class, 'aceptados'])->name('prestamos.aceptados');
Route::post('/prestamos/{id}/aceptar', [PrestamoController::class, 'aceptar'])->name('prestamos.aceptar'); Route::post('/prestamos/{id}/aceptar', [PrestamoController::class, 'aceptar'])->name('prestamos.aceptar');
Route::post('/prestamos/{id}/rechazar', [PrestamoController::class, 'rechazar'])->name('prestamos.rechazar'); Route::post('/prestamos/{id}/rechazar', [PrestamoController::class, 'rechazar'])->name('prestamos.rechazar');
Route::get('/prestamos/historial', [PrestamoController::class, 'historial'])->name('prestamos.historial'); Route::get('/prestamos/historial', [PrestamoController::class, 'historial'])->name('prestamos.historial');
Route::get('/prestamos/pendientes', [PrestamoController::class, 'pendientes'])->name('prestamos.pendientes'); Route::get('/prestamos/pendientes', [PrestamoController::class, 'pendientes'])->name('prestamos.pendientes');
Route::get('/prestamos/rechazados', [PrestamoController::class, 'rechazados'])->name('prestamos.rechazados'); Route::get('/prestamos/rechazados', [PrestamoController::class, 'rechazados'])->name('prestamos.rechazados');
Route::get('/prestamos/excel', [PrestamoController::class, 'exportExcel'])->name('prestamos.excel');
Route::get('/prestamos/pdf', [PrestamoController::class, 'exportPDF'])->name('prestamos.pdf');
Route::get('/prestamos/export/{format}', [PrestamoController::class, 'export'])->name('prestamos.export');
});
// Después la ruta de recurso (más general) // Ruta general de préstamos (accesible para todos los usuarios autenticados)
Route::resource('prestamos', PrestamoController::class); Route::resource('prestamos', PrestamoController::class);
Route::get('/docentes/export/{format}', [DocentesController::class, 'export'])->name('docentes.export'); Route::get('/docentes/export/{format}', [DocentesController::class, 'export'])->name('docentes.export');
@ -94,3 +97,10 @@ use App\Http\Controllers\DespartamentoController;
////corerecion rubi ////corerecion rubi
}); });
// Rutas para profesores
Route::middleware(['auth', 'profesor'])->prefix('profesor')->name('profesor.')->group(function () {
Route::get('/solicitudes', [SolicitudVehiculoController::class, 'index'])->name('solicitudes.index');
Route::get('/solicitudes/create', [SolicitudVehiculoController::class, 'create'])->name('solicitudes.create');
Route::post('/solicitudes', [SolicitudVehiculoController::class, 'store'])->name('solicitudes.store');
});

Loading…
Cancel
Save