Browse Source

todos los roles

estan los roles y todo lo que faltaba
main
sergiomarquez778 1 month ago
parent
commit
4c5ac4521a
  1. 38
      app/Exports/UsuariosExport.php
  2. 44
      app/Exports/puestosExport.php
  3. 13
      app/Http/Controllers/AdminController.php
  4. 10
      app/Http/Controllers/DespartamentoController.php
  5. 30
      app/Http/Controllers/HomeController.php
  6. 128
      app/Http/Controllers/PuestoController.php
  7. 65
      app/Http/Controllers/TipoController.php
  8. 95
      app/Http/Controllers/usuariosController.php
  9. 5
      app/Http/Kernel.php
  10. 24
      app/Http/Middleware/AdminMiddleware.php
  11. 10
      app/Models/User.php
  12. 1
      app/Models/puesto.php
  13. 13
      app/Models/tipo.php
  14. 23
      database/factories/TipoFactory.php
  15. 34
      database/migrations/2013_02_20_022824_create_tipos_table.php
  16. 59
      database/migrations/2014_10_12_000000_create_users_table.php
  17. 12
      database/migrations/2025_05_20_032155_add_columneliminado_topuestos.php
  18. 0
      hilads
  19. 0
      hollla.txt
  20. 20
      resources/views/auth/login.blade.php
  21. 86
      resources/views/dashboard.blade.php
  22. 53
      resources/views/exports/puestos.blade.php
  23. 2
      resources/views/exports/tipos_vehiculos_pdf.blade.php
  24. 33
      resources/views/exports/usuarios-pdf.blade.php
  25. 8
      resources/views/layouts/dashboard.blade.php
  26. 142
      resources/views/puestos.blade.php
  27. 84
      resources/views/puestosCrearEditar.blade.php
  28. 19
      resources/views/usuarios.blade.php
  29. 18
      resources/views/usuariosCrearEditar.blade.php
  30. 6
      routes/web.php

38
app/Exports/UsuariosExport.php

@ -10,23 +10,37 @@ class UsuariosExport implements FromCollection, WithHeadings
{
public function collection()
{
return User::select( 'name', 'email','apellido',
'puesto',
'carrera',
'telefono',)->get();
$usuarios = User::with(['puesto', 'tipo', 'departamento'])->get();
$data = [];
$contador = 1;
foreach ($usuarios as $usuario) {
$data[] = [
'No.' => $contador++,
'Nombre' => $usuario->name,
'Correo' => $usuario->email,
'Apellido' => $usuario->apellido,
'Puesto' => $usuario->puesto->nombre ?? '',
'Tipo' => $usuario->tipo->nombre ?? '',
'Departamento' => $usuario->departamento->departamento ?? '',
'Teléfono' => $usuario->telefono,
];
}
return collect($data);
}
public function headings(): array
{
return [
'nombre',
'correo',
'apellido',
'puesto',
'carrera',
'telefono',
'Fecha de Creación',
'Última Actualización'
'No.',
'Nombre',
'Correo',
'Apellido',
'Puesto',
'Tipo',
'Departamento',
'Teléfono',
];
}
}

44
app/Exports/puestosExport.php

@ -0,0 +1,44 @@
<?php
namespace App\Exports;
use App\Models\Puesto;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class PuestosExport implements FromCollection, WithHeadings
{
protected $puestos;
// Permite pasar una colección personalizada si lo deseas
public function __construct($puestos = null)
{
$this->puestos = $puestos;
}
public function collection()
{
// Obtén los puestos
$puestos = $this->puestos ?: Puesto::where('eliminado', 0)->get(['nombre']);
// Construye la colección con número consecutivo
$data = [];
$contador = 1;
foreach ($puestos as $puesto) {
$data[] = [
'ID' => $contador++,
'Nombre del Puesto' => $puesto->nombre,
];
}
return collect($data);
}
public function headings(): array
{
return [
'ID',
'Nombre del Puesto',
];
}
}

13
app/Http/Controllers/AdminController.php

@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AdminController extends Controller
{
public function dashboard()
{
return view('admin.dashboard');
}
}

10
app/Http/Controllers/DespartamentoController.php

@ -106,11 +106,13 @@ class DespartamentoController extends Controller
*/
public function destroy($id)
{
$despartamento = despartamento::findOrFail($id); // Encuentra el departamento por ID
$despartamento->eliminado = 1; // Cambia el estado a inactivo
$despartamento->save(); // Guarda los cambios
$despartamento = despartamento::findOrFail($id);
\App\Models\User::where('departamento_id', $id)->update(['departamento_id' => null]);
$despartamento->eliminado = 1;
$despartamento->save();
return redirect()->route('despartamentos.index')->with('success', 'Departamento inactivado correctamente.');
return redirect()->route('despartamentos.index')
->with('success', 'Departamento eliminado exitosamente. Los usuarios afectados necesitan ser reasignados.');
}
public function exportExcel()

30
app/Http/Controllers/HomeController.php

