frontendrepo

This commit is contained in:
ahmed531998 2023-03-30 15:15:54 +02:00
commit 0240b5d8a8
13 changed files with 27832 additions and 0 deletions

14
Dockerfile Normal file
View File

@ -0,0 +1,14 @@
FROM node:16-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
# required for docker desktop port mapping
CMD ["npm", "start"]

27146
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

38
package.json Normal file
View File

@ -0,0 +1,38 @@
{
"name": "myblog",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

11
public/index.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Janet Chat</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

24
src/ChatBox.js Normal file
View File

@ -0,0 +1,24 @@
import React, { useState } from "react";
import "./style.css";
import ChatBoxProps from "./ChatBoxProps.js";
import ChatButton from "./ChatButton.js";
const ChatBox = (props) => {
const { updateNeedForm, messages, updateMessages } = props.props;
const [visible, setVisible] = useState(false);
return (
<div className="container">
<div className="chatbox">
<ChatBoxProps
props={{ visible, updateNeedForm, messages, updateMessages }}
/>
<ChatButton onClick={() => setVisible(!visible)} />
</div>
</div>
);
};
export default ChatBox;

106
src/ChatBoxProps.js Normal file
View File

@ -0,0 +1,106 @@
import React, { useState } from "react";
import "./style.css";
import ChatBoxMessages from "./ChatMessages.js";
const ChatBoxProps = (props) => {
const { visible, updateNeedForm, messages, updateMessages } = props.props;
const [inputValue, setInputValue] = useState("");
const backendUrl = process.env.REACT_APP_BACKEND_URL;
function handleKeyDown(event) {
if (event.key === "Enter") {
onSend(inputValue);
}
}
function onSend(text) {
if (inputValue === "") {
return;
}
let msg1 = { name: "User", message: inputValue };
updateMessages(msg1);
//setMessages((prevMessages) => [msg1, ...prevMessages]);
/*let msg2 = {
name: "Sam",
message: "response" + inputValue,
query: "query" + inputValue,
history: messages,
modQuery: inputValue
};*/
//let msg2 = { name: "Sam", message: inputValue};
//setMessages((prevMessages) => [msg2, ...prevMessages]);
//updateMessages(msg2)
//setInputValue("");
//updateNeedForm(true);
//setMessages([msg2, ...messages]);
fetch(backendUrl + '/predict', {
method: 'POST',
body: JSON.stringify({ message: inputValue }),
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
})
.then(r => r.json())
.then(r => {
let msg2 = { name: "Sam", message: r.answer, query: r.query, cand: r.cand, history: r.history, modQuery: r.modQuery};
//setMessages((prevMessages) => [msg2, ...prevMessages]);
updateMessages(msg2);
setInputValue("");
updateNeedForm(true);
setInputValue("");
}).catch((error) => {
console.error('Error:', error);
setInputValue("");
});
}
function handleInputChange(event) {
setInputValue(event.target.value);
}
return (
<div
className="chatbox__support"
style={{
...{ opacity: visible ? "1" : "0" },
...{ zIndex: visible ? "123456" : "-123456" },
...{
transform: visible ? "translateY(-40px)" : "translateY(0px)"
}
}}
>
<div className="chatbox__header">
<div className="chatbox__image--header">
<img
src="https://img.icons8.com/color/48/000000/circled-user-female-skin-type-5--v1.png"
alt=""
/>
</div>
<div className="chatbox__content--header">
<h4 className="chatbox__heading--header">Janet</h4>
<p className="chatbox__description--header">
Hi, it's Janet. I am here to help you in utilizing the VRE.
</p>
</div>
</div>
<ChatBoxMessages messages={messages} />
<div className="chatbox__footer">
<input
type="text"
placeholder="Write a message..."
value={inputValue}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
/>
<button className="chatbox__send--footer send__button" onClick={onSend}>
Send
</button>
</div>
</div>
);
};
export default ChatBoxProps;

16
src/ChatButton.js Normal file
View File

@ -0,0 +1,16 @@
import React from "react";
import img from "./images/chatbox-icon.svg";
import "./style.css";
const ChatButton = (props) => {
return (
<div className="ChatButton">
<button onClick={() => props.onClick && props.onClick()}>
<img alt="" src={img} />
</button>
</div>
);
};
export default ChatButton;

24
src/ChatMessages.js Normal file
View File

@ -0,0 +1,24 @@
import React from "react";
import "./style.css";
const ChatBoxMessages = (props) => {
return (
<div className="chatbox__messages">
{props.messages.map((item, index) => (
<div
key={index}
className={`messages__item ${
item.name === "Sam"
? "messages__item--visitor"
: "messages__item--operator"
}`}
>
{item.message}
</div>
))}
</div>
);
};
export default ChatBoxMessages;

25
src/ChatPage.js Normal file
View File

@ -0,0 +1,25 @@
import React, { useState } from "react";
import "./style.css";
import ChatBox from "./ChatBox.js";
import FeedbackForm from "./FeedbackForm.js";
const ChatPage = () => {
const [needForm, setNeedForm] = useState(false);
const [messages, setMessages] = useState([]);
function updateNeedForm(value) {
setNeedForm(value);
}
function updateMessages(msg) {
setMessages((prevMessages) => [msg, ...prevMessages]);
}
return (
<div>
<ChatBox props={{ updateNeedForm, messages, updateMessages }} />
{ needForm && <FeedbackForm props={{ updateNeedForm, messages }} /> }
</div>
);
};
export default ChatPage;

184
src/FeedbackForm.js Normal file
View File

@ -0,0 +1,184 @@
import React, { useState } from "react";
import "./style.css";
const FeedbackForm = (props) => {
const { updateNeedForm, messages } = props.props;
const [responseLength, setResponseLength] = useState("short");
const [responseFluency, setResponseFluency] = useState("basic");
const [responseTruthfulness, setResponseTruthfulness] = useState("NA");
const [responseUsefulness, setResponseUsefulness] = useState("no");
const [responseTime, setResponseTime] = useState("slow");
const [intent, setIntent] = useState("QA");
const [modQueryCorrectness, setModQueryCorrectness] = useState("no");
const [modQuery, setModQuery] = useState("");
const [response, setResponse] = useState("");
const backendUrl = process.env.REACT_APP_BACKEND_URL;
function onSubmit(event) {
event.preventDefault();
var ratings = {};
ratings["query"] = messages[0].query;
ratings["history"] = messages[0].history;
ratings["modQuery"] = messages[0].modQuery;
ratings["queryModCorrect"] = modQueryCorrectness;
if (modQueryCorrectness === "yes") {
ratings["correctQuery"] = messages[0].modQuery;
} else {
ratings["correctQuery"] = modQuery;
}
ratings["janetResponse"] = messages[0].message;
ratings["preferredResponse"] = response;
ratings["length"] = responseLength;
ratings["fluency"] = responseFluency;
ratings["truthfulness"] = responseTruthfulness;
ratings["usefulness"] = responseUsefulness;
ratings["speed"] = responseTime;
ratings["intent"] = intent;
fetch(backendUrl + '/feedback', {
method: 'POST',
body: JSON.stringify({ feedback: ratings }),
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
}).then(r => r.json())
.catch(error => console.error(error));
console.log(ratings);
updateNeedForm(false);
}
return (
<div id="feedback-window" class="feedback-box">
<form id="feedback-form">
<div class="feedback-question">
<label for="response-length">
What do you think of the length of the response?
</label>
<select
id="response-length"
name="What do you think of the length of the response?"
onChange={(e) => setResponseLength(e.target.value)}
>
<option value="short">short</option>
<option value="right">right</option>
<option value="long">long</option>
</select>
</div>
<div class="feedback-question">
<label for="response-fluency">
How would you rate the fluency of the response?
</label>
<select
id="response-fluency"
name="How would you rate the fluency of the response?"
onChange={(e) => setResponseFluency(e.target.value)}
>
<option value="basic">basic</option>
<option value="intermediate">intermediate</option>
<option value="fluent">fluent</option>
</select>
</div>
<div class="feedback-question">
<label for="response-truthfulness">
If applicable, was the response true?
</label>
<select
id="response-truthfulness"
name="If applicable, was the response true?"
onChange={(e) => setResponseTruthfulness(e.target.value)}
>
<option value="yes">yes</option>
<option value="no">no</option>
<option value="NA">NA</option>
</select>
</div>
<div class="feedback-question">
<label for="response-usefulness">
Was your need satisfied by this response?
</label>
<select
id="response-usefulness"
name="Was your need satisfied by this response?"
onChange={(e) => setResponseUsefulness(e.target.value)}
>
<option value="yes">yes</option>
<option value="no">no</option>
</select>
</div>
<div class="feedback-question">
<label for="response-time">
How fast was it to produce the response?
</label>
<select
id="response-time"
name="How fast was it to produce the response?"
onChange={(e) => setResponseTime(e.target.value)}
>
<option value="fast">fast</option>
<option value="slow">slow</option>
<option value="acceptable">acceptable</option>
</select>
</div>
<div class="feedback-question">
<label for="query-intent">What was your intent?</label>
<select
id="query-intent"
name="What was your intent?"
onChange={(e) => setIntent(e.target.value)}
>
<option value="QA">QA</option>
<option value="CHITCHAT">CHITCHAT</option>
<option value="FINDPAPER">FINDPAPER</option>
<option value="FINDDATASET">FINDDATASET</option>
<option value="SUMMARIZEPAPER">SUMMARIZEPAPER</option>
<option value="AFFIRMATION">AFFIRMATION</option>
<option value="NEGATION">NEGATION</option>
<option value="NA">NA</option>
</select>
</div>
<div class="feedback-question">
<label for="query-correctness">
Was this modification to the query correct? {messages[0].modQuery}
</label>
<select
id="query-correctness"
name=" Was this modification to the query correct?"
onChange={(e) => setModQueryCorrectness(e.target.value)}
>
<option value="yes">yes</option>
<option value="no">no</option>
</select>
</div>
<label for="correct-query">
Could you provide a modified context-free
(chat-history-independent) version of your query?
</label>
<textarea
id="correct-query"
name="Could you provide a modified context-free (chat-history-independent) version of your query?"
onChange={(e) => setModQuery(e.target.value)}
></textarea>
'
<div class="feedback-question">
<label for="preferred response">
Would you write a better response?
</label>
<textarea
id="preferred response"
name="Would you write a better response?"
onChange={(e) => setResponse(e.target.value)}
></textarea>
'
</div>
<div class="feedback-submit">
<input type="submit" value="Submit" onClick={onSubmit} />
</div>
</form>
</div>
);
};
export default FeedbackForm;

View File

@ -0,0 +1,3 @@
<svg width="36" height="29" viewBox="0 0 36 29" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28.2857 10.5714C28.2857 4.88616 21.9576 0.285714 14.1429 0.285714C6.32813 0.285714 0 4.88616 0 10.5714C0 13.8259 2.08929 16.7388 5.34375 18.6272C4.66071 20.2946 3.77679 21.0781 2.9933 21.9621C2.77232 22.2232 2.51116 22.4643 2.59152 22.846C2.65179 23.1875 2.93304 23.4286 3.23438 23.4286C3.25446 23.4286 3.27455 23.4286 3.29464 23.4286C3.89732 23.3482 4.47991 23.2478 5.02232 23.1071C7.05134 22.5848 8.93973 21.721 10.6071 20.5357C11.7321 20.7366 12.9174 20.8571 14.1429 20.8571C21.9576 20.8571 28.2857 16.2567 28.2857 10.5714ZM36 15.7143C36 12.3594 33.7902 9.38616 30.3951 7.51786C30.6964 8.50223 30.8571 9.52679 30.8571 10.5714C30.8571 14.1674 29.0089 17.4821 25.654 19.933C22.5402 22.183 18.4621 23.4286 14.1429 23.4286C13.5603 23.4286 12.9576 23.3884 12.375 23.3482C14.8862 24.9955 18.221 26 21.8571 26C23.0826 26 24.2679 25.8795 25.3929 25.6786C27.0603 26.8638 28.9487 27.7277 30.9777 28.25C31.5201 28.3906 32.1027 28.4911 32.7054 28.5714C33.0268 28.6116 33.3281 28.3504 33.4085 27.9888C33.4888 27.6071 33.2277 27.3661 33.0067 27.1049C32.2232 26.221 31.3393 25.4375 30.6563 23.7701C33.9107 21.8817 36 18.9888 36 15.7143Z" fill="#581B98"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

13
src/index.js Normal file
View File

@ -0,0 +1,13 @@
import React from "react";
import ReactDOM from "react-dom";
import "./style.css";
import ChatPage from "./ChatPage.js";
ReactDOM.render(
<React.StrictMode>
<ChatPage />
</React.StrictMode>,
document.getElementById("root")
);

228
src/style.css Normal file
View File

@ -0,0 +1,228 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "Nunito", sans-serif;
font-weight: 400;
font-size: 100%;
background: #f1f1f1;
}
*,
html {
--primaryGradient: linear-gradient(93.12deg, #581b98 0.52%, #9c1de7 100%);
--secondaryGradient: linear-gradient(
268.91deg,
#581b98 -2.14%,
#9c1de7 99.69%
);
--primaryBoxShadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
--secondaryBoxShadow: 0px -10px 15px rgba(0, 0, 0, 0.1);
--primary: #581b98;
}
.feedback-box {
position: absolute;
bottom: 0;
left: 0;
z-index: 9999;
width: 400px;
height: 400px;
padding: 10px;
border: 1px solid black;
overflow-y: scroll;
background-color: #fff;
overflow: auto;
}
.feedback-box label,
.feedback-box textarea,
.feedback-box select {
display: block;
margin-bottom: 10px;
}
.feedback-question {
margin-bottom: 10px;
}
.feedback-box textarea {
width: 100%;
}
.feedback-submit {
text-align: right;
}
/* CHATBOX
=============== */
.chatbox {
position: absolute;
bottom: 30px;
right: 30px;
}
/* CONTENT IS CLOSE */
.chatbox__support {
display: flex;
flex-direction: column;
background: #eee;
width: 300px;
height: 350px;
transition: all 0.5s ease-in-out;
}
/* BUTTON */
.ChatButton {
text-align: right;
}
.send__button {
padding: 6px;
background: transparent;
border: none;
outline: none;
cursor: pointer;
}
/* HEADER */
.chatbox__header {
position: sticky;
top: 0;
background: orange;
}
/* MESSAGES */
.chatbox__messages {
margin-top: auto;
display: flex;
overflow-y: scroll;
flex-direction: column-reverse;
}
.messages__item {
background: orange;
max-width: 60.6%;
width: fit-content;
}
.messages__item--operator {
margin-left: auto;
}
.messages__item--visitor {
margin-right: auto;
}
/* FOOTER */
.chatbox__footer {
position: sticky;
bottom: 0;
}
.chatbox__support {
background: #f9f9f9;
height: 450px;
width: 350px;
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1);
border-top-left-radius: 20px;
border-top-right-radius: 20px;
}
/* HEADER */
.chatbox__header {
background: var(--primaryGradient);
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 15px 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
box-shadow: var(--primaryBoxShadow);
}
.chatbox__image--header {
margin-right: 10px;
}
.chatbox__heading--header {
font-size: 1.2rem;
color: white;
}
.chatbox__description--header {
font-size: 0.9rem;
color: white;
}
/* Messages */
.chatbox__messages {
padding: 0 20px;
}
.messages__item {
margin-top: 10px;
background: #e0e0e0;
padding: 8px 12px;
max-width: 70%;
}
.messages__item--visitor,
.messages__item--typing {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
.messages__item--operator {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
background: var(--primary);
color: white;
}
/* FOOTER */
.chatbox__footer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 20px 20px;
background: var(--secondaryGradient);
box-shadow: var(--secondaryBoxShadow);
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
margin-top: 20px;
}
.chatbox__footer input {
width: 80%;
border: none;
padding: 10px 10px;
border-radius: 30px;
text-align: left;
}
.chatbox__send--footer {
color: white;
}
.ChatButton button,
.ChatButton button:focus,
.ChatButton button:visited {
padding: 10px;
background: white;
border: none;
outline: none;
border-top-left-radius: 50px;
border-top-right-radius: 50px;
border-bottom-left-radius: 50px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
cursor: pointer;
}