@@ -10,7 +10,12 @@ import {
1010 TooltipProvider ,
1111 TooltipTrigger ,
1212} from "@/components/ui/tooltip"
13- import { CircleHelp } from 'lucide-react'
13+ import {
14+ Collapsible ,
15+ CollapsibleContent ,
16+ CollapsibleTrigger ,
17+ } from "@/components/ui/collapsible"
18+ import { CircleHelp , ChevronDown } from 'lucide-react'
1419import { cn } from '@/lib/utils' ;
1520
1621function ChatContent ( ) {
@@ -19,8 +24,8 @@ function ChatContent() {
1924 const [ aiKey , setAiKey ] = useQueryState ( 'ai_key' ) ;
2025
2126 return (
22- < >
23- < div className = "flex w-full max-w-sm items-center space-x-2" >
27+ < div className = "flex flex-col h-[calc(100vh-65px)]" >
28+ < div className = "flex items-center space-x-2 p-4 " >
2429 < Input type = "password" placeholder = "Anthropic API key" value = { aiKey ?? '' } onChange = { ( e ) => setAiKey ( e . target . value ) } />
2530 < TooltipProvider >
2631 < Tooltip >
@@ -32,38 +37,64 @@ function ChatContent() {
3237 </ TooltipProvider >
3338 </ div >
3439
35- < div className = "flex flex-col w-full max-w-md py-24 mx-auto stretch " >
40+ < div className = "flex-1 min-h-0 overflow-y-auto p-4 space-y-4 " >
3641 { messages . map ( m => (
37- < div key = { m . id } className = "whitespace-pre-wrap" >
38- { m . role === 'user' ? 'User: ' : 'AI: ' }
39- { m . toolInvocations ? (
40- < pre > { JSON . stringify ( m . toolInvocations , null , 2 ) } </ pre >
41- ) : (
42- < p > { m . content } </ p >
43- ) }
42+ < div key = { m . id } className = { cn (
43+ "flex" ,
44+ m . role === 'user' ? "justify-end" : "justify-start"
45+ ) } >
46+ < div className = { cn (
47+ "max-w-[80%] rounded-lg px-4 py-2 whitespace-pre-wrap" ,
48+ m . role === 'user'
49+ ? "bg-primary text-primary-foreground"
50+ : "bg-muted"
51+ ) } >
52+ { m . toolInvocations ? (
53+ < >
54+ < p className = "mb-2" > { m . content } </ p >
55+ < Collapsible >
56+ < CollapsibleTrigger className = "flex items-center text-sm text-muted-foreground hover:text-foreground" >
57+ < ChevronDown className = "h-4 w-4" />
58+ < span > View Tool Invocations</ span >
59+ </ CollapsibleTrigger >
60+ < CollapsibleContent >
61+ < pre className = "mt-2 p-2 text-sm bg-background rounded" > { JSON . stringify ( m . toolInvocations , null , 2 ) } </ pre >
62+ </ CollapsibleContent >
63+ </ Collapsible >
64+ </ >
65+ ) : (
66+ < p > { m . content } </ p >
67+ ) }
68+ </ div >
4469 </ div >
4570 ) ) }
71+ </ div >
4672
73+ < div className = "sticky bottom-0 p-4 bg-background border-t" >
4774 < form onSubmit = { ( e ) => {
4875 handleSubmit ( e , { headers : { token : token ?? '' , ai_key : aiKey ?? '' } } ) ;
4976 } } >
5077 < input
51- className = { cn ( "fixed bottom-0 w-full max-w-md p-2 mb-8 border border-gray-300 rounded shadow-xl" , ! token || ! aiKey && 'opacity-50 cursor-not-allowed' ) }
78+ className = { cn (
79+ "w-full p-2 rounded-md border shadow-sm" ,
80+ "focus:outline-none focus:ring-2 focus:ring-primary" ,
81+ ! token || ! aiKey && "opacity-50 cursor-not-allowed"
82+ ) }
5283 value = { input }
5384 placeholder = { aiKey ? 'Ask about your data' : "Anthropic API key is required" }
5485 onChange = { handleInputChange }
5586 disabled = { ! token || ! aiKey }
5687 />
5788 </ form >
5889 </ div >
59- </ >
90+ </ div >
6091 ) ;
6192}
6293
6394export default function Chat ( ) {
6495 return (
6596 < Suspense fallback = {
66- < div className = "flex flex-col w- full max-w-md py-24 mx-auto stretch " >
97+ < div className = "flex h- full items-center justify-center " >
6798 < p > Loading chat...</ p >
6899 </ div >
69100 } >
0 commit comments