From 5a85a68fcdbfa01c5a6a7e274d183c6bbdfc67c3 Mon Sep 17 00:00:00 2001 From: Tetiana Mohorian Date: Tue, 20 May 2025 11:07:05 +0000 Subject: [PATCH] =?UTF-8?q?Nahr=C3=A1t=20soubory=20do=20=E2=80=9Ewebsite/f?= =?UTF-8?q?rontend/src/components=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/frontend/src/components/ChatInput.jsx | 67 ++++++++ .../frontend/src/components/ChatWindow.jsx | 16 ++ website/frontend/src/components/Footer.jsx | 20 +++ website/frontend/src/components/Header.jsx | 9 ++ website/frontend/src/components/Historia.jsx | 35 +++++ website/frontend/src/components/InfoBox.jsx | 148 ++++++++++++++++++ 6 files changed, 295 insertions(+) create mode 100644 website/frontend/src/components/ChatInput.jsx create mode 100644 website/frontend/src/components/ChatWindow.jsx create mode 100644 website/frontend/src/components/Footer.jsx create mode 100644 website/frontend/src/components/Header.jsx create mode 100644 website/frontend/src/components/Historia.jsx create mode 100644 website/frontend/src/components/InfoBox.jsx diff --git a/website/frontend/src/components/ChatInput.jsx b/website/frontend/src/components/ChatInput.jsx new file mode 100644 index 0000000..9c746a2 --- /dev/null +++ b/website/frontend/src/components/ChatInput.jsx @@ -0,0 +1,67 @@ +import React, { useState } from 'react'; +import { Send } from 'lucide-react'; + +const ChatInput = ({ onSubmit }) => { + const [input, setInput] = useState(''); + const [error, setError] = useState(''); + + const handleSubmit = async (e) => { + e.preventDefault(); + setError(""); // reset chyby + + if (input.trim()) { + try { + const response = await fetch("/api/predict", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ text: input }), + }); + + const data = await response.json(); + + if (!response.ok) { + setError(data.error || "Chyba pri analýze textu."); + return; + } + + if (onSubmit) { + onSubmit(input, data.prediction); + } + + setInput(''); + } catch (error) { + console.error("Chyba požiadavky:", error); + setError("Nepodarilo sa spojiť so serverom."); + } + } else { + setError("Text nesmie byť prázdny."); + } + }; + + return ( +
+
+ setInput(e.target.value)} + placeholder="Zadajte text na analýzu" + className="text-input" + /> + +
+ + {error && ( +
+ ⚠️ {error} +
+ )} +
+ ); +}; + +export default ChatInput; + + diff --git a/website/frontend/src/components/ChatWindow.jsx b/website/frontend/src/components/ChatWindow.jsx new file mode 100644 index 0000000..1bdd6c2 --- /dev/null +++ b/website/frontend/src/components/ChatWindow.jsx @@ -0,0 +1,16 @@ +import React from "react"; + + +const ChatWindow = ({ messages }) => { + return ( +
+ {messages.map((msg, index) => ( +
+ {msg.text} +
+ ))} +
+ ); +}; + +export default ChatWindow; diff --git a/website/frontend/src/components/Footer.jsx b/website/frontend/src/components/Footer.jsx new file mode 100644 index 0000000..ec17a0f --- /dev/null +++ b/website/frontend/src/components/Footer.jsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { FaTelegram, FaGooglePlay } from 'react-icons/fa'; + +const Footer = () => { + return ( + + ); +}; + +export default Footer; diff --git a/website/frontend/src/components/Header.jsx b/website/frontend/src/components/Header.jsx new file mode 100644 index 0000000..83606e7 --- /dev/null +++ b/website/frontend/src/components/Header.jsx @@ -0,0 +1,9 @@ +import React from 'react'; + +const Header = () => ( +
+

Detektor nenávistného jazyka

+
+); + +export default Header; diff --git a/website/frontend/src/components/Historia.jsx b/website/frontend/src/components/Historia.jsx new file mode 100644 index 0000000..a1a6be6 --- /dev/null +++ b/website/frontend/src/components/Historia.jsx @@ -0,0 +1,35 @@ +import React from 'react'; + +const Historia = ({ history }) => { + if (!history || history.length === 0) { + return

Zatiaľ žiadna história

; + } + + return ( +
+
+ + + {history.map((item, index) => ( + + + + + + ))} + +
{item.text} + + {item.prediction} + + {item.timestamp}
+
+
+ ); +}; + +export default Historia; diff --git a/website/frontend/src/components/InfoBox.jsx b/website/frontend/src/components/InfoBox.jsx new file mode 100644 index 0000000..e1b30c6 --- /dev/null +++ b/website/frontend/src/components/InfoBox.jsx @@ -0,0 +1,148 @@ +import React, { useState, useEffect } from 'react'; +import ChatInput from './ChatInput.jsx'; +import Historia from './Historia.jsx'; +import { ChevronDown, ChevronUp } from 'lucide-react'; + +const InfoBox = () => { + const [headerText, setHeaderText] = useState('Analyzujte text na nenávistný jazyk'); + const [paragraphText, setParagraphText] = useState('Tento nástroj využíva umelú inteligenciu na identifikáciu toxického obsahu v textoch. Stačí zadať text a zistiť, či obsahuje nenávistný jazyk.'); + const [history, setHistory] = useState([]); + const [showHistory, setShowHistory] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const fetchHistory = async () => { + try { + const response = await fetch("/api/history"); + const data = await response.json(); + setHistory(data); + } catch (err) { + console.error("Nepodarilo sa načítať históriu:", err); + } + }; + + const handleSendMessage = async (userMessage) => { + setHeaderText("Analyzujem text..."); + setParagraphText("Analyzujeme váš text, prosím čakajte..."); + setIsLoading(true); + const startTime = Date.now(); + + try { + const response = await fetch("/api/predict", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ text: userMessage }), + }); + const data = await response.json(); + const elapsed = Date.now() - startTime; + const minimumDelay = 5000; + + if (elapsed < minimumDelay) { + await new Promise(resolve => setTimeout(resolve, minimumDelay - elapsed)); + } + + if (response.ok) { + setHeaderText(data.prediction); + setParagraphText(`Váš text bol: "${userMessage}"`); + fetchHistory(); + } else { + console.error("Server vrátil chybu:", data.error); + } + } catch (error) { + console.error("Chyba pri odosielaní:", error); + } finally { + setIsLoading(false); + } + }; + + useEffect(() => { + fetchHistory(); + }, []); + + + return ( +
+

{isLoading ? 'Analyzujem text...' : headerText}

+

{isLoading ? 'Prosím čakajte, prebieha analýza.' : paragraphText}

+ +
+ + + {isLoading && ( +
+
+
+ )} + +
+ + + {showHistory && ( +
+
+
+ +
+
+
+ )} +
+
+
+ ); +}; + +export default InfoBox;