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

Clase

Función

divide-y divide-gray-200

Separador horizontal entre items

dark:divide-gray-700

Separador en modo oscuro

flex flex-col md:flex-row

Columnas en móvil, filas en escritorio

md:items-center

Centrado vertical en escritorio

md:justify-between

Espaciado entre elementos en escritorio

py-4

Padding vertical

space-x-2

Espaciado horizontal entre botones

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

Archivo

Acción

resources/js/Pages/Chatbots/Index.vue

✅ Creado

resources/js/Components/Chatbots/ChatbotListItem.vue

✅ Creado

app/Http/Controllers/ChatbotController.php

✅ Actualizado

routes/web.php

✅ Actualizado previamente

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

  1. 🚀 Crear funcionalidad para crear nuevos chatbots

  2. 📝 Implementar edición de chatbots

  3. 🗑️ Agregar eliminación con confirmación

  4. 💬 Desarrollar sistema de chat

¡El listado de chatbots está completo y listo para usar! 


Comentarios

Entradas más populares de este blog

1. Introducción al curso de Chatbots personalizados con Laravel & OpenAI

2. Prerequisitos para el Curso de Chatbots con Laravel y OpenAI

4. Herramientas de Calidad