frontendrepo
This commit is contained in:
commit
0240b5d8a8
|
@ -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"]
|
File diff suppressed because it is too large
Load Diff
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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 |
|
@ -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")
|
||||
);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue