| import React, { useState, useRef } from 'react'; |
| import ChatMessage from './ChatMessage'; |
|
|
| export default function App() { |
| const [messages, setMessages] = useState([]); |
| const [input, setInput] = useState(''); |
| const [model, setModel] = useState('glm-5.1'); |
| const [isLoading, setIsLoading] = useState(false); |
| const messagesEndRef = useRef(null); |
|
|
| const handleSend = async () => { |
| if (!input.trim() || isLoading) return; |
|
|
| const userMessage = { role: 'user', content: input }; |
| const newMessages = [...messages, userMessage]; |
| setMessages(newMessages); |
| setInput(''); |
| setIsLoading(true); |
|
|
| |
| setMessages(prev => [...prev, { role: 'assistant', content: '', thinking: '' }]); |
|
|
| try { |
| const response = await fetch('/api/chat', { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify({ messages: newMessages, model }) |
| }); |
|
|
| const reader = response.body.getReader(); |
| const decoder = new TextDecoder(); |
| let fullText = ''; |
| let isThinking = false; |
| let currentThinking = ''; |
| let currentContent = ''; |
|
|
| while (true) { |
| const { done, value } = await reader.read(); |
| if (done) break; |
|
|
| const chunk = decoder.decode(value, { stream: true }); |
| |
| |
| fullText += chunk; |
|
|
| |
| if (fullText.includes("")) { |
| const parts = fullText.split(""); |
| currentThinking = parts[0].replace("", ""); |
| currentContent = parts[1] || ""; |
| } else { |
| currentContent = fullText; |
| } |
|
|
| |
| setMessages(prev => { |
| const updated = [...prev]; |
| updated[updated.length - 1] = { |
| role: 'assistant', |
| content: currentContent, |
| thinking: currentThinking |
| }; |
| return updated; |
| }); |
| } |
| } catch (error) { |
| console.error('Error:', error); |
| } finally { |
| setIsLoading(false); |
| } |
| }; |
|
|
| return ( |
| <div className="app-container"> |
| <div className="sidebar"> |
| <h1>AnesNT 🇩🇿</h1> |
| <h3>Genisi AI</h3> |
| <select value={model} onChange={(e) => setModel(e.target.value)}> |
| <option value="gemma-4-31b">Gemma 4 31B (Flash)</option> |
| <option value="glm-5.1">GLM 5.1 (Thinking)</option> |
| </select> |
| <button onClick={() => setMessages([])}>🗑️ مسح المحادثة</button> |
| </div> |
| |
| <div className="chat-area"> |
| <div className="chat-header"> |
| <h2>Genisi AI - {model === 'glm-5.1' ? 'مفكر' : 'سريع'}</h2> |
| </div> |
| |
| <div className="messages-container"> |
| {messages.map((msg, idx) => ( |
| <ChatMessage key={idx} message={msg} /> |
| ))} |
| <div ref={messagesEndRef} /> |
| </div> |
| |
| <div className="input-area"> |
| <input |
| type="text" |
| value={input} |
| onChange={(e) => setInput(e.target.value)} |
| onKeyDown={(e) => e.key === 'Enter' && handleSend()} |
| placeholder="اكتب رسالتك هنا..." |
| disabled={isLoading} |
| /> |
| <button onClick={handleSend} disabled={isLoading}>إرسال</button> |
| </div> |
| </div> |
| </div> |
| ); |
| } |