Se agrega avance de historial de chat y referencias de la ia
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||
import { createFileRoute, useRouterState } from '@tanstack/react-router'
|
||||
import {
|
||||
Sparkles,
|
||||
@@ -10,6 +11,8 @@ import {
|
||||
BookOpen,
|
||||
Check,
|
||||
X,
|
||||
MessageSquarePlus,
|
||||
Trash2,
|
||||
} from 'lucide-react'
|
||||
import { useState, useEffect, useRef, useMemo } from 'react'
|
||||
|
||||
@@ -84,6 +87,52 @@ function RouteComponent() {
|
||||
const [pendingSuggestion, setPendingSuggestion] = useState<any>(null)
|
||||
|
||||
const scrollRef = useRef<HTMLDivElement>(null)
|
||||
const [activeChatId, setActiveChatId] = useState('1')
|
||||
const [chatHistory, setChatHistory] = useState([
|
||||
{ id: '1', title: 'Chat inicial' },
|
||||
])
|
||||
const [allMessages, setAllMessages] = useState<{ [key: string]: Array<any> }>(
|
||||
{
|
||||
'1': [
|
||||
{
|
||||
id: 'm1',
|
||||
role: 'assistant',
|
||||
content: '¡Hola! Soy tu asistente de IA en este chat inicial.',
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
const currentMessages = allMessages[activeChatId] || []
|
||||
|
||||
const createNewChat = () => {
|
||||
const newId = Date.now().toString()
|
||||
const newChat = { id: newId, title: `Nuevo chat ${chatHistory.length + 1}` }
|
||||
|
||||
setChatHistory([newChat, ...chatHistory])
|
||||
setAllMessages({
|
||||
...allMessages,
|
||||
[newId]: [
|
||||
{
|
||||
id: '1',
|
||||
role: 'assistant',
|
||||
content: '¡Nuevo chat creado! ¿En qué puedo ayudarte?',
|
||||
},
|
||||
],
|
||||
})
|
||||
setActiveChatId(newId)
|
||||
}
|
||||
|
||||
const deleteChat = (e: React.MouseEvent, id: string) => {
|
||||
e.stopPropagation() // Evita que se seleccione el chat al borrarlo
|
||||
|
||||
const newHistory = chatHistory.filter((chat) => chat.id !== id)
|
||||
setChatHistory(newHistory)
|
||||
|
||||
// Si borramos el chat activo, pasamos al primero disponible
|
||||
if (activeChatId === id && newHistory.length > 0) {
|
||||
setActiveChatId(newHistory[0].id)
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Transformar datos de la API para el menú de selección
|
||||
const availableFields = useMemo(() => {
|
||||
@@ -208,6 +257,49 @@ ${fieldsText}
|
||||
}
|
||||
return (
|
||||
<div className="flex h-[calc(100vh-160px)] max-h-[calc(100vh-160px)] w-full gap-6 overflow-hidden p-4">
|
||||
{/* --- PANEL IZQUIERDO: HISTORIAL (NUEVO) --- */}
|
||||
<div className="flex w-64 flex-col border-r pr-4">
|
||||
<div className="mb-4">
|
||||
<h2 className="mb-4 px-2 text-xs font-bold tracking-wider text-slate-500 uppercase">
|
||||
Chats
|
||||
</h2>
|
||||
<Button
|
||||
onClick={createNewChat}
|
||||
variant="outline"
|
||||
className="mb-4 w-full justify-start gap-2 border-slate-200 hover:bg-teal-50 hover:text-teal-700"
|
||||
>
|
||||
<MessageSquarePlus size={18} /> Nuevo chat
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<ScrollArea className="flex-1">
|
||||
<div className="space-y-1">
|
||||
{chatHistory.map((chat) => (
|
||||
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
|
||||
<div
|
||||
key={chat.id}
|
||||
onClick={() => setActiveChatId(chat.id)}
|
||||
className={`group relative flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-3 text-sm transition-colors ${
|
||||
activeChatId === chat.id
|
||||
? 'bg-slate-100 font-medium text-slate-900'
|
||||
: 'text-slate-600 hover:bg-slate-50'
|
||||
}`}
|
||||
>
|
||||
<FileText size={16} className="shrink-0 opacity-40" />
|
||||
<span className="truncate pr-6">{chat.title}</span>
|
||||
|
||||
{/* Botón de borrar que aparece al hacer hover */}
|
||||
<button
|
||||
onClick={(e) => deleteChat(e, chat.id)}
|
||||
className="absolute right-2 p-1 opacity-0 transition-opacity group-hover:opacity-100 hover:text-red-600"
|
||||
>
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
{/* PANEL DE CHAT PRINCIPAL */}
|
||||
<div className="relative flex min-w-0 flex-[3] flex-col overflow-hidden rounded-xl border border-slate-200 bg-slate-50/50 shadow-sm">
|
||||
{/* NUEVO: Barra superior de campos seleccionados */}
|
||||
@@ -285,7 +377,6 @@ ${fieldsText}
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* INPUT FIJO AL FONDO CON SUGERENCIAS : */}
|
||||
{/* INPUT FIJO AL FONDO CON SUGERENCIAS : */}
|
||||
<div className="shrink-0 border-t bg-white p-4">
|
||||
<div className="relative mx-auto max-w-4xl">
|
||||
|
||||
Reference in New Issue
Block a user