diff --git a/components/chat-input.tsx b/components/chat-input.tsx index a164db9..8ff108d 100644 --- a/components/chat-input.tsx +++ b/components/chat-input.tsx @@ -1,19 +1,26 @@ -"use client" +"use client"; -import React, { useCallback, useRef, useEffect } from "react" -import { Button } from "@/components/ui/button" -import { Textarea } from "@/components/ui/textarea" -import { Loader2, Send, Trash, Image as ImageIcon, X } from "lucide-react" -import Image from "next/image" +import React, { useCallback, useRef, useEffect } from "react"; +import { Button } from "@/components/ui/button"; +import { Textarea } from "@/components/ui/textarea"; +import { Loader2, Send, RotateCcw, Image as ImageIcon, X } from "lucide-react"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import Image from "next/image"; interface ChatInputProps { - input: string - status: "submitted" | "streaming" | "ready" | "error" - onSubmit: (e: React.FormEvent) => void - onChange: (e: React.ChangeEvent) => void - setMessages: (messages: any[]) => void - files?: FileList - onFileChange?: (files: FileList | undefined) => void + input: string; + status: "submitted" | "streaming" | "ready" | "error"; + onSubmit: (e: React.FormEvent) => void; + onChange: (e: React.ChangeEvent) => void; + setMessages: (messages: any[]) => void; + onDisplayChart: (xml: string) => void; + files?: FileList; + onFileChange?: (files: FileList | undefined) => void; } export function ChatInput({ @@ -22,57 +29,58 @@ export function ChatInput({ onSubmit, onChange, setMessages, + onDisplayChart, files, - onFileChange + onFileChange, }: ChatInputProps) { - const textareaRef = useRef(null) - const fileInputRef = useRef(null) + const textareaRef = useRef(null); + const fileInputRef = useRef(null); // Auto-resize textarea based on content const adjustTextareaHeight = useCallback(() => { - const textarea = textareaRef.current + const textarea = textareaRef.current; if (textarea) { - textarea.style.height = "auto" - textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px` + textarea.style.height = "auto"; + textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`; } - }, []) + }, []); useEffect(() => { - adjustTextareaHeight() - }, [input, adjustTextareaHeight]) + adjustTextareaHeight(); + }, [input, adjustTextareaHeight]); // Handle keyboard shortcuts const handleKeyDown = (e: React.KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === "Enter") { - e.preventDefault() - const form = e.currentTarget.closest("form") + e.preventDefault(); + const form = e.currentTarget.closest("form"); if (form && input.trim() && status !== "streaming") { - form.requestSubmit() + form.requestSubmit(); } } - } + }; // Handle file changes const handleFileChange = (e: React.ChangeEvent) => { if (onFileChange) { - onFileChange(e.target.files || undefined) + onFileChange(e.target.files || undefined); } - } + }; // Clear file selection const clearFiles = () => { if (fileInputRef.current) { - fileInputRef.current.value = '' + fileInputRef.current.value = ""; } if (onFileChange) { - onFileChange(undefined) + onFileChange(undefined); } - } + }; // Trigger file input click const triggerFileInput = () => { - fileInputRef.current?.click() - } + fileInputRef.current?.click(); + }; return (
@@ -82,7 +90,7 @@ export function ChatInput({ {Array.from(files).map((file, index) => (
- {file.type.startsWith('image/') ? ( + {file.type.startsWith("image/") ? ( {file.name} -
+
+
+ + + + + + + Clear current conversation and diagram + + + +
- -
- ) + ); } diff --git a/components/chatPanel.tsx b/components/chatPanel.tsx index 202e306..1388de0 100644 --- a/components/chatPanel.tsx +++ b/components/chatPanel.tsx @@ -225,6 +225,7 @@ export default function ChatPanel({ onDisplayChart, onFetchChart }: ChatPanelPro onSubmit={onFormSubmit} onChange={handleInputChange} setMessages={setMessages} + onDisplayChart={onDisplayChart} files={files} onFileChange={handleFileChange} />