@ -23,8 +23,36 @@ class HomeController extends Controller
*/
public function index()
{
$user = auth()->user();
return view('dashboard');
// Validar que el usuario tenga tipo asignado y que sea Administrador
if (!$user->tipo || $user->tipo->nombre !== 'Administrador') {
// Cerrar la sesión del usuario
auth()->logout();
// Redirigir con mensaje de error
return redirect()->route('login')->with('error', 'No tienes permisos para acceder al sistema. Solo los administradores pueden acceder en este momento.');
}
// Notificaciones si el usuario no tiene puesto o departamento asignado
$notificaciones = [];
if (is_null($user->puesto_id)) {
$notificaciones[] = 'No tienes un puesto asignado. Contacta al administrador para que te asigne uno.';
}
if (is_null($user->departamento_id)) {
$notificaciones[] = 'No tienes un departamento asignado. Contacta al administrador para que te asigne uno.';
}
// Si es administrador, mostrar el dashboard con datos reales
$adminData = [
'totalUsers' => \App\Models\User::count(),
'totalPrestamos' => \App\Models\Prestamo::count(),
'prestamosPendientes' => \App\Models\Prestamo::where('estado', 'pendiente')->count(),
'prestamosAceptados' => \App\Models\Prestamo::where('estado', 'aceptado')->count(),
];
return view('dashboard', [
'adminData' => $adminData,
'notificaciones' => $notificaciones
]);
}
}

128
app/Http/Controllers/PuestoController.php

@ -0,0 +1,128 @@
<?php
namespace App\Http\Controllers;
use App\Models\Puesto;
use Illuminate\Http\Request;
use App\Exports\PuestosExport;
use Maatwebsite\Excel\Facades\Excel;
use PDF;
class PuestoController extends Controller
{
public function index(Request $request)
{
$busqueda = $request->busqueda;
if ($busqueda) {
$puestos = Puesto::where('nombre', 'LIKE', "%{$busqueda}%")
->where('eliminado', 0)
->get();
if ($puestos->isEmpty()) {
return redirect()->route('puestos.index')
->with('error', 'No existe ningún puesto con el nombre "' . $busqueda . '". Por favor, inténtalo de nuevo.');
}
} else {
$puestos = Puesto::where('eliminado', 0)->get();
}
return view('puestos', ['puestos' => $puestos]);
}
public function create()
{
return view('puestosCrearEditar', ['puesto' => null]);
}
public function store(Request $request)
{
$validated = $request->validate([
'nombre' => ['required', 'string', 'max:255'],
], [
'nombre.required' => 'El campo nombre es obligatorio.',
'nombre.string' => 'El campo nombre debe ser una cadena de texto.',
'nombre.max' => 'El campo nombre no debe exceder 255 caracteres.',
]);
$puesto = new Puesto($validated);
$puesto->eliminado = 0;
$puesto->save();
return redirect()->route('puestos.index')
->with('success', 'Puesto creado exitosamente');
}
public function edit($id)
{
$puesto = Puesto::findOrFail($id);
return view('puestosCrearEditar', ['puesto' => $puesto]);
}
public function update(Request $request, $id)
{
$validated = $request->validate([
'nombre' => ['required', 'string', 'max:255'],
], [
'nombre.required' => 'El campo nombre es obligatorio.',
'nombre.string' => 'El campo nombre debe ser una cadena de texto.',
'nombre.max' => 'El campo nombre no debe exceder 255 caracteres.',
]);
$puesto = Puesto::findOrFail($id);
$puesto->update($validated);
return redirect()->route('puestos.index')
->with('success', 'Puesto actualizado exitosamente');
}
public function destroy($id)
{
$puesto = Puesto::findOrFail($id);
\App\Models\User::where('puesto_id', $id)->update(['puesto_id' => null]);
$puesto->eliminado = 1;
$puesto->save();
return redirect()->route('puestos.index')
->with('success', 'Puesto eliminado exitosamente. Los usuarios afectados necesitan ser reasignados.');
}
public function exportExcel()
{
return Excel::download(new PuestosExport, 'puestos.xlsx');
}
public function exportPDF()
{
$puestos = Puesto::where('eliminado', 0)->get();
$pdf = PDF::loadView('exports.puestos', ['puestos' => $puestos]);
return $pdf->download('puestos.pdf');
}
public function export($format)
{
$puestos = Puesto::where('eliminado', 0)
->orderBy('updated_at', 'desc')
->get();
switch($format) {
case 'excel':
return Excel::download(new PuestosExport($puestos), 'puestos.xlsx');
case 'pdf':
$pdf = PDF::loadView('exports.puestos', ['puestos' => $puestos]);
return $pdf->download('puestos.pdf');
default:
return redirect()->back()->with('error', 'Formato no soportado');
}
}
public function toggleStatus($id)
{
$puesto = Puesto::findOrFail($id);
$puesto->eliminado = !$puesto->eliminado;
$puesto->save();
return redirect()->route('puestos.index')
->with('success', 'Estado del puesto actualizado correctamente');
}
}

65
app/Http/Controllers/TipoController.php

@ -0,0 +1,65 @@
<?php
namespace App\Http\Controllers;
use App\Models\tipo;
use Illuminate\Http\Request;
class TipoController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(tipo $tipo)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(tipo $tipo)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, tipo $tipo)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(tipo $tipo)
{
//
}
}

95
app/Http/Controllers/usuariosController.php

