civicsetu / frontend /src /components /ChatThread.tsx
adeshboudh16
style: apply interaction polish and mobile spacing
cd7e224
'use client';
import { useEffect, useRef } from 'react';
import { MessageBubble } from '@/components/MessageBubble';
import type { ChatMessage } from '@/lib/types';
const EXAMPLE_QUERIES = [
'What are promoter obligations under RERA?',
'What penalty applies for delayed possession?',
'How does agent registration work under Maharashtra rules?',
'What is the complaint filing process for a buyer?',
] as const;
interface Props {
messages: ChatMessage[];
isLoading: boolean;
onExampleClick: (query: string) => void;
}
export function ChatThread({ messages, isLoading, onExampleClick }: Props) {
const bottomRef = useRef<HTMLDivElement>(null);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages, isLoading]);
if (messages.length === 0 && !isLoading) {
return (
<div className="ledger-scroll flex h-full flex-col justify-center overflow-y-auto px-4 py-8">
<div className="max-w-md">
<p className="font-mono text-[10px] uppercase tracking-[0.28em] text-white/25">Research desk</p>
<h2 className="mt-3 text-2xl font-semibold tracking-[-0.02em] text-white/84">
Ask the ledger a legal question.
</h2>
<p className="mt-3 text-sm leading-6 text-white/50">
Query Indian RERA provisions, compare jurisdictions, and route selected graph sections directly into the chat.
</p>
</div>
<div className="mt-8 grid gap-2">
{EXAMPLE_QUERIES.map(query => (
<button
key={query}
type="button"
onClick={() => onExampleClick(query)}
className="rounded-[10px] bg-[#1a1a1a] px-3.5 py-3 text-left text-[13px] leading-5 text-white/60 transition-[background-color,color,transform] duration-150 ease-out hover:bg-[#222222] hover:text-white/80 active:scale-[0.97]"
>
{query}
</button>
))}
</div>
</div>
);
}
return (
<div className="ledger-scroll flex h-full flex-col gap-6 overflow-y-auto p-4">
{messages.map(message => (
<MessageBubble key={message.id} message={message} />
))}
{isLoading ? (
<div className="flex gap-1.5 self-start p-2">
<span className="h-1.5 w-1.5 animate-pulse rounded-full bg-white/20" />
<span className="h-1.5 w-1.5 animate-pulse rounded-full bg-white/20 [animation-delay:200ms]" />
<span className="h-1.5 w-1.5 animate-pulse rounded-full bg-white/20 [animation-delay:400ms]" />
</div>
) : null}
<div ref={bottomRef} />
</div>
);
}