Загрузка данных


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" class="opacity-0" lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Tailwise admin is super flexible, powerful, clean & modern responsive tailwind admin template with unlimited possibilities.">
    <meta name="keywords" content="admin template, Tailwise Admin Template, dashboard template, flat admin template, responsive admin template, web app">
    <meta name="author" content="LEFT4CODE">
    <title>Виртуальный бухгалтер - Чат</title>
    <!-- BEGIN: CSS Assets-->
    <link rel="stylesheet" href="dist/css/vendors/tippy.css">
    <link rel="stylesheet" href="dist/css/vendors/zoom-vanilla.css">
    <link rel="stylesheet" href="dist/css/vendors/simplebar.css">
    <link rel="stylesheet" href="dist/css/themes/hurricane.css">
    <link rel="stylesheet" href="dist/css/app.css">
    <!-- END: CSS Assets-->
</head>
<body>
    <div class="hurricane before:content-[''] before:z-[-1] before:w-screen before:bg-slate-50 before:top-0 before:h-screen before:fixed before:bg-texture-black before:bg-contain before:bg-fixed before:bg-[center_-20rem] before:bg-no-repeat">
        <div class="relative loading-page loading-page--before-hide [&.loading-page--before-hide]:before:block [&.loading-page--hide]:before:opacity-0 before:content-[''] before:transition-opacity before:duration-300 before:hidden before:inset-0 before:h-screen before:w-screen before:fixed before:bg-gradient-to-b before:from-theme-1 before:to-theme-2 before:z-[60] [&.loading-page--before-hide]:after:block [&.loading-page--hide]:after:opacity-0 after:content-[''] after:transition-opacity after:duration-300 after:hidden after:h-16 after:w-16 after:animate-pulse after:fixed after:opacity-50 after:inset-0 after:m-auto after:bg-loading-puff after:bg-cover after:z-[61]">
            
            <!-- TOP BAR -->
            <div class="fixed top-0 left-0 z-50 side-menu group side-menu--collapsed">
                <div class="fixed top-0 inset-x-0 mt-2.5 z-10 mx-2.5 h-[65px] bg-gradient-to-r from-theme-1 to-theme-2 rounded-[0.6rem] shadow-lg flex before:content-[''] before:absolute before:inset-x-0 before:-mt-2.5 before:h-2.5 before:backdrop-blur">
                    <div class="absolute inset-x-0 h-full transition-[padding] duration-100">
                        <div class="flex items-center w-full h-full px-5">
                            <!-- BEGIN: Breadcrumb -->
                            <nav aria-label="breadcrumb" class="flex flex-1 hidden xl:block">
                                <ol class="flex items-center text-theme-1 dark:text-slate-300 text-white/90">
                                    <li class="">
                                        <a href="">Виртуальный бухгалтер</a>
                                    </li>
                                    <li class="relative ml-5 pl-0.5 before:content-[''] before:w-[14px] before:h-[14px] before:bg-chevron-white before:transform before:rotate-[-90deg] before:bg-[length:100%] before:-ml-[1.125rem] before:absolute before:my-auto before:inset-y-0 dark:before:bg-chevron-white">
                                        <a href="">Чат</a>
                                    </li>
                                </ol>
                            </nav>
                            <!-- END: Breadcrumb -->
                            
                            <!-- BEGIN: Notification & User Menu -->
                            <div class="flex items-center flex-1">
                                <div class="flex items-center gap-1 ml-auto">
                                    <a class="p-2 rounded-full request-full-screen hover:bg-white/5" href="">
                                        <i data-tw-merge="" data-lucide="expand" class="stroke-[1] h-[18px] w-[18px] text-white"></i>
                                    </a>
                                </div>
                                <div data-tw-merge="" data-tw-placement="bottom-end" class="dropdown relative ml-5">
                                    <button data-tw-toggle="dropdown" aria-expanded="false" class="cursor-pointer image-fit h-[36px] w-[36px] overflow-hidden rounded-full border-[3px] border-white/[0.15]">
                                    </button>
                                    <div data-transition="" data-selector=".show" data-enter="transition-all ease-linear duration-150" data-enter-from="absolute !mt-5 invisible opacity-0 translate-y-1" data-enter-to="!mt-1 visible opacity-100 translate-y-0" data-leave="transition-all ease-linear duration-150" data-leave-from="!mt-1 visible opacity-100 translate-y-0" data-leave-to="absolute !mt-5 invisible opacity-0 translate-y-1" class="dropdown-menu absolute z-[9999] hidden">
                                        <div data-tw-merge="" class="dropdown-content rounded-md border-transparent bg-white p-2 shadow-[0px_3px_10px_#00000017] dark:border-transparent dark:bg-darkmode-600 w-56 mt-1">
                                            <a href="hurricane-settings-email-settings.html" class="cursor-pointer flex items-center p-2 transition duration-300 ease-in-out rounded-md hover:bg-slate-200/60 dark:bg-darkmode-600 dark:hover:bg-darkmode-400 dropdown-item">
                                                <i data-tw-merge="" data-lucide="inbox" class="stroke-[1] w-4 h-4 mr-2"></i>
                                                Настройки почты
                                            </a>
                                            <a href="hurricane-settings-security.html" class="cursor-pointer flex items-center p-2 transition duration-300 ease-in-out rounded-md hover:bg-slate-200/60 dark:bg-darkmode-600 dark:hover:bg-darkmode-400 dropdown-item">
                                                <i data-tw-merge="" data-lucide="lock" class="stroke-[1] w-4 h-4 mr-2"></i>
                                                Восстановить пароль
                                            </a>
                                            <div class="h-px my-2 -mx-2 bg-slate-200/60 dark:bg-darkmode-400"></div>
                                            <a href="/logout" class="cursor-pointer flex items-center p-2 transition duration-300 ease-in-out rounded-md hover:bg-slate-200/60 dark:bg-darkmode-600 dark:hover:bg-darkmode-400 dropdown-item">
                                                <i data-tw-merge="" data-lucide="power" class="stroke-[1] w-4 h-4 mr-2"></i>
                                                Выйти
                                            </a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <!-- END: Notification & User Menu -->
                        </div>
                    </div>
                </div>
            </div>

            <!-- VUE APP -->
            <div id="chat-app" class="content transition-[margin,width] duration-100 px-5 xl:mr-2.5 mt-[75px] pt-[31px] pb-16 content--compact xl:ml-[275px] [&.content--compact]:xl:ml-[100px]">
                <div class="container">
                    <div class="grid grid-cols-12 gap-x-6 gap-y-10">
                        <div class="col-span-12">
                            <!-- HEADER -->
                            <div class="mt-4 flex flex-col gap-y-3 md:mt-0 md:h-10 md:flex-row md:items-center">
                                <div class="text-base font-medium group-[.mode--light]:text-white">
                                    Чат бот
                                </div>
                                <div class="flex flex-col gap-x-3 gap-y-2 sm:flex-row md:ml-auto">
                                    <button @click="createNewChat" data-tw-merge="" class="transition duration-200 border shadow-sm inline-flex items-center justify-center py-2 px-3 rounded-md font-medium cursor-pointer focus:ring-4 focus:ring-primary focus:ring-opacity-20 focus-visible:outline-none dark:focus:ring-slate-700 dark:focus:ring-opacity-50 [&:hover:not(:disabled)]:bg-opacity-90 [&:hover:not(:disabled)]:border-opacity-90 [&:not(button)]:text-center disabled:opacity-70 disabled:cursor-not-allowed bg-primary border-primary text-white dark:border-primary group-[.mode--light]:!border-transparent group-[.mode--light]:!bg-white/[0.12] group-[.mode--light]:!text-slate-200">
                                        <i data-tw-merge="" data-lucide="messages-square" class="mr-2 h-4 w-4 stroke-[1.3]"></i>
                                        Создать новый чат
                                    </button>
                                </div>
                            </div>
                            
                            <div class="mt-3.5 flex flex-col gap-x-6 gap-y-10 lg:flex-row">
                                <!-- SIDEBAR - ИСТОРИЯ -->
                                <div class="w-full flex-none lg:w-[23rem]">
                                    <div class="flex flex-col gap-y-7">
                                        <div class="box box--stacked flex flex-col p-2">
                                            <ul data-tw-merge="" role="tablist" class="p-0.5 border rounded-lg dark:border-darkmode-400 w-full flex border-transparent bg-transparent">
                                                <li id="example-1-tab" data-tw-merge="" role="presentation" class="focus-visible:outline-none flex-1 first:rounded-l-[0.6rem] last:rounded-r-[0.6rem] [&[aria-selected='true']_button]:border-primary/[0.15] [&[aria-selected='true']_button]:bg-primary/[0.04] [&[aria-selected='true']_button]:font-medium [&[aria-selected='true']_button]:text-primary [&[aria-selected='true']_button]:shadow-sm">
                                                    <button data-tw-merge="" data-tw-target="#example-1" role="tab" class="cursor-pointer appearance-none px-3 border border-transparent transition-colors dark:text-slate-400 [&.active]:text-slate-700 dark:border-transparent [&.active]:border [&.active]:shadow-sm [&.active]:font-medium [&.active]:border-slate-200 [&.active]:bg-white [&.active]:dark:text-slate-300 [&.active]:dark:bg-darkmode-400 [&.active]:dark:border-darkmode-400 active flex w-full items-center justify-center gap-2 whitespace-nowrap rounded-[0.6rem] py-3 text-slate-500">
                                                        <i data-tw-merge="" data-lucide="messages-square" class="h-4 w-4 stroke-[1.4]"></i>
                                                        История
                                                        <span class="flex min-w-[1.15rem] items-center justify-center rounded-full bg-white text-xs">
                                                            <span class="block h-full w-full rounded-full bg-theme-1/[0.75] px-1.5 py-0.5 leading-none text-white">
                                                                @{{ chats.length }}
                                                            </span>
                                                        </span>
                                                    </button>
                                                </li>
                                            </ul>
                                        </div>
                                        
                                        <div class="box box--stacked flex flex-col p-5">
                                            <div class="tab-content">
                                                <div data-transition="" data-selector=".active" id="example-1" role="tabpanel" aria-labelledby="example-1-tab" class="tab-pane active">
                                                    <div class="">
                                                        <div class="relative">
                                                            <i data-tw-merge="" data-lucide="search" class="absolute inset-y-0 left-0 z-10 my-auto ml-4 h-4 w-4 stroke-[1.3] text-slate-500/90"></i>
                                                            <input v-model="searchQuery" data-tw-merge="" type="text" placeholder="Поиск в истории..." class="disabled:bg-slate-100 disabled:cursor-not-allowed dark:disabled:bg-darkmode-800/50 dark:disabled:border-transparent [&[readonly]]:bg-slate-100 [&[readonly]]:cursor-not-allowed [&[readonly]]:dark:bg-darkmode-800/50 [&[readonly]]:dark:border-transparent transition duration-200 ease-in-out w-full text-sm border-slate-200 shadow-sm placeholder:text-slate-400/90 focus:ring-4 focus:ring-primary focus:ring-opacity-20 focus:border-primary focus:border-opacity-40 dark:bg-darkmode-800 dark:border-transparent dark:focus:ring-slate-700 dark:focus:ring-opacity-50 dark:placeholder:text-slate-500/80 [&[type='file']]:border file:mr-4 file:py-2 file:px-4 file:rounded-l-md file:border-0 file:border-r-[1px] file:border-slate-100/10 file:text-sm file:font-semibold file:bg-slate-100 file:text-slate-500/70 hover:file:bg-200 group-[.form-inline]:flex-1 group-[.input-group]:rounded-none group-[.input-group]:[&:not(:first-child)]:border-l-transparent group-[.input-group]:first:rounded-l group-[.input-group]:last:rounded-r group-[.input-group]:z-10 rounded-full py-2.5 pl-10">
                                                        </div>

                                                        <div class="mt-4 flex flex-col gap-1">
                                                            <!-- История чатов -->
                                                            <div v-for="chat in filteredChats" :key="chat.id" 
                                                                 @click="selectChat(chat.id)"
                                                                 :class="['cursor-pointer items-center gap-4 rounded-lg px-2 py-2.5 hover:bg-slate-50', { 'bg-slate-100': currentChatId === chat.id }]"
                                                                 class="-mx-2 flex">
                                                                <div class="w-full">
                                                                    <div class="flex w-full items-center">
                                                                        <div class="max-w-[7rem] truncate font-medium md:max-w-[8rem]">
                                                                            @{{ chat.title }}
                                                                        </div>
                                                                        <div class="ml-auto flex items-center gap-2">
                                                                            <div class="text-xs text-slate-500/90">
                                                                                @{{ formatTime(chat.updated_at) }}
                                                                            </div>
                                                                        </div>
                                                                    </div>
                                                                    <div v-if="chat.last_message" class="mt-1.5 flex items-center">
                                                                        <div class="max-w-[7rem] truncate text-slate-500/90 md:max-w-[10rem]">
                                                                            @{{ chat.last_message }}
                                                                        </div>
                                                                    </div>
                                                                </div>
                                                            </div>
                                                            
                                                            <!-- Пустое состояние -->
                                                            <div v-if="chats.length === 0" class="text-center py-8 text-slate-500">
                                                                Нет истории чатов
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>

                                <!-- CHAT WINDOW -->
                                <div class="flex w-full flex-col gap-y-7">
                                    <div class="box box--stacked flex flex-col p-5">
                                        <!-- HEADER -->
                                        <div class="flex items-center gap-3.5 border-b border-dashed pb-5">
                                            <div>
                                                <div class="image-fit h-12 w-12 overflow-hidden rounded-full border-[3px] border-slate-200/70">
                                                    <img src="dist/images/users/user6-50x50.jpg" alt="Виртуальный бухгалтер">
                                                </div>
                                            </div>
                                            <div>
                                                <div class="max-w-[9rem] truncate font-medium md:max-w-none">
                                                    Виртуальный бухгалтер
                                                </div>
                                                <div class="mt-0.5 max-w-[9rem] truncate text-slate-500 md:max-w-none">
                                                    Ваш персональный помощник
                                                </div>
                                            </div>
                                        </div>
                                        
                                        <!-- MESSAGES -->
                                        <div ref="messagesContainer" class="scrollable-ref h-96 -mx-3 overflow-y-auto [&:-webkit-scrollbar]:w-0 [&:-webkit-scrollbar]:bg-transparent [&_.simplebar-content]:p-0 [&_.simplebar-track.simplebar-vertical]:w-[10px] [&_.simplebar-track.simplebar-vertical]:mr-0.5 [&_.simplebar-track.simplebar-vertical_.simplebar-scrollbar]:before:bg-slate-400/20">
                                            
                                            <!-- Message item -->
                                            <div v-for="message in messages" :key="message.id" 
                                                 :class="['max-w-[85%] sm:max-w-none relative group flex items-end gap-3 pt-4', message.is_bot ? 'mr-auto' : 'ml-auto flex-row-reverse right']">
                                                
                                                <div v-if="message.is_bot" class="hidden sm:block">
                                                    <!-- Avatar placeholder for bot -->
                                                </div>
                                                
                                                <div :class="['rounded-r-xl rounded-tl-xl border border-slate-200/80 px-4 pb-4 pt-3', 
                                                              message.is_bot ? 'bg-slate-50/80' : 'bg-primary/10 rounded-l-xl rounded-br-none text-right']">
                                                    <div>@{{ message.text }}</div>
                                                    
                                                    <!-- Buttons for bot messages -->
                                                    <div v-if="message.is_bot && message.buttons && message.buttons.length > 0" 
                                                         class="max-w-[85%] sm:max-w-none relative mr-auto group pt-4 flex flex-wrap items-end gap-3">
                                                        <button v-for="(button, index) in message.buttons" 
                                                                :key="index"
                                                                @click="handleButtonClick(button, message.id)"
                                                                class="transition duration-200 border shadow-sm inline-flex items-center justify-center py-2 px-3 rounded-md font-medium cursor-pointer focus:ring-4 focus:ring-primary focus:ring-opacity-20 focus-visible:outline-none dark:focus:ring-slate-700 dark:focus:ring-opacity-50 [&:hover:not(:disabled)]:bg-opacity-90 [&:hover:not(:disabled)]:border-opacity-90 [&:not(button)]:text-center disabled:opacity-70 disabled:cursor-not-allowed bg-primary border-primary text-white dark:border-primary group-[.mode--light]:!border-transparent group-[.mode--light]:!bg-white/[0.12] group-[.mode--light]:!text-slate-200">
                                                            <div>@{{ button.text }}</div>
                                                        </button>
                                                    </div>
                                                </div>
                                            </div>
                                            
                                            <!-- Loading indicator -->
                                            <div v-if="isLoading" class="flex justify-center py-4">
                                                <div class="animate-pulse text-slate-500">Печатает...</div>
                                            </div>
                                        </div>
                                        
                                        <!-- INPUT -->
                                        <div class="relative">
                                            <textarea v-model="newMessage" 
                                                      @keyup.enter.exact="sendMessage"
                                                      data-tw-merge="" 
                                                      placeholder="Напишите сообщение..." 
                                                      class="disabled:bg-slate-100 disabled:cursor-not-allowed dark:disabled:bg-darkmode-800/50 dark:disabled:border-transparent [&[readonly]]:bg-slate-100 [&[readonly]]:cursor-not-allowed [&[readonly]]:dark:bg-darkmode-800/50 [&[readonly]]:dark:border-transparent transition duration-200 ease-in-out w-full text-sm border-slate-200 shadow-sm placeholder:text-slate-400/90 focus:ring-4 focus:ring-primary focus:ring-opacity-20 focus:border-primary focus:border-opacity-40 dark:bg-darkmode-800 dark:border-transparent dark:focus:ring-slate-700 dark:focus:ring-opacity-50 dark:placeholder:text-slate-500/80 group-[.form-inline]:flex-1 group-[.input-group]:rounded-none group-[.input-group]:[&:not(:first-child)]:border-l-transparent group-[.input-group]:first:rounded-l group-[.input-group]:last:rounded-r group-[.input-group]:z-10 -mb-1.5 resize-none rounded-xl pr-16"></textarea>
                                            <div class="absolute inset-y-0 right-0 flex w-[3.8rem] items-center justify-center">
                                                <a @click.prevent="sendMessage" class="box flex h-9 w-9 cursor-pointer items-center justify-center rounded-full border-transparent bg-gradient-to-b from-theme-1/90 to-theme-2/90" href="">
                                                    <i data-tw-merge="" data-lucide="send" class="-ml-0.5 h-4 w-4 stroke-[1.3] text-white/70"></i>
                                                </a>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- BEGIN: Vendor JS Assets-->
    <script src="dist/js/vendors/dom.js"></script>
    <script src="dist/js/vendors/tailwind-merge.js"></script>
    <script src="dist/js/vendors/lucide.js"></script>
    <script src="dist/js/vendors/tab.js"></script>
    <script src="dist/js/vendors/tippy.js"></script>
    <script src="dist/js/vendors/popper.js"></script>
    <script src="dist/js/vendors/dropdown.js"></script>
    <script src="dist/js/vendors/image-zoom.js"></script>
    <script src="dist/js/vendors/simplebar.js"></script>
    <script src="dist/js/vendors/transition.js"></script>
    <script src="dist/js/vendors/modal.js"></script>
    <script src="dist/js/components/base/theme-color.js"></script>
    <script src="dist/js/components/base/lucide.js"></script>
    <script src="dist/js/components/base/tippy.js"></script>
    <script src="dist/js/themes/hurricane.js"></script>
    <!-- END: Vendor JS Assets-->
    
    <!-- VUE.JS -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script>
        const { createApp } = Vue;

        createApp({
            data() {
                return {
                    chats: [],
                    currentChatId: null,
                    messages: [],
                    newMessage: '',
                    isLoading: false,
                    searchQuery: ''
                }
            },
            
            computed: {
                filteredChats() {
                    if (!this.searchQuery) return this.chats;
                    
                    return this.chats.filter(chat => 
                        chat.title.toLowerCase().includes(this.searchQuery.toLowerCase())
                    );
                }
            },
            
            mounted() {
                this.loadChats();
                // Инициализация Lucide иконок после монтирования
                this.$nextTick(() => {
                    if (window.lucide) {
                        lucide.createIcons();
                    }
                });
            },
            
            updated() {
                // Переинициализация иконок после обновления
                this.$nextTick(() => {
                    if (window.lucide) {
                        lucide.createIcons();
                    }
                });
            },
            
            methods: {
                // Загрузка списка чатов
                async loadChats() {
                    try {
                        const response = await fetch('/api/chats', {
                            headers: {
                                'Accept': 'application/json',
                                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                            }
                        });
                        
                        if (response.ok) {
                            this.chats = await response.json();
                            
                            // Автоматически выбрать первый чат
                            if (this.chats.length > 0 && !this.currentChatId) {
                                this.selectChat(this.chats[0].id);
                            }
                        }
                    } catch (error) {
                        console.error('Ошибка загрузки чатов:', error);
                    }
                },
                
                // Создание нового чата
                async createNewChat() {
                    try {
                        const response = await fetch('/api/chats', {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'Accept': 'application/json',
                                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                            },
                            body: JSON.stringify({
                                title: 'Новый чат ' + new Date().toLocaleTimeString()
                            })
                        });
                        
                        if (response.ok) {
                            const newChat = await response.json();
                            this.chats.unshift(newChat);
                            this.selectChat(newChat.id);
                        } else {
                            alert('Не удалось создать чат');
                        }
                    } catch (error) {
                        console.error('Ошибка создания чата:', error);
                        alert('Не удалось создать чат');
                    }
                },
                
                // Выбор чата
                async selectChat(chatId) {
                    this.currentChatId = chatId;
                    await this.loadMessages(chatId);
                },
                
                // Загрузка сообщений
                async loadMessages(chatId) {
                    try {
                        this.isLoading = true;
                        const response = await fetch(`/api/chats/${chatId}/messages`, {
                            headers: {
                                'Accept': 'application/json',
                                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                            }
                        });
                        
                        if (response.ok) {
                            this.messages = await response.json();
                            this.scrollToBottom();
                        }
                    } catch (error) {
                        console.error('Ошибка загрузки сообщений:', error);
                    } finally {
                        this.isLoading = false;
                    }
                },
                
                // Отправка сообщения
                async sendMessage() {
                    if (!this.newMessage.trim() || !this.currentChatId) return;
                    
                    const messageText = this.newMessage;
                    this.newMessage = '';
                    
                    // Добавляем сообщение пользователя локально
                    this.messages.push({
                        id: Date.now(),
                        text: messageText,
                        is_bot: false,
                        buttons: []
                    });
                    
                    this.scrollToBottom();
                    
                    try {
                        this.isLoading = true;
                        const response = await fetch(`/api/chats/${this.currentChatId}/messages`, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'Accept': 'application/json',
                                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                            },
                            body: JSON.stringify({
                                message: messageText
                            })
                        });
                        
                        if (response.ok) {
                            const data = await response.json();
                            
                            // Добавляем ответ бота
                            if (data.bot_response) {
                                this.messages.push({
                                    id: data.bot_response.id,
                                    text: data.bot_response.text,
                                    is_bot: true,
                                    buttons: data.bot_response.buttons || []
                                });
                                this.scrollToBottom();
                            }
                            
                            // Обновляем список чатов
                            await this.loadChats();
                        } else {
                            alert('Не удалось отправить сообщение');
                        }
                    } catch (error) {
                        console.error('Ошибка отправки сообщения:', error);
                        alert('Не удалось отправить сообщение');
                    } finally {
                        this.isLoading = false;
                    }
                },
                
                // Обработка нажатия на кнопку в сообщении бота
                async handleButtonClick(button, messageId) {
                    console.log('Нажата кнопка:', button);
                    
                    // Если кнопка отправляет текст
                    if (button.action === 'send_message') {
                        this.newMessage = button.payload || button.text;
                        await this.sendMessage();
                        return;
                    }
                    
                    // Если кнопка выполняет действие (callback)
                    if (button.action === 'callback') {
                        try {
                            this.isLoading = true;
                            const response = await fetch(`/api/chats/${this.currentChatId}/button-callback`, {
                                method: 'POST',
                                headers: {
                                    'Content-Type': 'application/json',
                                    'Accept': 'application/json',
                                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                                },
                                body: JSON.stringify({
                                    button_payload: button.payload,
                                    message_id: messageId
                                })
                            });
                            
                            if (response.ok) {
                                const data = await response.json();
                                
                                if (data.bot_response) {
                                    this.messages.push({
                                        id: data.bot_response.id,
                                        text: data.bot_response.text,
                                        is_bot: true,
                                        buttons: data.bot_response.buttons || []
                                    });
                                    this.scrollToBottom();
                                }
                            }
                        } catch (error) {
                            console.error('Ошибка обработки кнопки:', error);
                        } finally {
                            this.isLoading = false;
                        }
                    }
                },
                
                // Прокрутка вниз
                scrollToBottom() {
                    this.$nextTick(() => {
                        const container = this.$refs.messagesContainer;
                        if (container) {
                            container.scrollTop = container.scrollHeight;
                        }
                    });
                },
                
                // Форматирование времени
                formatTime(timestamp) {
                    if (!timestamp) return '';
                    const date = new Date(timestamp);
                    return date.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });
                }
            }
        }).mount('#chat-app');
    </script>
</body>
</html>



<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ChatController;

Route::middleware('web')->group(function () {
    Route::get('/chats', [ChatController::class, 'index']);
    Route::post('/chats', [ChatController::class, 'store']);
    Route::get('/chats/{chatId}/messages', [ChatController::class, 'messages']);
    Route::post('/chats/{chatId}/messages', [ChatController::class, 'sendMessage']);
    Route::post('/chats/{chatId}/button-callback', [ChatController::class, 'buttonCallback']);
});