@ -9,6 +9,7 @@ use Maatwebsite\Excel\Facades\Excel;
use PDF; // Asegúrate de incluir la clase PDF
use App\Models\Puesto;
use App\Models\Despartamento;
use App\Models\Tipo;
class usuariosController extends Controller
{
@ -40,9 +41,10 @@ class usuariosController extends Controller
*/
public function create()
{
$tipos = Tipo::all();
$despartamentos = Despartamento::all();
$puestos = Puesto::all();
return view('usuariosCrearEditar', ['usuario' => null, 'puestos' => $puestos, 'despartamentos'=> $despartamentos]);
return view('usuariosCrearEditar', ['usuario' => null, 'puestos' => $puestos, 'despartamentos'=> $despartamentos, 'tipos' => $tipos]);
}
/**
@ -50,24 +52,47 @@ class usuariosController extends Controller
*/
public function store(Request $request)
{
// Validación de datos
// Validación de datos en español
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'apellido' => 'required|string|max:255',
'puesto_id' => 'required|exists:puestos,id',
'departamento_id' => 'required|exists:despartamentos,id',
'telefono' => 'required|string|max:255',
'password' => 'required|string|min:8|confirmed',
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'apellido' => ['required', 'string', 'max:255'],
'tipos_id' => ['required', 'exists:tipos,id'],
'puesto_id' => ['required', 'exists:puestos,id'],
'departamento_id' => ['required', 'exists:despartamentos,id'],
'telefono' => ['required', 'string', 'max:255'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
], [
'name.required' => 'El campo nombre es obligatorio.',
'email.required' => 'El campo email es obligatorio.',
'email.unique' => 'El email ya está registrado.',
'name.string' => 'El campo nombre debe ser una cadena de texto.',
'name.max' => 'El campo nombre no debe exceder 255 caracteres.',
'email.required' => 'El campo correo electrónico es obligatorio.',
'email.string' => 'El campo correo electrónico debe ser una cadena de texto.',
'email.email' => 'El campo correo electrónico debe ser una dirección de correo válida.',
'email.max' => 'El campo correo electrónico no debe exceder 255 caracteres.',
'email.unique' => 'El correo electrónico ya está registrado.',
'apellido.required' => 'El campo apellido es obligatorio.',
'apellido.string' => 'El campo apellido debe ser una cadena de texto.',
'apellido.max' => 'El campo apellido no debe exceder 255 caracteres.',
'tipos_id.required' => 'El campo tipo es obligatorio.',
'tipos_id.exists' => 'El tipo seleccionado no es válido.',
'puesto_id.required' => 'El campo puesto es obligatorio.',
'puesto_id.exists' => 'El puesto seleccionado no es válido.',
'departamento_id.required' => 'El campo departamento es obligatorio.',
'departamento_id.exists' => 'El departamento seleccionado no es válido.',
'telefono.required' => 'El campo teléfono es obligatorio.',
'telefono.string' => 'El campo teléfono debe ser una cadena de texto.',
'telefono.max' => 'El campo teléfono no debe exceder 255 caracteres.',
'password.required' => 'El campo contraseña es obligatorio.',
'password.string' => 'El campo contraseña debe ser una cadena de texto.',
'password.min' => 'La contraseña debe tener al menos 8 caracteres.',
'password.confirmed' => 'Las contraseñas no coinciden.',
]);
@ -76,6 +101,7 @@ class usuariosController extends Controller
$usuario->name = $request->name;
$usuario->email = $request->email;
$usuario->apellido = $request->apellido;
$usuario->tipos_id = $request->tipos_id;
$usuario->puesto_id = $request->puesto_id;
$usuario->departamento_id = $request->departamento_id;
$usuario->telefono = $request->telefono;
@ -101,7 +127,8 @@ class usuariosController extends Controller
$user = User::findOrFail($id);
$puestos = Puesto::all();
$despartamentos = Despartamento::all();
return view('usuariosCrearEditar',['usuario' => $user, 'puestos' => $puestos,'despartamentos'=> $despartamentos]); // Asegúrate de que la clave sea 'usuario'
$tipos = Tipo::all();
return view('usuariosCrearEditar',['usuario' => $user, 'puestos' => $puestos,'despartamentos'=> $despartamentos, 'tipos' => $tipos]); // Asegúrate de que la clave sea 'usuario'
}
/**
@ -109,24 +136,47 @@ class usuariosController extends Controller
*/
public function update(Request $request, $id)
{
// Validación de datos
// Validación de datos (reglas y mensajes personalizados en español)
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'apellido' => 'required|string|max:255',
'puesto_id' => 'required|exists:puestos,id',
'departamento_id' => 'required|exists:despartamentos,id',
'telefono' => 'required|string|max:255',
'password' => 'required|string|min:8|confirmed',
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email,'.$id],
'apellido' => ['required', 'string', 'max:255'],
'tipos_id' => ['required', 'exists:tipos,id'],
'puesto_id' => ['required', 'exists:puestos,id'],
'departamento_id' => ['required', 'exists:despartamentos,id'],
'telefono' => ['required', 'string', 'max:255'],
'password' => ['nullable', 'string', 'min:8', 'confirmed'],
], [
'name.required' => 'El campo nombre es obligatorio.',
'email.required' => 'El campo email es obligatorio.',
'email.unique' => 'El email ya está registrado.',
'name.string' => 'El campo nombre debe ser una cadena de texto.',
'name.max' => 'El campo nombre no debe exceder 255 caracteres.',
'email.required' => 'El campo correo electrónico es obligatorio.',
'email.string' => 'El campo correo electrónico debe ser una cadena de texto.',
'email.email' => 'El campo correo electrónico debe ser una dirección válida.',
'email.max' => 'El campo correo electrónico no debe exceder 255 caracteres.',
'email.unique' => 'El correo electrónico ya está registrado.',
'apellido.required' => 'El campo apellido es obligatorio.',
'apellido.string' => 'El campo apellido debe ser una cadena de texto.',
'apellido.max' => 'El campo apellido no debe exceder 255 caracteres.',
'tipos_id.required' => 'El campo tipo es obligatorio.',
'tipos_id.exists' => 'El tipo seleccionado no es válido.',
'puesto_id.required' => 'El campo puesto es obligatorio.',
'puesto_id.exists' => 'El puesto seleccionado no es válido.',
'departamento_id.required' => 'El campo departamento es obligatorio.',
'departamento_id.exists' => 'El departamento seleccionado no es válido.',
'telefono.required' => 'El campo teléfono es obligatorio.',
'telefono.string' => 'El campo teléfono debe ser una cadena de texto.',
'telefono.max' => 'El campo teléfono no debe exceder 255 caracteres.',
'password.required' => 'El campo contraseña es obligatorio.',
'password.string' => 'El campo contraseña debe ser una cadena de texto.',
'password.min' => 'La contraseña debe tener al menos 8 caracteres.',
'password.confirmed' => 'Las contraseñas no coinciden.',
]);
@ -135,6 +185,7 @@ class usuariosController extends Controller
$usuario->name = $request->name;
$usuario->email = $request->email;
$usuario->apellido = $request->apellido;
$usuario->tipos_id = $request->tipos_id;
$usuario->puesto_id = $request->puesto_id;
$usuario->departamento_id = $request->departamento_id;
$usuario->telefono = $request->telefono;

