8. Listado de Chatbots
Listado de Chatbots
1. Creación de la Vista Index
1.1. Estructura de Carpetas
Creamos la carpeta para las vistas de chatbots:
text
resources/js/Pages/Chatbots/
└── Index.vue
1.2. Crear el Componente Index
Crear resources/js/Pages/Chatbots/Index.vue:
vue
<script setup>
import { defineProps } from 'vue'
import AppLayout from '@/Layouts/AppLayout.vue'
// Importaremos más componentes después
</script>
<template>
<AppLayout title="Chatbots">
<template #header>
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
Chatbots
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xl sm:rounded-lg">
<div class="p-6 lg:p-8 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
<!-- Contenido aquí -->
</div>
</div>
</div>
</div>
</AppLayout>
</template>
2. Controlador - Pasando Datos
2.1. Actualizar ChatbotController
En app/Http/Controllers/ChatbotController.php:
php
<?php
namespace App\Http\Controllers;
use App\Models\Chatbot;
use Illuminate\Http\Request;
use Inertia\Inertia;
class ChatbotController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
// Obtener solo los chatbots del usuario autenticado
$chatbots = $request->user()->chatbots;
return Inertia::render('Chatbots/Index', [
'chatbots' => $chatbots,
]);
}
// ... otros métodos
}
2.2. Importar Request
php
use Illuminate\Http\Request; // Asegurarse de importar
3. Recibir Datos en el Componente
3.1. Definir Props
En resources/js/Pages/Chatbots/Index.vue:
vue
<script setup>
import { defineProps } from 'vue'
import AppLayout from '@/Layouts/AppLayout.vue'
defineProps({
chatbots: {
type: Array,
required: true
}
})
</script>
3.2. Verificar los Datos
Para depuración temporal:
vue
<template>
<AppLayout title="Chatbots">
<!-- ... header ... -->
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xl sm:rounded-lg">
<div class="p-6 lg:p-8">
<!-- Ver datos temporalmente -->
<pre>{{ chatbots }}</pre>
</div>
</div>
</div>
</div>
</AppLayout>
</template>
4. Componente de Lista de Chatbots
4.1. Estructura de la Lista
En Index.vue:
vue
<template>
<AppLayout title="Chatbots">
<template #header>
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
Chatbots
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xl sm:rounded-lg">
<div class="p-6 lg:p-8">
<!-- Lista de chatbots -->
<section aria-label="Lista de chatbots">
<div class="divide-y divide-gray-200 dark:divide-gray-700">
<div
v-for="chatbot in chatbots"
:key="chatbot.id"
>
{{ chatbot.name }}
</div>
</div>
</section>
</div>
</div>
</div>
</div>
</AppLayout>
</template>
5. Componente ChatbotListItem
5.1. Crear el Componente
Crear resources/js/Components/Chatbots/ChatbotListItem.vue:
vue
<script setup>
import { defineProps } from 'vue'
import { Link } from '@inertiajs/vue3'
import { PrimaryButton, SecondaryButton, DangerButton } from '@/Components/Buttons'
defineProps({
chatbot: {
type: Object,
required: true
}
})
</script>
<template>
<div class="flex flex-col md:flex-row md:items-center md:justify-between py-4">
<!-- Información del chatbot -->
<div class="flex-1">
<div class="text-gray-800 dark:text-gray-200 font-medium">
{{ chatbot.name }}
</div>
<div class="text-sm text-gray-500 dark:text-gray-400">
Creado: {{ new Date(chatbot.created_at).toLocaleDateString() }}
</div>
</div>
<!-- Acciones -->
<div class="flex space-x-2 mt-4 md:mt-0">
<PrimaryButton as="a" :href="route('chatbots.show', chatbot.id)">
Ver
</PrimaryButton>
<SecondaryButton as="a" :href="route('chatbots.edit', chatbot.id)">
Editar
</SecondaryButton>
<DangerButton @click="confirmDelete = true">
Eliminar
</DangerButton>
</div>
</div>
</template>
5.2. Actualizar Index con el Componente
En Index.vue:
vue
<script setup>
import { defineProps } from 'vue'
import AppLayout from '@/Layouts/AppLayout.vue'
import ChatbotListItem from '@/Components/Chatbots/ChatbotListItem.vue'
defineProps({
chatbots: {
type: Array,
required: true
}
})
</script>
<template>
<AppLayout title="Chatbots">
<template #header>
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
Chatbots
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xl sm:rounded-lg">
<div class="p-6 lg:p-8">
<section aria-label="Lista de chatbots">
<div class="divide-y divide-gray-200 dark:divide-gray-700">
<ChatbotListItem
v-for="chatbot in chatbots"
:key="chatbot.id"
:chatbot="chatbot"
/>
</div>
</section>
</div>
</div>
</div>
</div>
</AppLayout>
</template>
6. Estilos con Tailwind CSS
6.1. Clases Utilizadas
6.2. Modo Oscuro
Clases para modo oscuro:
dark:text-gray-200 - Texto claro en modo oscuro
dark:bg-gray-800 - Fondo oscuro
dark:border-gray-700 - Bordes en modo oscuro
dark:text-gray-400 - Texto secundario en modo oscuro
6.3. Responsive Design
Puntos de quiebre (breakpoints):
md: - Pantallas medianas (768px+)
lg: - Pantallas grandes (1024px+)
xl: - Pantallas extra grandes (1280px+)
7. Botones de Jetstream
7.1. Botones Disponibles
Jetstream proporciona varios componentes de botones:
vue
<!-- Botón primario (azul) -->
<PrimaryButton>Ver</PrimaryButton>
<!-- Botón secundario (gris) -->
<SecondaryButton>Editar</SecondaryButton>
<!-- Botón de peligro (rojo) -->
<DangerButton>Eliminar</DangerButton>
7.2. Usar con Inertia Links
vue
<!-- Como link de Inertia -->
<PrimaryButton as="a" :href="route('chatbots.show', chatbot.id)">
Ver
</PrimaryButton>
<!-- Con evento de click -->
<DangerButton @click="handleDelete">
Eliminar
</DangerButton>
8. Formateo de Fechas
8.1. Usando JavaScript Nativo
vue
{{ new Date(chatbot.created_at).toLocaleDateString('es-ES') }}
Opciones de formato:
javascript
// Fecha corta
new Date(chatbot.created_at).toLocaleDateString()
// "20/7/2024"
// Fecha larga
new Date(chatbot.created_at).toLocaleDateString('es-ES', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
// "20 de julio de 2024"
// Con hora
new Date(chatbot.created_at).toLocaleString('es-ES')
// "20/7/2024 15:30:45"
8.2. Usando Day.js (Recomendado)
Instalación:
bash
npm install dayjs
Uso:
vue
<script setup>
import dayjs from 'dayjs'
import 'dayjs/locale/es'
dayjs.locale('es')
const formatDate = (date) => {
return dayjs(date).format('DD/MM/YYYY HH:mm')
}
</script>
<template>
<div class="text-sm text-gray-500">
{{ formatDate(chatbot.created_at) }}
</div>
</template>
9. Mejoras Adicionales
9.1. Mensaje cuando no hay Chatbots
En Index.vue:
vue
<template>
<!-- ... -->
<section aria-label="Lista de chatbots">
<div v-if="chatbots.length === 0" class="py-8 text-center">
<p class="text-gray-500 dark:text-gray-400">
No tienes chatbots creados.
</p>
<Link :href="route('chatbots.create')"
class="mt-4 inline-block text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300">
Crear tu primer chatbot
</Link>
</div>
<div v-else class="divide-y divide-gray-200 dark:divide-gray-700">
<ChatbotListItem
v-for="chatbot in chatbots"
:key="chatbot.id"
:chatbot="chatbot"
/>
</div>
</section>
</template>
9.2. Animaciones
Usando Transitions de Vue:
vue
<template>
<TransitionGroup
name="list"
tag="div"
class="divide-y divide-gray-200 dark:divide-gray-700"
>
<ChatbotListItem
v-for="chatbot in chatbots"
:key="chatbot.id"
:chatbot="chatbot"
/>
</TransitionGroup>
</template>
<style scoped>
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
</style>
9.3. Búsqueda y Filtrado
En el controlador:
php
public function index(Request $request)
{
$query = $request->user()->chatbots();
if ($search = $request->get('search')) {
$query->where('name', 'like', "%{$search}%");
}
return Inertia::render('Chatbots/Index', [
'chatbots' => $query->get(),
]);
}
En la vista:
vue
<script setup>
import { ref } from 'vue'
import { router } from '@inertiajs/vue3'
const search = ref('')
const handleSearch = () => {
router.get('/chatbots', { search: search.value }, {
preserveState: true,
})
}
</script>
<template>
<div class="mb-4">
<input
v-model="search"
@input="handleSearch"
type="text"
placeholder="Buscar chatbots..."
class="rounded-lg border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300"
/>
</div>
</template>
10. Resumen Final
10.1. Archivos Creados/Modificados
10.2. Funcionalidades Implementadas
✅ Listado de chatbots del usuario
✅ Visualización de nombre y fecha
✅ Botones de acción (Ver, Editar, Eliminar)
✅ Diseño responsive
✅ Soporte para modo oscuro
✅ Separación en componentes reutilizables
10.3. Próximos Pasos
🚀 Crear funcionalidad para crear nuevos chatbots
📝 Implementar edición de chatbots
🗑️ Agregar eliminación con confirmación
💬 Desarrollar sistema de chat
¡El listado de chatbots está completo y listo para usar!
Comentarios
Publicar un comentario