Browse Source

usuarios

complementos lala tabla de usuarios modifiacion ene l web etc etc
main
sergiomarquez778 6 days ago
parent
commit
f17ee26d14
  1. 3
      app/Exports/MarcasExport.php
  2. 24
      app/Exports/UsuariosExport.php
  3. 99
      app/Http/Controllers/usuariosController.php
  4. 4
      app/Models/User.php
  5. 2
      composer.json
  6. 2
      config/app.php
  7. 4
      database/migrations/2014_10_12_000000_create_users_table.php
  8. 28
      database/migrations/2025_03_27_135638_add_columneliminar_to_users.php
  9. 48
      resources/views/exports/usuarios-pdf.blade.php
  10. 145
      resources/views/usuarios.blade.php
  11. 87
      resources/views/usuariosCrearEditar.blade.php
  12. 12
      routes/web.php

3
app/Exports/MarcasExport.php

@ -7,6 +7,7 @@ use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class MarcasExport implements FromCollection, WithHeadings
{
/**
* Método que devuelve la colección de datos a exportar.
@ -32,4 +33,4 @@ class MarcasExport implements FromCollection, WithHeadings
'Marca', // Encabezado para la columna Marca
];
}
}
}

24
app/Exports/UsuariosExport.php

@ -0,0 +1,24 @@
<?php
namespace App\Exports;
use App\Models\User;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class UsuariosExport implements FromCollection, WithHeadings
{
public function collection()
{
return User::select('id', 'name', 'email')->get();
}
public function headings(): array
{
return [
'ID',
'Nombre',
'Email'
];
}
}

99
app/Http/Controllers/usuariosController.php

@ -4,6 +4,9 @@ namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use App\Exports\UsuariosExport;
use Maatwebsite\Excel\Facades\Excel;
use PDF; // Asegúrate de incluir la clase PDF
class usuariosController extends Controller
{
@ -12,9 +15,22 @@ class usuariosController extends Controller
*/
public function index(Request $request)
{
$usuarios = User::all();
$busqueda = $request->busqueda;
return view('usuarios', compact('usuarios'));
if ($busqueda) {
// Busca en la columna 'name' de la tabla 'users'
$usuarios = User::where('name', 'LIKE', "%{$busqueda}%")->where('eliminado', 0)->get();
if ($usuarios->isEmpty()) {
return redirect()->route('usuarios')
->with('error', 'No existe ningún usuario con el nombre "' . $busqueda . '". Por favor, inténtalo de nuevo.');
}
} else {
// Si no hay búsqueda, mostrar todos los usuarios
$usuarios = User::where('eliminado', 0)->get();
}
return view('usuarios', ['usuarios' => $usuarios]);
}
/**
@ -22,25 +38,36 @@ class usuariosController extends Controller
*/
public function create()
{
return view('usuarios.create');
return view('usuariosCrearEditar'); // Vista para crear usuario
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
// Validación de datos
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'apellido' => 'required|string|max:255',
'puesto' => 'required|string|max:255',
'carrera' => 'required|string|max:255',
'telefono' => 'required|string|max:255',
'password' => 'required|string|min:8|confirmed',
]);
User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
// Crear nuevo usuario
$usuario = new User();
$usuario->name = $request->name;
$usuario->email = $request->email;
$usuario->apellido = $request->apellido;
$usuario->puesto = $request->puesto;
$usuario->carrera = $request->carrera;
$usuario->telefono = $request->telefono;
$usuario->password = bcrypt($request->password);
$usuario->save();
return redirect()->route('usuarios')->with('success', 'Usuario creado exitosamente.');
}
@ -50,7 +77,7 @@ class usuariosController extends Controller
*/
public function show(string $id)
{
//
// Implementar si es necesario
}
/**
@ -58,25 +85,73 @@ class usuariosController extends Controller
*/
public function edit($id)
{
$usuario = User::findOrFail($id);
return view('usuariosCrearEditar', compact('usuario')); // Vista para editar usuario
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, $id)
{
// Validación de datos
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255',
'apellido' => 'required|string|max:255',
'puesto' => 'required|string|max:255',
'carrera' => 'required|string|max:255',
'telefono' => 'required|string|max:255',
'password' => 'nullable|string|min:8|confirmed',
]);
// Actualizar usuario
$usuario = User::findOrFail($id);
$usuario->name = $request->name;
$usuario->email = $request->email;
$usuario->apellido = $request->apellido;
$usuario->puesto = $request->puesto;
$usuario->carrera = $request->carrera;
$usuario->telefono = $request->telefono;
if ($request->filled('password')) {
$usuario->password = bcrypt($request->password);
}
$usuario->save();
return redirect()->route('usuarios')->with('success', 'Usuario actualizado exitosamente.');
}
/**
* Remove the specified resource from storage.
*/
public function destroy($id)
public function destroy($id)
{
// Buscar el usuario por ID
$usuario = User::findOrFail($id);
$usuario->delete();
// Cambiar el estado de eliminado a 1
$usuario->eliminado = 1; // Asumiendo que 'eliminado' es el campo que indica el estado
$usuario->save(); // Guardar los cambios
// Redirigir a la lista de usuarios con un mensaje de éxito
return redirect()->route('usuarios')->with('success', 'Usuario eliminado exitosamente.');
}
public function exportExcel()
{
return Excel::download(new UsuariosExport, 'usuarios.xlsx');
}
public function exportPDF()
{
$usuarios = User::where('eliminado', 0)->get();
$pdf = PDF::loadView('exports.usuarios-pdf', ['usuarios' => $usuarios]);
return $pdf->download('usuarios.pdf');
}
}