5
app/Http/Kernel.php

@ -64,4 +64,9 @@ class Kernel extends HttpKernel
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
protected $routeMiddleware = [
// ... otros middlewares
'admin' => \App\Http\Middleware\AdminMiddleware::class,
];
}

24
app/Http/Middleware/AdminMiddleware.php

@ -0,0 +1,24 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (!auth()->check() || auth()->user()->tipo->nombre !== 'Administrador') {
return redirect('/')->with('error', 'No tienes permisos para acceder a esta página.');
}
return $next($request);
}
}

10
app/Models/User.php

@ -23,6 +23,7 @@ class User extends Authenticatable
'name',
'email',
'apellido',
'tipos_id',
'puesto_id',
'departamento_id',
'telefono',
@ -49,10 +50,7 @@ class User extends Authenticatable
'email_verified_at' => 'datetime',
];
public function puesto():HasOne{
return $this->hasOne(Puesto::class, 'id','puesto_id');
}
public function despartamento():HasOne{
return $this->hasOne(Despartamento::class, 'id','departamento_id');
}
public function puesto() { return $this->belongsTo(\App\Models\Puesto::class, 'puesto_id'); }
public function tipo() { return $this->belongsTo(\App\Models\Tipo::class, 'tipos_id'); }
public function departamento() { return $this->belongsTo(\App\Models\Despartamento::class, 'departamento_id'); }
}

1
app/Models/puesto.php

@ -8,4 +8,5 @@ use Illuminate\Database\Eloquent\Model;
class puesto extends Model
{
use HasFactory;
protected $fillable = ['nombre', 'eliminado'];
}

13
app/Models/tipo.php

@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class tipo extends Model
{
use HasFactory;
protected $table = 'tipos';
protected $fillable = ['nombre'];
}

23
database/factories/TipoFactory.php

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\tipo>
*/
class TipoFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
//
];
}
}

34
database/migrations/2013_02_20_022824_create_tipos_table.php

@ -0,0 +1,34 @@
<?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::create('tipos', function (Blueprint $table) {
$table->id();
$table->string('nombre');
$table->timestamps();
});
DB::table('tipos')->insert(['nombre'=> 'Administrador']);
DB::table('tipos')->insert(['nombre'=> 'Usuario']);
DB::table('tipos')->insert(['nombre'=> 'Jefe de Departamento']);
DB::table('tipos')->insert(['nombre'=> 'Servicios Generales']);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tipos');
}
};

59
database/migrations/2014_10_12_000000_create_users_table.php

