diff --git a/backend/email/email.js b/backend/email/email.js
index 5b70a030c..4eff7b09f 100644
--- a/backend/email/email.js
+++ b/backend/email/email.js
@@ -1,4 +1,16 @@
+const sentEmails = [];
+
+function clearEmails() {
+ sentEmails.length = 0;
+}
+
+function getSentEmails() {
+ return sentEmails;
+}
+
function sendEmail(email, subject, message) {
+ // add to the list of sent emails
+ sentEmails.push({ address: email, subject: subject, content: message });
response =
"Sending email to " +
email +
@@ -10,4 +22,4 @@ function sendEmail(email, subject, message) {
return response;
}
-module.exports = { sendEmail };
+module.exports = { clearEmails, getSentEmails, sendEmail };
diff --git a/backend/router.js b/backend/router.js
index 8da6edcfe..6dd33656e 100644
--- a/backend/router.js
+++ b/backend/router.js
@@ -1,5 +1,6 @@
// Importing express module
const express = require("express");
+const { clearEmails, getSentEmails } = require("./email/email");
const { chatGptSendMessage, clearMessages } = require("./openai/openai");
const router = express.Router();
@@ -8,6 +9,17 @@ router.get("/", (req, res, next) => {
res.send("Hello world");
});
+// Clear sent emails
+router.post("/email/clear", (req, res, next) => {
+ clearEmails();
+ res.send("Sent emails cleared");
+});
+
+// Get sent emails
+router.get("/email/get", (req, res, next) => {
+ res.send(getSentEmails());
+});
+
// Chat to ChatGPT
router.post("/openai/chat", async (req, res, next) => {
const message = req.body?.message;
diff --git a/frontend/src/App.css b/frontend/src/App.css
index 2e7dd7bfb..797a90135 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -1,4 +1,10 @@
#main-area {
+ display: flex;
+ flex-direction: row;
+ height: 100%;
+}
+
+#centre-area {
display: flex;
flex-direction: column;
border-width: 0px 1px;
@@ -6,7 +12,7 @@
border-color: #ccc;
position: relative;
height: 100%;
- width: 500px;
+ width: 40%;
margin: 0 auto;
text-align: center;
}
@@ -20,3 +26,19 @@ h1 {
height: 100%;
}
+.side-bar {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ width: 30%;
+}
+
+.side-bar-header {
+ border-color: #ccc;
+ border-width: 0 0 1px 0;
+ border-style: solid;
+ margin: 40px;
+ margin-bottom: 10px;
+ padding-bottom: 20px;
+ text-align: center;
+}
diff --git a/frontend/src/App.js b/frontend/src/App.js
index 87b04006b..9332b90fa 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -1,15 +1,27 @@
import "./App.css";
-import ChatBox from "./components/ChatBox";
+import ChatBox from "./components/ChatBox/ChatBox";
+import EmailBox from "./components/EmailBox/EmailBox";
import Header from "./components/Header";
+import { useState } from "react";
function App() {
+ const [emails, setEmails] = useState([]);
+
return (
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
export default App;
-
diff --git a/frontend/src/components/ChatBox.css b/frontend/src/components/ChatBox.css
deleted file mode 100644
index 47d589ff5..000000000
--- a/frontend/src/components/ChatBox.css
+++ /dev/null
@@ -1,23 +0,0 @@
-#chat-box {
- display: flex;
- flex-direction: column;
- flex-grow: 1;
-}
-
-#chat-box-input {
- align-self: flex-end;
- display: flex;
- justify-content: center;
- width: 100%;
- padding: 40px 0px;
-}
-
-#chat-box-input input {
- width: 85%;
- height: 40px;
- border: 1px solid #ccc;
- border-radius: 5px;
- padding: 0 20px;
- font-size: 16px;
- box-sizing: border-box;
-}
diff --git a/frontend/src/components/ChatBox.jsx b/frontend/src/components/ChatBox.jsx
deleted file mode 100644
index 44ed0d759..000000000
--- a/frontend/src/components/ChatBox.jsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import React, { useState } from "react";
-
-import "./ChatBox.css";
-import ChatBoxFeed from "./ChatBoxFeed";
-
-function ChatBox() {
- const [messages, setMessages] = useState([]);
-
- const onKeyUpValue = (event) => {
- if (event.key === "Enter") {
- // get the message
- const message = event.target.value;
- // add it to the list of messages
- setMessages((messages) => [...messages, { message, isUser: true }]);
- // clear the input
- event.target.value = "";
-
- // send the message to the backend
- fetch("http://localhost:3001/openai/chat", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ message }),
- }).then((response) => {
- // get the response message
- response.text().then((data) => {
- // add it to the list of messages
- setMessages((messages) => [
- ...messages,
- { message: data, isUser: false },
- ]);
- });
- });
- }
- };
-
- return (
-
- );
-}
-
-export default ChatBox;
diff --git a/frontend/src/components/ChatBox/ChatBox.css b/frontend/src/components/ChatBox/ChatBox.css
new file mode 100644
index 000000000..1b0256443
--- /dev/null
+++ b/frontend/src/components/ChatBox/ChatBox.css
@@ -0,0 +1,49 @@
+#chat-box {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+}
+
+#chat-box-footer {
+ align-items: center;
+ display: flex;
+ padding: 0 32px;
+}
+
+#chat-box-input {
+ align-self: flex-end;
+ display: flex;
+ justify-content: center;
+ width: 100%;
+ padding: 40px 0px;
+}
+
+#chat-box-input input {
+ width: 100%;
+ height: 40px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ padding: 0 12px;
+ font-size: 16px;
+ box-sizing: border-box;
+}
+
+#chat-box-button {
+ padding-left: 20px;
+}
+
+#chat-box-button button {
+ width: 100%;
+ height: 40px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ padding: 0 12px;
+ font-size: 16px;
+ box-sizing: border-box;
+ color: #666;
+}
+
+#chat-box-button button:hover {
+ background-color: #ccc;
+ color: #fff;
+}
diff --git a/frontend/src/components/ChatBox/ChatBox.jsx b/frontend/src/components/ChatBox/ChatBox.jsx
new file mode 100644
index 000000000..256395336
--- /dev/null
+++ b/frontend/src/components/ChatBox/ChatBox.jsx
@@ -0,0 +1,77 @@
+import React, { useEffect, useState } from "react";
+
+import "./ChatBox.css";
+import ChatBoxFeed from "./ChatBoxFeed";
+import {
+ clearOpenAiChat,
+ openAiSendMessage,
+} from "../../service/openaiService";
+import { getSentEmails } from "../../service/emailService";
+
+function ChatBox(props) {
+ const [messages, setMessages] = useState([]);
+
+ // called on mount
+ useEffect(() => {
+ // clear remote messages
+ clearOpenAiChat();
+ // get sent emails
+ getSentEmails().then((sentEmails) => {
+ props.setEmails(sentEmails);
+ });
+ }, []);
+
+ const clearClicked = () => {
+ // clear local messages
+ setMessages([]);
+ // clear remote messages
+ clearOpenAiChat();
+ };
+
+ const sendChatMessage = async (event) => {
+ if (event.key === "Enter") {
+ // get the message
+ const message = event.target.value;
+ // add it to the list of messages
+ setMessages((messages) => [
+ ...messages,
+ { message: message, isUser: true },
+ ]);
+ // clear the input
+ event.target.value = "";
+
+ const reply = await openAiSendMessage(message);
+ // add it to the list of messages
+ setMessages((messages) => [
+ ...messages,
+ { message: reply, isUser: false },
+ ]);
+
+ // get sent emails
+ const sentEmails = await getSentEmails();
+ // update emails
+ props.setEmails(sentEmails);
+ }
+ };
+
+ return (
+
+
+
+
+ );
+}
+
+export default ChatBox;
diff --git a/frontend/src/components/ChatBoxFeed.css b/frontend/src/components/ChatBox/ChatBoxFeed.css
similarity index 75%
rename from frontend/src/components/ChatBoxFeed.css
rename to frontend/src/components/ChatBox/ChatBoxFeed.css
index eeeebe429..d2ef15848 100644
--- a/frontend/src/components/ChatBoxFeed.css
+++ b/frontend/src/components/ChatBox/ChatBoxFeed.css
@@ -1,6 +1,6 @@
#chat-box-feed {
display: flex;
- flex-direction: column;
+ flex-direction: column-reverse;
flex-grow: 1;
height: 1px;
overflow: auto;
diff --git a/frontend/src/components/ChatBoxFeed.jsx b/frontend/src/components/ChatBox/ChatBoxFeed.jsx
similarity index 85%
rename from frontend/src/components/ChatBoxFeed.jsx
rename to frontend/src/components/ChatBox/ChatBoxFeed.jsx
index cedb99434..334a92520 100644
--- a/frontend/src/components/ChatBoxFeed.jsx
+++ b/frontend/src/components/ChatBox/ChatBoxFeed.jsx
@@ -4,7 +4,7 @@ import ChatBoxMessage from "./ChatBoxMessage";
function ChatBoxFeed(props) {
return (
- {props.messages.map((message, index) => {
+ {props.messages.toReversed().map((message, index) => {
return (
+ {props.emails.toReversed().map((email, index) => {
+ return (
+
+ );
+ })}
+
+ );
+}
+
+export default EmailBox;
diff --git a/frontend/src/components/EmailBox/SentEmail.css b/frontend/src/components/EmailBox/SentEmail.css
new file mode 100644
index 000000000..d94a0aaa5
--- /dev/null
+++ b/frontend/src/components/EmailBox/SentEmail.css
@@ -0,0 +1,15 @@
+.sent-email {
+ border-color: #ccc;
+ border-radius: 5px;
+ border-style: solid;
+ border-width: 1px;
+ font-size: 14px;
+ margin-top: 10px;
+ padding: 5px;
+}
+
+.sent-email-divider {
+ border-bottom: 1px solid #ccc;
+ margin: 5px 0;
+ width: 100%;
+}
diff --git a/frontend/src/components/EmailBox/SentEmail.jsx b/frontend/src/components/EmailBox/SentEmail.jsx
new file mode 100644
index 000000000..2d36746cf
--- /dev/null
+++ b/frontend/src/components/EmailBox/SentEmail.jsx
@@ -0,0 +1,14 @@
+import "./SentEmail.css";
+
+function SentEmail(props) {
+ return (
+
+
to: {props.address}
+
subject: {props.subject}
+
+
{props.content}
+
+ );
+}
+
+export default SentEmail;
diff --git a/frontend/src/service/emailService.js b/frontend/src/service/emailService.js
new file mode 100644
index 000000000..80a4d10b9
--- /dev/null
+++ b/frontend/src/service/emailService.js
@@ -0,0 +1,18 @@
+const URL = "http://localhost:3001/email/";
+
+async function clearEmails() {
+ const response = await fetch(URL + "clear", {
+ method: "POST",
+ });
+ return response.status === 200;
+}
+
+async function getSentEmails() {
+ const response = await fetch(URL + "get", {
+ method: "GET",
+ });
+ const data = await response.json();
+ return data;
+}
+
+export { clearEmails, getSentEmails };
diff --git a/frontend/src/service/openaiService.js b/frontend/src/service/openaiService.js
new file mode 100644
index 000000000..66056b197
--- /dev/null
+++ b/frontend/src/service/openaiService.js
@@ -0,0 +1,22 @@
+const URL = "http://localhost:3001/openai/";
+
+async function clearOpenAiChat() {
+ const response = await fetch(URL + "clear", {
+ method: "POST",
+ });
+ return response.status === 200;
+}
+
+async function openAiSendMessage(message) {
+ const response = await fetch(URL + "chat", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ message }),
+ });
+ const data = await response.text();
+ return data;
+}
+
+export { clearOpenAiChat, openAiSendMessage };