Spaces:
Sleeping
Sleeping
| import React, { useState } from 'react'; | |
| import { useChat } from 'ai/react'; | |
| import { MessageCircle, X, Send, Loader2, Bot } from 'lucide-react'; | |
| export default function ChatWidget() { | |
| const [isOpen, setIsOpen] = useState(false); | |
| // Ссылка берется из настроек Space или .env файла | |
| const apiEndpoint = "https://levinaleksey-chat-b.hf.space/api/chat"; | |
| const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({ | |
| api: apiEndpoint, | |
| }); | |
| return ( | |
| <div className="fixed bottom-6 right-6 z-50 font-sans"> | |
| {isOpen && ( | |
| <div className="mb-4 w-[380px] h-[550px] bg-white rounded-3xl shadow-[0_20px_50px_rgba(0,0,0,0.15)] border border-slate-100 flex flex-col overflow-hidden animate-in fade-in zoom-in duration-200"> | |
| <div className="bg-slate-900 p-5 text-white flex items-center justify-between"> | |
| <div className="flex items-center gap-3"> | |
| <div className="bg-blue-600 p-2 rounded-xl"><Bot size={20} /></div> | |
| <div> | |
| <p className="font-semibold text-sm">Inventory AI</p> | |
| <p className="text-[10px] text-slate-400">Gemini 1.5 Flash Online</p> | |
| </div> | |
| </div> | |
| <button onClick={() => setIsOpen(false)} className="opacity-50 hover:opacity-100"><X size={20} /></button> | |
| </div> | |
| <div className="flex-1 overflow-y-auto p-4 space-y-4 bg-slate-50"> | |
| {messages.map((m) => ( | |
| <div key={m.id} className={`flex ${m.role === 'user' ? 'justify-end' : 'justify-start'}`}> | |
| <div className={`max-w-[85%] px-4 py-2 rounded-2xl text-sm ${ | |
| m.role === 'user' ? 'bg-blue-600 text-white' : 'bg-white border border-slate-200 text-slate-800' | |
| }`}> | |
| {m.content} | |
| </div> | |
| </div> | |
| ))} | |
| {isLoading && <Loader2 className="animate-spin text-blue-600 mx-auto" size={20} />} | |
| </div> | |
| <form onSubmit={handleSubmit} className="p-4 bg-white border-t border-slate-100 flex gap-2"> | |
| <input | |
| className="flex-1 bg-slate-100 rounded-xl px-4 py-2 text-sm outline-none focus:ring-2 focus:ring-blue-500" | |
| value={input} | |
| placeholder="Спросите об оборудовании..." | |
| onChange={handleInputChange} | |
| /> | |
| <button type="submit" className="bg-slate-900 text-white p-2 rounded-xl"><Send size={18} /></button> | |
| </form> | |
| </div> | |
| )} | |
| <button | |
| onClick={() => setIsOpen(!isOpen)} | |
| className="bg-slate-900 text-white w-16 h-16 rounded-full shadow-2xl flex items-center justify-center hover:scale-105 transition-transform" | |
| > | |
| {isOpen ? <X size={28} /> : <MessageCircle size={28} />} | |
| </button> | |
| </div> | |
| ); | |
| } |