sameerbanchhor's picture
Upload folder using huggingface_hub
befc75a verified
"use client";
import { useState } from 'react';
import Image from 'next/image';
import { useToast } from "@/hooks/use-toast";
import { generateChatbotResponse } from '@/ai/flows/generate-chatbot-response';
import type { Message } from '@/lib/types';
import MessageList from './message-list';
import MessageForm from './message-form';
import { ThemeToggle } from './theme-toggle';
import { Bot, X } from 'lucide-react';
import { Button } from './ui/button';
export function Chat() {
const [messages, setMessages] = useState<Message[]>([
{
id: '1',
role: 'assistant',
content: "जय जोहार! मैं चत्तीसवाणी हावंव। आप मन के का मदद कर सकत हंव?",
},
]);
const [input, setInput] = useState('');
const [file, setFile] = useState<File | null>(null);
const [isLoading, setIsLoading] = useState(false);
const { toast } = useToast();
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files?.[0]) {
setFile(e.target.files[0]);
}
};
const handleRemoveFile = () => {
setFile(null);
}
const fileToDataUri = (file: File): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});
const handleSendMessage = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if ((!input.trim() && !file) || isLoading) return;
setIsLoading(true);
let fileDataUri: string | undefined = undefined;
let previewUrl: string | undefined = undefined;
if (file) {
previewUrl = URL.createObjectURL(file);
fileDataUri = await fileToDataUri(file);
}
const userMessage: Message = {
id: Date.now().toString(),
role: 'user',
content: input,
imageUrl: previewUrl,
};
setMessages((prev) => [...prev, userMessage]);
const currentInput = input;
setInput('');
setFile(null);
try {
const chatHistory = [...messages, userMessage].map(({ role, content }) => ({ role, content }));
const response = await generateChatbotResponse({
message: currentInput,
chatHistory,
photoDataUri: fileDataUri
});
const assistantMessage: Message = {
id: (Date.now() + 1).toString(),
role: 'assistant',
content: response.response,
};
setMessages((prev) => [...prev, assistantMessage]);
} catch (error) {
console.error("Error generating chatbot response:", error);
toast({
variant: "destructive",
title: "Oh no! Something went wrong.",
description: "There was a problem with our AI. Please try again later.",
});
const errorMessage: Message = {
id: (Date.now() + 1).toString(),
role: 'assistant',
content: "Sorry, I'm having a little trouble right now. Please try again in a moment.",
};
setMessages((prev) => [...prev, errorMessage]);
} finally {
setIsLoading(false);
// Clean up the object URL
if (previewUrl) {
URL.revokeObjectURL(previewUrl);
}
}
};
return (
<div className="flex h-screen w-full flex-col">
<header className="flex h-16 shrink-0 items-center justify-between border-b bg-background px-4">
<div className="flex items-center gap-2">
<Bot className="h-6 w-6 text-primary" />
<h1 className="text-lg font-semibold">ChhattisVani</h1>
<span className="text-xs text-muted-foreground">29.05.02 beta</span>
</div>
<ThemeToggle />
</header>
<div className="flex-1 overflow-hidden">
<MessageList messages={messages} isLoading={isLoading} />
</div>
<div className="w-full max-w-3xl mx-auto p-4 shrink-0">
{file && (
<div className="mb-2 p-2 border rounded-lg bg-muted flex items-center justify-between animate-slide-in-fade-in">
<div className="flex items-center gap-3">
<Image src={URL.createObjectURL(file)} alt="File preview" width={40} height={40} className="rounded object-cover" />
<span className="text-sm font-medium truncate max-w-xs">{file.name}</span>
</div>
<Button variant="ghost" size="icon" onClick={handleRemoveFile} className="h-7 w-7 shrink-0">
<X className="h-4 w-4" />
</Button>
</div>
)}
<MessageForm
input={input}
setInput={setInput}
handleSendMessage={handleSendMessage}
isLoading={isLoading}
handleFileChange={handleFileChange}
isFileSelected={!!file}
/>
<p className="text-xs text-center text-muted-foreground pt-2">
created with ❤️ by sameer banchhor
</p>
</div>
</div>
);
}