@ -18,7 +18,7 @@ return new class extends Migration
$table->timestamp('email_verified_at')->nullable();
$table->string('apellido')->nullable();
$table->unsignedBigInteger('puesto_id')->nullable();
$table->unsignedBigInteger('tipos_id')->nullable();
$table->unsignedBigInteger('departamento_id')->nullable();
$table->string('telefono')->nullable();
@ -26,15 +26,64 @@ return new class extends Migration
$table->rememberToken();
$table->timestamps();
$table->foreign('puesto_id')->references('id')->on('puestos');
$table->foreign('tipos_id')->references('id')->on('tipos');
$table->foreign('departamento_id')->references('id')->on('despartamentos');
});
DB::table('users')->insert([
'name' => 'silva',
'email' => 'silva@silva.com',
'apellido' => 'anael',
'tipos_id' => 2, // Asegúrate que este ID corresponde a "Usuario" en la tabla tipos
'puesto_id' => 2, // Asegúrate que este ID corresponde a "docente" en la tabla puestos
'departamento_id' => 2, // Asegúrate que este ID corresponde a "wfaf" en la tabla despartamentos
'telefono' => '33652147821',
'password' => bcrypt('12345678'),
'email_verified_at' => now(),
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('users')->insert([
'name'=> 'Administrador',
'email'=> 'admin@admin.com',
'password'=> bcrypt('12345678')
'name' => 'monse',
'email' => 'monse@monse.com',
'apellido' => 'martinez',
'tipos_id' => 1,
'puesto_id' => 1,
'departamento_id' => 3,
'telefono' => null,
'password' => bcrypt('12345678'),
'email_verified_at' => now(),
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('users')->insert([
'name' => 'usuario_tipo3',
'email' => 'tipo3@ejemplo.com',
'apellido' => 'apellido3',
'tipos_id' => 3, // Tercer tipo restante
'puesto_id' => 1, // Puedes ajustar el puesto según corresponda
'departamento_id' => 1, // Puedes ajustar el departamento según corresponda
'telefono' => '3333333333',
'password' => bcrypt('12345678'),
'email_verified_at' => now(),
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('users')->insert([
'name' => 'usuario_tipo4',
'email' => 'tipo4@ejemplo.com',
'apellido' => 'apellido4',
'tipos_id' => 4, // Cuarto tipo restante
'puesto_id' => 1, // Puedes ajustar el puesto según corresponda
'departamento_id' => 1, // Puedes ajustar el departamento según corresponda
'telefono' => '4444444444',
'password' => bcrypt('12345678'),
'email_verified_at' => now(),
'created_at' => now(),
'updated_at' => now(),
]);
}
/**

12
database/migrations/2025_05_08_175205_add_estado_to_prestamos_table.php → database/migrations/2025_05_20_032155_add_columneliminado_topuestos.php

@ -11,9 +11,9 @@ return new class extends Migration
*/
public function up(): void
{
Schema::table('prestamos', function (Blueprint $table) {
$table->enum('estado', ['pendiente', 'aceptado', 'rechazado'])->default('pendiente')->after('chofer');
});
Schema::table('puestos', function (Blueprint $table) {
$table->boolean('eliminado')->default(false);
});
}
/**
@ -21,8 +21,8 @@ return new class extends Migration
*/
public function down(): void
{
Schema::table('prestamos', function (Blueprint $table) {
$table->dropColumn('estado');
});
Schema::table('puestos', function (Blueprint $table) {
$table->dropColumn('eliminado');
});
}
};

0
hilads

0
hollla.txt

20
resources/views/auth/login.blade.php

@ -29,6 +29,14 @@
</div>
@endif
@if(session('error'))
<div class="mb-4 bg-red-50 border-l-4 border-red-500 p-4">
<div class="text-red-700">
{{ session('error') }}
</div>
</div>
@endif
<form method="POST" action="{{ route('login') }}" class="space-y-6">
@csrf
@ -44,6 +52,12 @@
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
value="{{ old('email') }}"
placeholder="tu@email.com">
@error('email')
<span class="text-red-500 text-sm">
{{ $message }}
</span>
@enderror
</div>
</div>
@ -58,6 +72,12 @@
<input id="password" name="password" type="password" required
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
placeholder="••••••••">
@error('password')
<span class="text-red-500 text-sm">
{{ $message }}
</span>
@enderror
</div>
</div>

86
resources/views/dashboard.blade.php

@ -1,6 +1,15 @@
@extends('layouts.dashboard')
@section('content')
@if(!empty($notificaciones))
<div class="bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4 mb-4">
<ul class="list-disc pl-5">
@foreach($notificaciones as $nota)
<li>{{ $nota }}</li>
@endforeach
</ul>
</div>
@endif
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- Tarjeta de Préstamos Activos -->
<div class="bg-white rounded-lg shadow p-6">
@ -10,8 +19,8 @@
<i class="fas fa-book-reader"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">25</p>
<p class="text-sm text-gray-500 mt-2">↑ 12% desde el mes pasado</p>
<p class="text-3xl font-bold text-gray-900">{{ $adminData['prestamosAceptados'] }}</p>
<p class="text-sm text-gray-500 mt-2">Préstamos actualmente activos</p>
</div>
<!-- Tarjeta de Usuarios Registrados -->
@ -22,32 +31,32 @@
<i class="fas fa-users"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">150</p>
<p class="text-sm text-gray-500 mt-2">↑ 5% desde el mes pasado</p>
<p class="text-3xl font-bold text-gray-900">{{ $adminData['totalUsers'] }}</p>
<p class="text-sm text-gray-500 mt-2">Total de usuarios en el sistema</p>
</div>
<!-- Tarjeta de Préstamos Vencidos -->
<!-- Tarjeta de Préstamos Pendientes -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Préstamos Vencidos</h3>
<h3 class="text-lg font-semibold text-gray-700">Préstamos Pendientes</h3>
<span class="text-red-600 bg-red-100 rounded-full p-2">
<i class="fas fa-exclamation-circle"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">3</p>
<p class="text-sm text-gray-500 mt-2">↓ 2% desde el mes pasado</p>
<p class="text-3xl font-bold text-gray-900">{{ $adminData['prestamosPendientes'] }}</p>
<p class="text-sm text-gray-500 mt-2">Préstamos por revisar</p>
</div>
<!-- Tarjeta de Préstamos del Mes -->
<!-- Tarjeta de Total Préstamos -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Préstamos del Mes</h3>
<h3 class="text-lg font-semibold text-gray-700">Total Préstamos</h3>
<span class="text-purple-600 bg-purple-100 rounded-full p-2">
<i class="fas fa-chart-line"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">42</p>
<p class="text-sm text-gray-500 mt-2">↑ 8% desde el mes pasado</p>
<p class="text-3xl font-bold text-gray-900">{{ $adminData['totalPrestamos'] }}</p>
<p class="text-sm text-gray-500 mt-2">Total de préstamos registrados</p>
</div>
</div>
@ -66,34 +75,37 @@
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10">
<img class="h-10 w-10 rounded-full" src="https://ui-avatars.com/api/?name=Juan+Pérez" alt="">
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">Juan Pérez</div>
<div class="text-sm text-gray-500">juan@example.com</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">Solicitó préstamo</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">Hace 2 horas</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
Aprobado
</span>
</td>
</tr>
<!-- Más filas de actividad aquí -->
<!-- Aquí irían los registros de actividad -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Sección de Administración -->
<div class="mt-8 bg-white rounded-lg shadow">
<div class="p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Acciones de Administración</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<a href="{{ route('usuarios') }}" class="p-4 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors">
<div class="flex items-center space-x-3">
<i class="fas fa-users text-blue-600 text-xl"></i>
<span class="text-blue-800 font-medium">Gestión de Usuarios</span>
</div>
</a>
<a href="{{ route('marca.index') }}" class="p-4 bg-green-50 rounded-lg hover:bg-green-100 transition-colors">
<div class="flex items-center space-x-3">
<i class="fas fa-trademark text-green-600 text-xl"></i>
<span class="text-green-800 font-medium">Gestión de Marcas</span>
</div>
</a>
<a href="{{ route('puestos.index') }}" class="p-4 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors">
<div class="flex items-center space-x-3">
<i class="fas fa-briefcase text-purple-600 text-xl"></i>
<span class="text-purple-800 font-medium">Gestión de Puestos</span>
</div>
</a>
</div>
</div>
</div>
@endsection

53
resources/views/exports/puestos.blade.php

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<title>Reporte de Puestos</title>
<style>
body {
font-family: Arial, sans-serif;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
.header {
text-align: center;
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="header">
<h1>Reporte de Puestos</h1>
<p>Fecha de generación: {{ date('d/m/Y H:i:s') }}</p>
</div>
<table>
<thead>
<tr>
<th>#</th>
<th>Nombre del Puesto</th>
</tr>
</thead>
<tbody>
@foreach($puestos as $index => $puesto)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ $puesto->nombre }}</td>
</tr>
@endforeach
</tbody>
</table>
</body>
</html>

2
resources/views/exports/tipos_vehiculos_pdf.blade.php

@ -72,4 +72,4 @@
</tbody>
</table>
</body>
</html>
</html>

33
resources/views/exports/usuarios-pdf.blade.php

@ -4,45 +4,60 @@
<head>
<title>Lista de Usuarios</title>
<style>
/* Estilos opcionales para el PDF */
body {
font-family: Arial, sans-serif;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
border: 1px solid black;
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
.header {
text-align: center;
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="header">
<h1>Lista de Usuarios</h1>
<p>Fecha de generación: {{ date('d/m/Y H:i:s') }}</p>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>No.</th>
<th>Nombre</th>
<th>Email</th>
<th>Apellido</th>
<th>Puesto</th>
<th>Carrera</th>
<th>Tipo</th>
<th>Departamento</th>
<th>Teléfono</th>
</tr>
</thead>
<tbody>
@foreach($usuarios as $usuario)
@foreach($usuarios as $index => $usuario)
<tr>
<td>{{ $usuario->id }}</td>
<td>{{ $index + 1 }}</td>
<td>{{ $usuario->name }}</td>
<td>{{ $usuario->email }}</td>
<td>{{ $usuario->apellido }}</td>
<td>{{ $usuario->puesto }}</td>
<td>{{ $usuario->carrera }}</td>
<td>{{ $usuario->puesto->nombre ?? '' }}</td>
<td>{{ $usuario->tipo->nombre ?? '' }}</td>
<td>{{ $usuario->departamento->departamento ?? '' }}</td>
<td>{{ $usuario->telefono }}</td>
</tr>
@endforeach
</tbody>
</table>
</body>
</html>
</html>

8
resources/views/layouts/dashboard.blade.php

@ -144,6 +144,13 @@
<span class="font-light">Marca</span>
</a>
</li>
<!-- puesto -->
<li>
<a href="{{ route('puestos.index') }}" class="nav-item-hover flex items-center space-x-3 px-4 py-3 rounded-lg hover:bg-white/10 backdrop-blur-sm {{ request()->is('puestos*') ? 'bg-white/20' : '' }}">
<i class="fas fa-briefcase text-white/80"></i>
<span class="font-light">Puestos</span>
</a>
</li>
<!-- departamento -->
<li>
@ -153,6 +160,7 @@
</a>
</li>
<!-- Tipos -->
<li>
<a href="{{ route('vehiculos.index') }}" class="nav-item-hover flex items-center space-x-3 px-4 py-3 rounded-lg hover:bg-white/10 backdrop-blur-sm {{ request()->is('vehiculos*') ? 'bg-white/20' : '' }}">

142
resources/views/puestos.blade.php

@ -0,0 +1,142 @@
@extends('layouts.dashboard')
@section('content')
<div class="container mx-auto px-4 py-6">
<!-- Mensajes de éxito y error -->
@if(session('success'))
<div id="success-message" 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
@if(session('error'))
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
<span class="block sm:inline">{{ session('error') }}</span>
</div>
@endif
<div class="bg-white rounded-lg shadow-lg">
<!-- Encabezado con título y botones de acción -->
<div class="p-4 border-b border-gray-200 flex justify-between items-center">
<h2 class="text-2xl font-bold">Gestión de Puestos</h2>
<div class="flex items-center space-x-6">
<!-- Íconos de agregar -->
<div class="flex space-x-4">
<a href="{{ route('puestos.excel') }}"
class="text-green-600 hover:text-green-700 transition-colors duration-200"
title="Exportar a Excel">
<i class="fas fa-file-excel text-xl"></i>
</a>
<a href="{{ route('puestos.pdf') }}"
class="text-red-600 hover:text-red-700 transition-colors duration-200"
title="Exportar a PDF">
<i class="fas fa-file-pdf text-xl"></i>
</a>
<!-- Agregar nuevo puesto -->
<a href="{{ route('puestos.create') }}"
class="text-blue-500 hover:text-blue-600 transition-colors duration-200"
title="Agregar nuevo puesto">
<i class="fas fa-plus text-xl"></i>
</a>
</div>
</div>
</div>
<!-- Barra de búsqueda -->
<div class="p-4 border-b border-gray-200 bg-gray-50">
<form action="{{ route('puestos.index') }}" method="GET" class="flex gap-2">
<div class="relative w-full sm:w-64">
<input type="text"
name="busqueda"
placeholder="Buscar puesto..."
value="{{ request('busqueda') }}"
class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<div class="absolute left-3 top-2.5 text-gray-400">
<i class="fas fa-search"></i>
</div>
</div>
<button type="submit" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600">
Buscar
</button>
@if(request('busqueda'))
<a href="{{ route('puestos.index') }}" class="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600">
Limpiar
</a>
@endif
</form>
</div>
<!-- Tabla de puestos -->
<div class="overflow-x-auto">
<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">Número</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Puesto</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Acciones</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@foreach($puestos as $index => $puesto)
<tr class="hover:bg-gray-50">
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ $index + 1 }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<i class="fas fa-briefcase text-blue-500 mr-2"></i>
{{ $puesto->nombre }}
</td>
<td class="flex space-x-2 px-6 py-4 whitespace-nowrap text-sm">
<a href="{{ route('puestos.edit', $puesto->id) }}"
class="text-yellow-600 hover:text-yellow-700 transition-colors duration-200"
title="Editar puesto">
<i class="fas fa-edit"></i>
</a>
<form action="{{ route('puestos.destroy', $puesto->id) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<a href="#" onclick="event.preventDefault(); confirmarEliminacion(this);"
class="text-red-600 hover:text-red-700 transition-colors duration-200"
title="Eliminar puesto">
<i class="fas fa-trash"></i>
</a>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
<script>
// Desaparecer el mensaje después de 3 segundos
setTimeout(function() {
var message = document.getElementById('success-message');
if (message) {
message.style.transition = 'opacity 0.5s ease';
message.style.opacity = '0';
setTimeout(function() {
message.remove();
}, 500);
}
}, 3000);
function confirmarEliminacion(button) {
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) {
button.closest('form').submit();
}
});
}
</script>
@endsection

84
resources/views/puestosCrearEditar.blade.php

@ -0,0 +1,84 @@
@extends('layouts.dashboard')
@section('content')
<div class="container mx-auto px-4 py-6">
<div class="max-w-lg mx-auto">
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
<div class="p-6">
<!-- Encabezado del formulario -->
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-gray-800">
{{ isset($puesto) ? 'Editar Puesto' : 'Nuevo Puesto' }}
</h2>
<div class="h-10 w-10 bg-blue-100 rounded-full flex items-center justify-center">
<i class="fas fa-briefcase text-blue-600"></i>
</div>
</div>
<!-- Mensajes de error -->
@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">
<i class="fas fa-exclamation-circle text-red-500 mr-3"></i>
<div class="text-red-700">
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<!-- Formulario -->
<form id="puestoForm"
action="{{ isset($puesto) ? route('puestos.update', $puesto->id) : route('puestos.store') }}"
method="POST">
@csrf
@if(isset($puesto))
@method('PUT')
@endif
<div class="space-y-6">
<!-- Campo Nombre -->
<div>
<label for="nombre" class="block text-sm font-medium text-gray-700 mb-2">
Nombre del Puesto
</label>
<div class="relative rounded-md shadow-sm">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-tag text-gray-400"></i>
</div>
<input type="text"
name="nombre"
id="nombre"
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
required
placeholder="Ingresa el nombre del puesto"
value="{{ isset($puesto) ? $puesto->nombre : old('nombre') }}">
</div>
@error('nombre')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Botones de acción -->
<div class="flex justify-end space-x-2 pt-4 border-t border-gray-200">
<a href="{{ route('puestos.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">
{{ isset($puesto) ? 'Actualizar' : 'Guardar' }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection

19
resources/views/usuarios.blade.php

@ -83,6 +83,7 @@
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Nombre </th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Email </th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Apellido </th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tipo </th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Puesto </th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Departamento </th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Teléfono </th>
@ -97,7 +98,7 @@
</tr>
@else
@foreach($usuarios as $index => $usuario)
<tr class="hover:bg-gray-50">
<tr class="hover:bg-gray-50 @if(is_null($usuario->puesto_id) || is_null($usuario->departamento_id)) bg-red-100 @endif">
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ $index + 1 }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<i class="fas fa-user text-blue-500 mr-2"></i>
@ -109,16 +110,30 @@
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<i class="fas fa-user-tag text-green-500"></i> {{ $usuario->apellido }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<div class="flex items-center">
<i class="fas fa-briefcase text-gray-400 mr-2"></i>
{{ $usuario->tipo->nombre ?? 'Sin tipo asignado' }}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
@if(is_null($usuario->puesto_id) || is_null($usuario->departamento_id))
<i class="fas fa-exclamation-triangle text-red-500 mr-2" title="Usuario sin puesto o departamento asignado"></i>
@endif
<div class="flex items-center">
<i class="fas fa-briefcase text-gray-400 mr-2"></i>
{{ $usuario->puesto->nombre ?? 'Sin puesto asignado' }}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
@if(is_null($usuario->puesto_id) || is_null($usuario->departamento_id))
<i class="fas fa-exclamation-triangle text-red-500 mr-2" title="Usuario sin puesto o departamento asignado"></i>
@endif
<div class="flex items-center">
<i class="fas fa-building text-gray-400 mr-2"></i>
{{ $usuario->despartamento->departamento ?? 'Sin departamento asignado' }}
{{ $usuario->departamento->departamento ?? 'Sin departamento asignado' }}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">

18
resources/views/usuariosCrearEditar.blade.php

@ -70,7 +70,23 @@
required value="{{ isset($usuario) ? $usuario->apellido : old('apellido') }}">
</div>
</div>
<div>
<label for="tipos_id" class="block text-sm font-medium text-gray-700 mb-2">Tipo</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-id-badge text-gray-400"></i>
</div>
<select name="tipos_id" id="tipos_id" class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md" required>
<option value="">Selecciona un tipo</option>
@foreach($tipos as $tipo)
<option value="{{ $tipo->id }}"
{{ (isset($usuario) && $usuario->tipos_id == $tipo->id) ? 'selected' : '' }}>
{{ $tipo->nombre }}
</option>
@endforeach
</select>
</div>
</div>
<div>
<label for="puestos_id" class="block text-sm font-medium text-gray-700 mb-2">Puesto</label>
<div class="relative">

6
routes/web.php

@ -10,6 +10,7 @@ use App\Http\Controllers\TiposLicenciasController;
use App\Http\Controllers\CapacidadController;
use App\Http\Controllers\PrestamoController;
use App\Http\Controllers\DespartamentoController;
use App\Http\Controllers\PuestoController;
/*
@ -31,6 +32,7 @@ use App\Http\Controllers\DespartamentoController;
Route::resource('marca', MarcaController::class);
Route::resource('docentes', DocentesController::class);
Route::resource('puestos', PuestoController::class);
Route::resource('despartamentos', DespartamentoController::class);
@ -55,6 +57,9 @@ use App\Http\Controllers\DespartamentoController;
Route::get('/despartamento/export/excel', [DespartamentoController::class, 'exportExcel'])->name('despartamentos.excel');
Route::get('/despartamento/export/pdf', [DespartamentoController::class, 'exportPDF'])->name('despartamentos.pdf');
Route::get('/puestos/export/excel', [PuestoController::class, 'exportExcel'])->name('puestos.excel');
Route::get('/puestos/export/pdf', [PuestoController::class, 'exportPDF'])->name('puestos.pdf');
// Primero las rutas de exportación (más específicas)
Route::get('/prestamos/excel', [PrestamoController::class, 'exportExcel'])->name('prestamos.excel');
Route::get('/prestamos/pdf', [PrestamoController::class, 'exportPDF'])->name('prestamos.pdf');
@ -84,6 +89,7 @@ use App\Http\Controllers\DespartamentoController;
Route::get('/usuarios/nuevo', [usuariosController::class, 'create'])->name('usuarios.create');
Route::post('/usuarios/store', [usuariosController::class,'store'])->name('usuarios.store');
Route::get('/usuarios/edit/{id}', [usuariosController::class, 'edit'])->name('usuarios.edit');
Route::put('/usuarios/{id}', [usuariosController::class, 'update'])->name('usuarios.update');
Route::delete('/usuarios/destroy/{id}', [usuariosController::class, 'destroy'])->name('usuarios.destroy');

Loading…
Cancel
Save