14 📋 | Listado de Roles: Creando una Tabla Profesional con Tailwind CSS | Laravel 12 🚀
Duración: 11 minDescripción
📋 Lección 14: Listado de Roles y Tablas Profesionales con Tailwind CSS
En esta sesión, aprenderás a conectar la base de datos con la interfaz de usuario, transformando los registros de seguridad en una tabla administrativa elegante, moderna y funcional dentro de Benji V2.
🗄️ Preparación de Datos en la DB
Antes de programar la vista, establecemos los cimientos de nuestro sistema de permisos:
- 🏗️ Roles Estratégicos: Creamos manualmente los roles base directamente en la tabla roles de Spatie: Super Administrador, Prestamista y Cobrador [01:29].
- 🌐 Guard Name: Definimos el guard como web, asegurando la compatibilidad con el sistema de autenticación estándar de Laravel [01:54].
🧠 Lógica en el Controlador (Eloquent Power)
Aprendemos a recuperar información de forma eficiente usando el ORM de Laravel:
- 🔍 Consulta Global: Utilizamos el método Role::all() para extraer todos los registros de la tabla de roles con una sola línea de código [04:04].
- 📦 Paso de Variables: Implementamos la función compact('roles') para inyectar los datos desde el controlador hacia nuestra vista de Blade [05:48].
🎨 Diseño de Interfaz con Tailwind CSS
Construimos una tabla con acabado profesional y alta legibilidad:
- 🔄 Bucle de Datos: Implementamos la directiva @foreach para iterar sobre la colección de roles y generar filas dinámicamente [06:04].
- 🔢 Iteración Inteligente: Utilizamos $loop->iteration para mostrar un contador correlativo automático (1, 2, 3...) independientemente del ID de la base de datos [08:57].
- ✨ Estética y Alineación: Aplicamos clases de Tailwind CSS para centrar textos, añadir sombras y definir estados para las acciones de visualizar, editar y eliminar [09:48].
✅ Resultado de la Lección
Al finalizar, habrás desarrollado un centro de mando para roles. El sistema ahora muestra en tiempo real cualquier cambio en la base de datos dentro de una tabla estilizada, equipada con botones de acción y lista para ser expandida con funcionalidades de CRUD.
Contenido
Código fuente de la lección
<x-layouts.app title="Roles del sistema">
<div class="relative mb-6 w-full">
<flux:heading size="xl" level="1">Roles del sistema</flux:heading>
<br>
<flux:separator variant="subtle" />
</div>
<div class="flex justify-end">
<a href="{{ url('/admin/roles/create') }}"
class="inline-flex items-center px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white text-xs font-semibold rounded transition">
<i class="fas fa-plus mr-2"></i>
Crear nuevo
</a>
</div>
<div class="overflow-x-auto rounded-lg border border-gray-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 mt-6">
<table class="min-w-full border-collapse">
<thead class="bg-gray-50 dark:bg-zinc-900 text-center">
<tr>
<th
class="px-6 py-3 border-x border-b border-gray-200 dark:border-zinc-700 text-xs font-bold text-gray-500 dark:text-gray-300 uppercase tracking-wider">
Nro</th>
<th
class="px-6 py-3 border-x border-b border-gray-200 dark:border-zinc-700 text-xs font-bold text-gray-500 dark:text-gray-300 uppercase tracking-wider">
Rol</th>
<th
class="px-6 py-3 border-x border-b border-gray-200 dark:border-zinc-700 text-xs font-bold text-gray-500 dark:text-gray-300 uppercase tracking-wider">
Acciones</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-zinc-800">
@foreach ($roles as $rol)
<tr class="hover:bg-gray-50 dark:hover:bg-zinc-700/50 transition">
<td
class="px-3 py-2 border border-gray-200 dark:border-zinc-700 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 text-center">
{{ $loop->iteration }}</td>
<td
class="px-3 py-2 border border-gray-200 dark:border-zinc-700 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
{{ $rol->name }}</td>
<td class="px-3 py-2 border border-gray-200 dark:border-zinc-700 whitespace-nowrap text-center">
<div class="flex justify-center gap-2">
<a href="{{ url('/admin/rol/' . $rol->id) }}"
class="inline-flex items-center px-4 py-2 bg-gray-500 hover:bg-gray-600 text-white text-xs font-semibold rounded transition">
<i class="fas fa-eye mr-2"></i> Ver
</a>
<a href="{{ url('/admin/rol/' . $rol->id . '/edit') }}"
class="inline-flex items-center px-4 py-2 bg-green-500 hover:bg-green-600 text-white text-xs font-semibold rounded transition">
<i class="fas fa-pencil-alt mr-2"></i> Editar
</a>
<form action="{{ url('/admin/rol/' . $rol->id) }}" method="post"
id="miFormulario{{ $rol->id }}">
@csrf
@method('DELETE')
<button type="submit"
class="inline-flex items-center px-4 py-2 bg-red-500 hover:bg-red-600 text-white text-xs font-semibold rounded transition"
onclick="preguntar{{ $rol->id }}(event)">
<i class="fas fa-trash-alt mr-2"></i> Eliminar
</button>
</form>
<script>
function preguntar{{ $rol->id }}(event) {
event.preventDefault();
Swal.fire({
title: '¿Desea eliminar este registro?',
text: '',
icon: 'question',
showDenyButton: true,
confirmButtonText: 'Eliminar',
confirmButtonColor: '#a5161d',
denyButtonColor: '#270a0a',
denyButtonText: 'Cancelar',
}).then((result) => {
if (result.isConfirmed) {
// JavaScript puro para enviar el formulario
document.getElementById('miFormulario{{ $rol->id }}').submit();
}
});
}
</script>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="py-4 flex justify-center">
</div>
</x-layouts.app>
Lecciones
Apoya este proyecto
Si te gusta nuestro contenido, ¡apóyanos con una donación!
Donar por Airtm Donar por Binance¡Gracias por tu apoyo! ❤️