4
app/Models/User.php

@ -20,6 +20,10 @@ class User extends Authenticatable
protected $fillable = [
'name',
'email',
'apellido',
'puesto',
'carrera',
'telefono',
'password',
];

2
composer.json

@ -12,7 +12,7 @@
"laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8",
"laravel/ui": "^4.6",
"maatwebsite/excel": "^3.1",
"maatwebsite/excel": "^1.1",
"phpoffice/phpspreadsheet": "^4.1"
},
"require-dev": {

2
config/app.php

@ -2,6 +2,7 @@
use Illuminate\Support\Facades\Facade;
return [
/*
@ -195,6 +196,7 @@ return [
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
/*

4
database/migrations/2014_10_12_000000_create_users_table.php

@ -16,6 +16,10 @@ return new class extends Migration
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('apellido')->nullable();
$table->string('puesto')->nullable();
$table->string('carrera')->nullable();
$table->string('telefono')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();

28
database/migrations/2025_03_27_135638_add_columneliminar_to_users.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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('eliminado')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('eliminado');
});
}
};

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

@ -0,0 +1,48 @@
<!-- resources/views/exports/usuarios-pdf.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Lista de Usuarios</title>
<style>
/* Estilos opcionales para el PDF */
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 8px;
text-align: left;
}
</style>
</head>
<body>
<h1>Lista de Usuarios</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Email</th>
<th>Apellido</th>
<th>Puesto</th>
<th>Carrera</th>
<th>Teléfono</th>
</tr>
</thead>
<tbody>
@foreach($usuarios as $usuario)
<tr>
<td>{{ $usuario->id }}</td>
<td>{{ $usuario->name }}</td>
<td>{{ $usuario->email }}</td>
<td>{{ $usuario->apellido }}</td>
<td>{{ $usuario->puesto }}</td>
<td>{{ $usuario->carrera }}</td>
<td>{{ $usuario->telefono }}</td>
</tr>
@endforeach
</tbody>
</table>
</body>
</html>

145
resources/views/usuarios.blade.php

@ -2,9 +2,9 @@
@section('content')
<div class="container mx-auto px-4 py-6">
<!-- Encabezado -->
<!-- Mensajes de éxito y error -->
@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">
<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
@ -16,8 +16,35 @@
@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 Usuarios</h2>
<div class="flex items-center space-x-6">
<!-- Íconos de exportación y agregar -->
<div class="flex space-x-4">
<!-- Exportar a Excel -->
<a href="{{ route('usuarios.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>
<!-- Exportar a PDF -->
<a href="{{ route('usuarios.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 usuario -->
<a href="{{ route('usuarios.create') }}"
class="text-blue-500 hover:text-blue-600 transition-colors duration-200"
title="Agregar nuevo usuario">
<i class="fas fa-plus text-xl"></i>
</a>
</div>
</div>
</div>
<!-- Barra de búsqueda -->
@ -44,6 +71,7 @@
</form>
</div>
<!-- Tabla de usuarios -->
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
@ -51,31 +79,71 @@
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">ID</th>
<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">Puesto</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Carrera</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Teléfono</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Estado</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">
@if($usuarios->isEmpty())
<tr>
<td colspan="4" class="px-6 py-4 text-center text-gray-500">No hay usuarios registrados.</td>
<td colspan="9" class="px-6 py-4 text-center text-gray-500">No hay usuarios registrados.</td>
</tr>
@else
@foreach($usuarios as $usuario)
<tr class="hover:bg-gray-50">
<td class="px-6 py-4 whitespace-nowrap">{{ $usuario->id }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ $usuario->name }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ $usuario->email }}</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex gap-2">
<div class="flex gap-2">
<form action="{{ route('usuarios.destroy', $usuario->id) }}" method="POST" class="inline" onsubmit="return false;">
@csrf
@method('DELETE')
<button type="button" onclick="confirmarEliminacion(this)" class="text-red-600 hover:text-red-900">
<i class="fas fa-trash"></i> <!-- Icono de eliminación -->
</button>
</form>
</div>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ $usuario->id }}</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>
{{ $usuario->name }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $usuario->email }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $usuario->apellido }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $usuario->puesto }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $usuario->carrera }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ $usuario->telefono }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm">
@if($usuario->eliminado == 0)
<span class="flex items-center">
<span class="h-2 w-2 bg-green-500 rounded-full mr-2"></span> Activo
</span>
@else
<span class="flex items-center">
<span class="h-2 w-2 bg-red-500 rounded-full mr-2"></span> Inactivo
</span>
@endif
</td>
<td class="flex space-x-2 px-6 py-4 whitespace-nowrap text-sm">
@if($usuario->eliminado == 1)
<form action="{{ route('usuarios.update', $usuario->id) }}" method="POST" class="d-inline">
@csrf
@method('PUT')
<input type="hidden" name="recuperar" value="1">
<a href="#" onclick="event.preventDefault(); this.closest('form').submit();"
class="text-green-600 hover:text-green-700 transition-colors duration-200"
title="Recuperar usuario">
<i class="fas fa-undo"></i>
</a>
</form>
@else
<a href="{{ route('usuarios.edit', $usuario->id) }}"
class="text-yellow-600 hover:text-yellow-700 transition-colors duration-200"
title="Editar usuario">
<i class="fas fa-edit"></i>
</a>
<form action="{{ route('usuarios.destroy', $usuario->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 usuario">
<i class="fas fa-trash"></i>
</a>
</form>
@endif
</td>
</tr>
@endforeach
@ -87,22 +155,33 @@
</div>
<script>
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').onsubmit = null;
button.closest('form').submit();
// 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

