feat: Fix typing indicator and add New Conversation button

- Fixed typing indicator to use correct AI SDK status values (submitted/streaming)
- Added "New Conversation" button to clear chat and start fresh
- Updated all loading states to use status instead of undefined isLoading
- Disabled input and send button while AI is responding

The typing indicator now properly shows "AI Thinking..." while waiting for
responses, and the New Conversation button allows users to reset the chat.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-09 05:00:55 +00:00
parent 4571a6f1cc
commit 7dd917b2be

View File

@@ -12,6 +12,8 @@ import {
Group,
Text,
Loader,
ActionIcon,
Tooltip,
} from '@mantine/core';
import { useRef, useState, useEffect } from 'react';
import { MicrophoneRecorder } from '@/components/MicrophoneRecorder';
@@ -20,7 +22,7 @@ export default function ChatPage() {
const viewport = useRef<HTMLDivElement>(null);
const [input, setInput] = useState('');
const { messages, sendMessage, isLoading, setMessages } = useChat({
const { messages, sendMessage, setMessages, status } = useChat({
api: '/api/chat',
body: {
persona: 'Socratic',
@@ -56,17 +58,44 @@ export default function ChatPage() {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!input.trim() || isLoading) return;
if (!input.trim() || status === 'submitted' || status === 'streaming') return;
sendMessage({ text: input });
setInput('');
};
const handleNewConversation = () => {
// Clear all messages and reset to initial greeting
setMessages([
{
id: 'initial-greeting',
role: 'assistant',
parts: [
{
type: 'text',
text: 'Welcome to Ponderants! I\'m here to help you explore and structure your ideas through conversation.\n\nWhat would you like to talk about today? I can adapt my interview style to best suit your needs (Socratic questioning, collaborative brainstorming, or other approaches).\n\nJust start sharing your thoughts, and we\'ll discover meaningful insights together.',
},
],
},
]);
};
return (
<Container size="md" h="100vh" style={{ display: 'flex', flexDirection: 'column' }}>
<Title order={2} py="md">
Ponderants Interview
</Title>
<Group justify="space-between" py="md">
<Title order={2}>
Ponderants Interview
</Title>
<Tooltip label="Start a new conversation">
<Button
variant="subtle"
onClick={handleNewConversation}
disabled={status === 'submitted' || status === 'streaming'}
>
New Conversation
</Button>
</Tooltip>
</Group>
<ScrollArea
h="100%"
@@ -128,7 +157,7 @@ export default function ChatPage() {
))}
{/* Typing indicator while AI is generating a response */}
{isLoading && (
{(status === 'submitted' || status === 'streaming') && (
<Paper
withBorder
shadow="md"
@@ -165,7 +194,7 @@ export default function ChatPage() {
},
}}
variant="unstyled"
disabled={isLoading}
disabled={status === 'submitted' || status === 'streaming'}
/>
{/* Microphone Recorder */}
@@ -184,7 +213,11 @@ export default function ChatPage() {
}}
/>
<Button type="submit" radius="xl" loading={isLoading}>
<Button
type="submit"
radius="xl"
loading={status === 'submitted' || status === 'streaming'}
>
Send
</Button>
</Group>