@@ -25,7 +25,12 @@ import type { IASugerencia } from '@/types/asignatura'
|
||||
import ReferenciasParaIA from '@/components/planes/wizard/PasoDetallesPanel/ReferenciasParaIA'
|
||||
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Drawer, DrawerContent } from '@/components/ui/drawer'
|
||||
import {
|
||||
Drawer,
|
||||
DrawerContent,
|
||||
DrawerOverlay,
|
||||
DrawerPortal,
|
||||
} from '@/components/ui/drawer'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import {
|
||||
@@ -75,6 +80,7 @@ export function IAAsignaturaTab({
|
||||
const [showSuggestions, setShowSuggestions] = useState(false)
|
||||
const [isSending, setIsSending] = useState(false)
|
||||
const scrollRef = useRef<HTMLDivElement>(null)
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(false)
|
||||
|
||||
// --- DATA QUERIES ---
|
||||
const { data: datosGenerales } = useSubject(asignaturaId)
|
||||
@@ -355,10 +361,35 @@ export function IAAsignaturaTab({
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="flex h-[calc(100vh-160px)] w-full gap-6 overflow-hidden p-4">
|
||||
{/* PANEL IZQUIERDO */}
|
||||
<div className="flex w-64 flex-col border-r pr-4">
|
||||
<div className="mb-4 flex items-center justify-between px-2">
|
||||
<div className="flex h-full w-full overflow-hidden bg-white">
|
||||
<div className="fixed top-0 z-40 flex w-full items-center justify-between border-b bg-white/80 p-2 backdrop-blur-md">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-slate-600"
|
||||
onClick={() => setIsSidebarOpen(true)}
|
||||
>
|
||||
<History size={18} className="mr-2" /> Historial
|
||||
</Button>
|
||||
|
||||
<div className="flex flex-col items-center">
|
||||
<span className="text-[9px] font-bold tracking-wider text-teal-600 uppercase">
|
||||
Asistente
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-slate-600"
|
||||
onClick={() => setOpenIA(true)} // O el drawer de acciones/referencias
|
||||
>
|
||||
<FileText size={18} className="mr-2 text-teal-600" /> Referencias
|
||||
</Button>
|
||||
</div>
|
||||
{/* 1. PANEL IZQUIERDO (HISTORIAL) - Desktop */}
|
||||
<aside className="hidden h-full w-64 shrink-0 flex-col border-r bg-white pr-4 md:flex">
|
||||
<div className="mb-4 flex items-center justify-between px-2 pt-4">
|
||||
<h2 className="flex items-center gap-2 text-xs font-bold text-slate-500 uppercase">
|
||||
<History size={14} /> Historial
|
||||
</h2>
|
||||
@@ -378,25 +409,19 @@ export function IAAsignaturaTab({
|
||||
<Button
|
||||
onClick={() => {
|
||||
setActiveChatId(undefined)
|
||||
hasInitialSelected.current = true
|
||||
setIsCreatingNewChat(true)
|
||||
setInput('')
|
||||
setSelectedFields([])
|
||||
|
||||
// 4. Opcional: Limpiar el caché de mensajes actual para que la pantalla se vea vacía al instante
|
||||
queryClient.setQueryData(['subject-messages', undefined], [])
|
||||
}}
|
||||
variant="outline"
|
||||
className="mb-4 w-full justify-start gap-2 border-dashed border-slate-300 hover:border-teal-500"
|
||||
className="mb-4 w-full justify-start gap-2 border-dashed border-slate-300 text-slate-600 hover:border-teal-500 hover:bg-teal-50/50"
|
||||
>
|
||||
<MessageSquarePlus size={18} /> Nuevo Chat
|
||||
</Button>
|
||||
|
||||
{/* PANEL IZQUIERDO - Cambios en ScrollArea y contenedor */}
|
||||
<ScrollArea className="flex-1">
|
||||
<div className="flex flex-col gap-1 pr-3">
|
||||
{' '}
|
||||
{/* Eliminado space-y-1 para mejor control con gap */}
|
||||
{(showArchived ? archivedChats : activeChats).map((chat: any) => (
|
||||
<div
|
||||
key={chat.id}
|
||||
@@ -507,31 +532,51 @@ export function IAAsignaturaTab({
|
||||
))}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</aside>
|
||||
|
||||
{/* 2. PANEL CENTRAL (CHAT) - EL RECUADRO ESTILIZADO */}
|
||||
<main className="relative flex min-w-0 flex-1 flex-col overflow-hidden rounded-xl border border-slate-200 bg-slate-50/50 shadow-sm md:m-2">
|
||||
{/* Header Interno del Recuadro */}
|
||||
<div className="flex shrink-0 items-center justify-between border-b bg-white p-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="md:hidden"
|
||||
onClick={() => setIsSidebarOpen(true)}
|
||||
>
|
||||
<History size={20} className="text-slate-500" />
|
||||
</Button>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[10px] font-bold tracking-wider text-teal-600 uppercase">
|
||||
Asistente Académico
|
||||
</span>
|
||||
<span className="text-[11px] text-slate-400">
|
||||
Personalizado para tu asignatura
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* PANEL CENTRAL */}
|
||||
<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">
|
||||
<div className="flex shrink-0 items-center justify-between border-b bg-white p-3">
|
||||
<span className="text-[10px] font-bold tracking-wider text-slate-400 uppercase">
|
||||
Asistente IA
|
||||
</span>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => setOpenIA(true)}
|
||||
className="flex items-center gap-2 rounded-md bg-slate-100 px-3 py-1.5 text-xs font-medium transition hover:bg-slate-200"
|
||||
className="flex items-center gap-2 rounded-lg bg-slate-100 px-3 py-1.5 text-xs font-medium text-slate-600 transition-colors hover:bg-slate-200"
|
||||
>
|
||||
<FileText size={14} className="text-slate-500" />
|
||||
Referencias
|
||||
<FileText size={14} />
|
||||
<span className="xs:inline hidden">Referencias</span>
|
||||
{totalReferencias > 0 && (
|
||||
<span className="animate-in zoom-in flex h-4 min-w-[16px] items-center justify-center rounded-full bg-teal-600 px-1 text-[10px] text-white">
|
||||
<span className="flex h-4 min-w-[16px] items-center justify-center rounded-full bg-teal-600 px-1 text-[10px] text-white">
|
||||
{totalReferencias}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Área de Mensajes */}
|
||||
<div className="relative min-h-0 flex-1">
|
||||
<ScrollArea ref={scrollRef} className="h-full w-full">
|
||||
<div className="mx-auto max-w-3xl space-y-8 p-6">
|
||||
<div className="mx-auto max-w-3xl space-y-6 p-3 md:p-6">
|
||||
{messages.map((msg) => (
|
||||
<div
|
||||
key={msg.id}
|
||||
@@ -642,8 +687,9 @@ export function IAAsignaturaTab({
|
||||
</ScrollArea>
|
||||
</div>
|
||||
|
||||
{/* INPUT */}
|
||||
<div className="shrink-0 border-t bg-white p-4">
|
||||
{/* Input de Chat */}
|
||||
<footer className="shrink-0 border-t bg-white p-3 md:p-4">
|
||||
<div className="shrink-0 border-t bg-white p-2 md:p-4">
|
||||
<div className="relative mx-auto max-w-4xl">
|
||||
{showSuggestions && (
|
||||
<div className="animate-in fade-in slide-in-from-bottom-2 absolute bottom-full left-0 z-50 mb-2 w-72 overflow-hidden rounded-xl border bg-white shadow-2xl">
|
||||
@@ -722,7 +768,8 @@ export function IAAsignaturaTab({
|
||||
<Button
|
||||
onClick={() => handleSend()}
|
||||
disabled={
|
||||
(!input.trim() && selectedFields.length === 0) || isSending
|
||||
(!input.trim() && selectedFields.length === 0) ||
|
||||
isSending
|
||||
}
|
||||
size="icon"
|
||||
className="h-9 w-9 bg-teal-600 hover:bg-teal-700"
|
||||
@@ -733,29 +780,33 @@ export function IAAsignaturaTab({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
{/* PANEL DERECHO ACCIONES */}
|
||||
<div className="flex flex-[1] flex-col gap-4 overflow-y-auto pr-2">
|
||||
{/* 3. PANEL DERECHO (ATAJOS) */}
|
||||
<aside className="hidden w-64 shrink-0 flex-col gap-4 overflow-y-auto p-4 lg:flex">
|
||||
<h4 className="flex items-center gap-2 text-sm font-bold text-slate-800">
|
||||
<Lightbulb size={18} className="text-orange-500" /> Atajos
|
||||
<Lightbulb size={18} className="text-orange-500" /> Atajos Rápidos
|
||||
</h4>
|
||||
<div className="space-y-2">
|
||||
{PRESETS.map((preset) => (
|
||||
<button
|
||||
key={preset.id}
|
||||
onClick={() => handleSend(preset.prompt)}
|
||||
className="group flex w-full items-center gap-3 rounded-xl border bg-white p-3 text-left text-sm transition-all hover:border-teal-500 hover:bg-teal-50"
|
||||
className="group flex w-full items-center gap-3 rounded-xl border border-slate-100 bg-white p-3 text-left text-sm transition-all hover:border-teal-500 hover:shadow-sm"
|
||||
>
|
||||
<div className="rounded-lg bg-slate-100 p-2 group-hover:bg-teal-100 group-hover:text-teal-600">
|
||||
<div className="rounded-lg bg-slate-50 p-2 group-hover:bg-teal-50 group-hover:text-teal-600">
|
||||
<preset.icon size={16} />
|
||||
</div>
|
||||
<span className="font-medium text-slate-700">{preset.label}</span>
|
||||
<span className="font-medium text-slate-600 group-hover:text-slate-900">
|
||||
{preset.label}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{/* --- DRAWER DE REFERENCIAS --- */}
|
||||
</aside>
|
||||
|
||||
{/* DRAWERS (Referencias e Historial Móvil) */}
|
||||
<Drawer open={openIA} onOpenChange={setOpenIA}>
|
||||
<DrawerContent className="fixed inset-x-0 bottom-0 mx-auto mb-4 flex h-[80vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl border bg-white shadow-2xl">
|
||||
<div className="flex items-center justify-between border-b bg-slate-50/50 px-4 py-3">
|
||||
@@ -790,6 +841,140 @@ export function IAAsignaturaTab({
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<Drawer open={isSidebarOpen} onOpenChange={setIsSidebarOpen}>
|
||||
<DrawerPortal>
|
||||
<DrawerOverlay className="fixed inset-0 bg-black/40" />
|
||||
<DrawerContent className="fixed right-0 bottom-0 left-0 h-[70vh] p-4 outline-none">
|
||||
<div className="flex h-full flex-col overflow-hidden">
|
||||
{/* Reutiliza aquí el componente de la lista de chats */}
|
||||
<Button
|
||||
onClick={() => {
|
||||
setActiveChatId(undefined)
|
||||
setIsCreatingNewChat(true)
|
||||
setInput('')
|
||||
setSelectedFields([])
|
||||
queryClient.setQueryData(['subject-messages', undefined], [])
|
||||
setIsSidebarOpen(false) // Cierra el drawer al crear nuevo
|
||||
}}
|
||||
variant="outline"
|
||||
className="mb-6 w-full justify-center gap-2 border-dashed border-teal-500 bg-teal-50/50 text-teal-700 hover:bg-teal-100"
|
||||
>
|
||||
<MessageSquarePlus size={18} /> Nuevo Chat
|
||||
</Button>
|
||||
<h2 className="mb-4 font-bold">Historial de Chats</h2>
|
||||
{(showArchived ? archivedChats : activeChats).map((chat: any) => (
|
||||
<div
|
||||
key={chat.id}
|
||||
className={cn(
|
||||
// Agregamos 'overflow-hidden' para que nada salga de este cuadro
|
||||
'group relative flex w-full min-w-0 items-center justify-between gap-2 overflow-hidden rounded-lg px-3 py-2 text-sm transition-all',
|
||||
activeChatId === chat.id
|
||||
? 'bg-teal-50 text-teal-900'
|
||||
: 'text-slate-600 hover:bg-slate-100',
|
||||
)}
|
||||
onDoubleClick={() => {
|
||||
setEditingId(chat.id)
|
||||
setTempName(chat.nombre || chat.titulo || 'Conversacion')
|
||||
}}
|
||||
>
|
||||
{editingId === chat.id ? (
|
||||
<div className="flex min-w-0 flex-1 items-center">
|
||||
<input
|
||||
autoFocus
|
||||
className="w-full rounded border-none bg-white px-1 text-xs ring-1 ring-teal-400 outline-none"
|
||||
value={tempName}
|
||||
onChange={(e) => setTempName(e.target.value)}
|
||||
onBlur={() => handleSaveName(chat.id)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') handleSaveName(chat.id)
|
||||
if (e.key === 'Escape') setEditingId(null)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* CLAVE 2: 'truncate' y 'min-w-0' en el span para que ceda ante los botones */}
|
||||
<span
|
||||
onClick={() => setActiveChatId(chat.id)}
|
||||
className="block max-w-[140px] min-w-0 flex-1 cursor-pointer truncate pr-1"
|
||||
title={chat.nombre || chat.titulo}
|
||||
>
|
||||
{chat.nombre || chat.titulo || 'Conversación'}
|
||||
</span>
|
||||
|
||||
{/* CLAVE 3: 'shrink-0' asegura que los botones NUNCA desaparezcan */}
|
||||
<div
|
||||
className={cn(
|
||||
'z-10 flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100',
|
||||
activeChatId === chat.id
|
||||
? 'bg-teal-50'
|
||||
: 'bg-slate-100',
|
||||
)}
|
||||
>
|
||||
<TooltipProvider delayDuration={300}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setEditingId(chat.id)
|
||||
setTempName(chat.nombre || chat.titulo || '')
|
||||
}}
|
||||
className="rounded-md p-1 transition-colors hover:bg-slate-200 hover:text-teal-600"
|
||||
>
|
||||
<Edit2 size={14} />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top" className="text-[10px]">
|
||||
Editar nombre
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
const nuevoEstado =
|
||||
chat.estado === 'ACTIVA'
|
||||
? 'ARCHIVADA'
|
||||
: 'ACTIVA'
|
||||
updateStatus({
|
||||
id: chat.id,
|
||||
estado: nuevoEstado,
|
||||
})
|
||||
}}
|
||||
className={cn(
|
||||
'rounded-md p-1 transition-colors hover:bg-slate-200',
|
||||
chat.estado === 'ACTIVA'
|
||||
? 'hover:text-red-500'
|
||||
: 'hover:text-teal-600',
|
||||
)}
|
||||
>
|
||||
{chat.estado === 'ACTIVA' ? (
|
||||
<Archive size={14} />
|
||||
) : (
|
||||
<History size={14} className="scale-x-[-1]" />
|
||||
)}
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top" className="text-[10px]">
|
||||
{chat.estado === 'ACTIVA'
|
||||
? 'Archivar'
|
||||
: 'Desarchivar'}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</DrawerPortal>
|
||||
</Drawer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -139,6 +139,10 @@ function RouteComponent() {
|
||||
null,
|
||||
)
|
||||
const [filterQuery, setFilterQuery] = useState('')
|
||||
|
||||
const [isHistoryOpen, setIsHistoryOpen] = useState(false)
|
||||
const [isActionsOpen, setIsActionsOpen] = useState(false)
|
||||
|
||||
const availableFields = useMemo(() => {
|
||||
const definicion = data?.estructuras_plan
|
||||
?.definicion as EstructuraDefinicion
|
||||
@@ -478,37 +482,38 @@ function RouteComponent() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-[calc(100vh-160px)] max-h-[calc(100vh-160px)] w-full gap-6 overflow-hidden p-4">
|
||||
{/* --- PANEL IZQUIERDO: HISTORIAL --- */}
|
||||
<div className="flex w-64 flex-col border-r pr-4">
|
||||
<div className="mb-4">
|
||||
<div className="mb-4 flex items-center justify-between px-2">
|
||||
<h2 className="text-xs font-bold tracking-wider text-slate-500 uppercase">
|
||||
Chats
|
||||
</h2>
|
||||
{/* Botón de toggle archivados movido aquí arriba */}
|
||||
<button
|
||||
onClick={() => setShowArchived(!showArchived)}
|
||||
className={`rounded-md p-1.5 transition-colors ${
|
||||
showArchived
|
||||
? 'bg-teal-50 text-teal-600'
|
||||
: 'text-slate-400 hover:bg-slate-100'
|
||||
}`}
|
||||
title={showArchived ? 'Ver chats activos' : 'Ver archivados'}
|
||||
>
|
||||
<Archive size={16} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex h-[calc(100vh-160px)] max-h-[calc(100vh-160px)] w-full flex-col gap-6 overflow-hidden p-4 md:flex-row">
|
||||
{/* --- HEADER MÓVIL (Solo visible en < md) --- */}
|
||||
<div className="flex items-center justify-between rounded-lg border bg-white p-2 md:hidden">
|
||||
<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"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setIsHistoryOpen(true)}
|
||||
>
|
||||
<MessageSquarePlus size={18} /> Nuevo chat
|
||||
<Archive size={18} className="mr-2" /> Historial
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setIsActionsOpen(true)}
|
||||
>
|
||||
<Lightbulb size={18} className="mr-2 text-orange-500" /> Acciones
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* --- PANEL IZQUIERDO: HISTORIAL (Escritorio) --- */}
|
||||
<div className="hidden w-64 flex-col border-r pr-4 md:flex">
|
||||
{/* ... (Tu código actual del historial de chats) ... */}
|
||||
<h2 className="text-xs font-bold tracking-wider text-slate-500 uppercase">
|
||||
Chats
|
||||
</h2>
|
||||
<Button
|
||||
onClick={createNewChat}
|
||||
variant="outline"
|
||||
className="mt-2 mb-4 w-full justify-start gap-2"
|
||||
>
|
||||
<MessageSquarePlus size={18} /> Nuevo chat
|
||||
</Button>
|
||||
<ScrollArea className="flex-1">
|
||||
<div className="space-y-1 pr-2">
|
||||
{' '}
|
||||
@@ -655,8 +660,9 @@ function RouteComponent() {
|
||||
</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">
|
||||
|
||||
{/* --- PANEL DE CHAT PRINCIPAL (Centro) --- */}
|
||||
<div className="relative flex min-w-0 flex-1 flex-col overflow-hidden rounded-xl border border-slate-200 bg-slate-50/50 shadow-sm md:flex-[3]">
|
||||
{/* NUEVO: Barra superior de campos seleccionados */}
|
||||
<div className="shrink-0 border-b bg-white p-3">
|
||||
<div className="flex items-center justify-between">
|
||||
@@ -931,8 +937,9 @@ function RouteComponent() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* PANEL LATERAL */}
|
||||
<div className="flex flex-[1] flex-col gap-4 overflow-y-auto pr-2">
|
||||
|
||||
{/* --- PANEL LATERAL: ACCIONES RÁPIDAS (Escritorio) --- */}
|
||||
<div className="hidden flex-[1] flex-col gap-4 overflow-y-auto pr-2 md:flex">
|
||||
<h4 className="flex items-center gap-2 text-left text-sm font-bold text-slate-800">
|
||||
<Lightbulb size={18} className="text-orange-500" /> Acciones rápidas
|
||||
</h4>
|
||||
@@ -953,6 +960,65 @@ function RouteComponent() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* --- DRAWER: HISTORIAL (Móvil) --- */}
|
||||
<Drawer open={isHistoryOpen} onOpenChange={setIsHistoryOpen}>
|
||||
<DrawerContent className="h-[80vh] p-4">
|
||||
<Button
|
||||
onClick={() => {
|
||||
createNewChat()
|
||||
setIsHistoryOpen(false)
|
||||
}}
|
||||
className="mb-4 w-full bg-teal-600 text-white"
|
||||
>
|
||||
<MessageSquarePlus size={18} className="mr-2" /> Nuevo Chat
|
||||
</Button>
|
||||
<ScrollArea className="flex-1">
|
||||
{/* Reutiliza aquí el mapeo de chats que tienes en el panel izquierdo */}
|
||||
<p className="mb-4 text-xs font-bold text-slate-400 uppercase">
|
||||
Historial Reciente
|
||||
</p>
|
||||
{activeChats.map((chat) => (
|
||||
<div
|
||||
key={chat.id}
|
||||
onClick={() => {
|
||||
setActiveChatId(chat.id)
|
||||
setIsHistoryOpen(false)
|
||||
}}
|
||||
className="border-b p-3 text-sm"
|
||||
>
|
||||
{chat.nombre || 'Chat sin nombre'}
|
||||
</div>
|
||||
))}
|
||||
</ScrollArea>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
{/* --- DRAWER: ACCIONES RÁPIDAS (Móvil) --- */}
|
||||
<Drawer open={isActionsOpen} onOpenChange={setIsActionsOpen}>
|
||||
<DrawerContent className="h-[60vh] p-4">
|
||||
<h4 className="mb-4 flex items-center gap-2 font-bold">
|
||||
<Lightbulb size={18} className="text-orange-500" /> Acciones rápidas
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
{PRESETS.map((preset) => (
|
||||
<button
|
||||
key={preset.id}
|
||||
onClick={() => {
|
||||
handleSend(preset.prompt)
|
||||
setIsActionsOpen(false)
|
||||
}}
|
||||
className="flex items-center gap-3 rounded-xl border p-4 text-left text-sm"
|
||||
>
|
||||
<preset.icon size={16} />
|
||||
<span>{preset.label}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
{/* Tu Drawer de Referencias IA se queda igual */}
|
||||
<Drawer open={openIA} onOpenChange={setOpenIA}>
|
||||
<DrawerContent className="fixed inset-x-0 bottom-0 mx-auto mb-4 flex h-[80vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl border bg-white shadow-2xl">
|
||||
{/* Cabecera más compacta */}
|
||||
|
||||
Reference in New Issue
Block a user