87
resources/views/usuariosCrearEditar.blade.php

@ -0,0 +1,87 @@
@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">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-gray-800">
{{ isset($usuario) ? 'Editar Usuario' : 'Nuevo Usuario' }}
</h2>
</div>
@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="{{ isset($usuario) ? route('usuarios.update', $usuario->id) : route('usuarios.store') }}" method="POST">
@csrf
@if(isset($usuario))
@method('PUT')
@endif
<div class="space-y-6">
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-2">Nombre</label>
<input type="text" name="name" id="name" class="block w-full px-3 py-2 border border-gray-300 rounded-md" required value="{{ isset($usuario) ? $usuario->name : old('name') }}">
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-2">Correo Electrónico</label>
<input type="email" name="email" id="email" class="block w-full px-3 py-2 border border-gray-300 rounded-md" required value="{{ isset($usuario) ? $usuario->email : old('email') }}">
</div>
<div>
<label for="apellido" class="block text-sm font-medium text-gray-700 mb-2">Apellido</label>
<input type="text" name="apellido" id="apellido" class="block w-full px-3 py-2 border border-gray-300 rounded-md" required value="{{ isset($usuario) ? $usuario->apellido : old('apellido') }}">
</div>
<div>
<label for="puesto" class="block text-sm font-medium text-gray-700 mb-2">Puesto</label>
<input type="text" name="puesto" id="puesto" class="block w-full px-3 py-2 border border-gray-300 rounded-md" required value="{{ isset($usuario) ? $usuario->puesto : old('puesto') }}">
</div>
<div>
<label for="carrera" class="block text-sm font-medium text-gray-700 mb-2">Carrera</label>
<input type="text" name="carrera" id="carrera" class="block w-full px-3 py-2 border border-gray-300 rounded-md" required value="{{ isset($usuario) ? $usuario->carrera : old('carrera') }}">
</div>
<div>
<label for="telefono" class="block text-sm font-medium text-gray-700 mb-2">Teléfono</label>
<input type="text" name="telefono" id="telefono" class="block w-full px-3 py-2 border border-gray-300 rounded-md" required value="{{ isset($usuario) ? $usuario->telefono : old('telefono') }}">
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-2">Contraseña</label>
<input type="password" name="password" id="password" class="block w-full px-3 py-2 border border-gray-300 rounded-md" {{ isset($usuario) ? '' : 'required' }}>
</div>
<div>
<label for="password_confirmation" class="block text-sm font-medium text-gray-700 mb-2">Confirmar Contraseña</label>
<input type="password" name="password_confirmation" id="password_confirmation" class="block w-full px-3 py-2 border border-gray-300 rounded-md" {{ isset($usuario) ? '' : 'required' }}>
</div>
<div class="flex justify-end space-x-2 pt-4 border-t border-gray-200">
<a href="{{ route('usuarios') }}" class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50">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">
{{ isset($usuario) ? 'Actualizar' : 'Guardar' }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection

12
routes/web.php

@ -47,11 +47,15 @@ Route::get('marcas/pdf', [MarcaController::class, 'exportPDF'])->name('marcas.pd
Route::middleware(['auth'])->group(function () {
Route::get('/dashboard', [HomeController::class, 'index'])->name('dashboard');
Route::get('/usuarios', [usuariosController::class,'index'])->name('usuarios');
Route::get('/usuarios/nuevo', [usuariosController::class,'create'])->name('usuarios.create');
Route::get('/usuarios/nuevo', [usuariosController::class, 'create'])->name('usuarios.create');
Route::post('/usuarios/store', [usuariosController::class,'store'])->name('usuarios.store');
Route::get('/usuarios/{id}/edit', [usuariosController::class, 'edit'])->name('usuarios.edit');
Route::put('/usuarios/{id}', [usuariosController::class, 'update'])->name('usuarios.update');
Route::delete('/usuarios/{id}', [usuariosController::class, 'destroy'])->name('usuarios.destroy');
Route::get('/usuarios/edit/{id}', [usuariosController::class, 'edit'])->name('usuarios.edit');
Route::put('/usuarios/update', [usuariosController::class,'update'])->name('usuarios.update');
Route::delete('/usuarios/destroy/{id}', [usuariosController::class, 'destroy'])->name('usuarios.destroy');
Route::get('usuarios/excel', [usuariosController::class, 'exportExcel'])->name('usuarios.excel');
Route::get('usuarios/pdf', [usuariosController::class, 'exportPDF'])->name('usuarios.pdf');
Route::get('/home', [HomeController::class, 'index'])->name('home');

Loading…
Cancel
Save