Skip to content
This repository has been archived by the owner on Mar 26, 2024. It is now read-only.

Commit

Permalink
thalia chatbot added (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
SHUHAIB-T authored Mar 9, 2024
2 parents 4cd2369 + 9c7ce8a commit cf6d64d
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 19 deletions.
7 changes: 7 additions & 0 deletions client/src/API/aiThaliaAPI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import axios from 'axios';
const baseURL = import.meta.env.VITE_AI_BASE_URL;
const aiThaliaAPI = axios.create({
baseURL,
});

export default aiThaliaAPI;
13 changes: 13 additions & 0 deletions client/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
@tailwind components;
@tailwind utilities;

* {
padding: 0;
margin: 0;
box-sizing: border-box;
}

*::-webkit-scrollbar-track {
background: #291f3a;
}
Expand All @@ -23,3 +29,10 @@
background-color: rgb(74, 29, 86) !important;
color: rgb(168, 145, 174) !important;
}

.chat-didi:hover .my-tooltip {
display: inline-block;
}
.my-tooltip {
display: none;
}
28 changes: 28 additions & 0 deletions client/src/assets/Chat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
164 changes: 164 additions & 0 deletions client/src/components/BotModal/BotModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { Modal } from "flowbite-react";
import SendIcon from "@mui/icons-material/Send";
import PropTypes from "prop-types";
import { useEffect, useRef, useState } from "react";
import aiThaliaAPI from "../../API/aiThaliaAPI";
import Loader3 from "../../components/Loader/Loader3/Loader3";

export default function BotModal({ openModal, setOpenModal }) {
const [query, setQuery] = useState("");
const [submit, setSubmit] = useState(true);
const scroll = useRef(null);
const qInput = useRef();

const [messages, setMessages] = useState([
{
id: "bot",
message: "",
},
]);

useEffect(() => {
console.log(import.meta.env.VITE_AI_BASE_URL);
if (qInput.current && !submit) {
qInput.current.focus();
}
}, [submit]);

useEffect(() => {
scroll.current?.scrollIntoView({ behavior: "smooth" });
}, [messages, openModal]);

useEffect(() => {
if (openModal && messages.length < 2) {
setTimeout(() => {
setMessages([
{
id: "bot",
message: "Hello, Do you have anything to share with me😊",
},
]);
setSubmit(false);
}, 1000);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [openModal]);

useEffect(() => {
(async function () {
if (query && submit) {
try {
const { data } = await aiThaliaAPI.post("/chat", { query: query });
if (data.success) {
setMessages([
...messages,
{
id: "bot",
message: data.message,
},
]);
setSubmit(false);
setQuery("");
}
} catch (err) {
console.log(err);
setQuery("");
setSubmit(false);
setQuery("");
}
}
})();
}, [submit, query, messages]);

const handlSubmit = (e) => {
e.preventDefault();
if (query) {
setMessages([
...messages,
{
id: "user",
message: query,
},
]);
setSubmit(true);
}
};

return (
<>
<Modal
className="sm:p-10 py-10"
size={"md"}
dismissible
show={openModal}
position={"bottom-right"}
onClose={() => {
setOpenModal(false);
}}
>
<Modal.Header className="bg-primary">Chat with Didi 🤎</Modal.Header>
<Modal.Body className="min-h-80 max-h-80 w-full">
<div className="flex flex-col w-full flex-grow h-full space-y-4 overflow-auto">
{messages.map((e) => {
return (
<>
{e.id === "bot" ? (
<div className="flex w-full mt-2 space-x-3 max-w-xs">
<div>
{e.message && (
<div className="bg-gray-300 p-3 rounded-r-lg rounded-bl-lg">
<p className="text-sm">{e.message}</p>
</div>
)}
</div>
</div>
) : (
<div className="flex w-full mt-2 space-x-3 max-w-xs ml-auto justify-end">
<div>
<div className="bg-secondary text-white p-3 rounded-l-lg rounded-br-lg">
<p className="text-sm">{e.message}</p>
</div>
</div>
</div>
)}
</>
);
})}
{submit && (
<div className="flex w-full mt-2 space-x-3 max-w-xs">
<div>
<div className="bg-gray-300 px-3 py-2 rounded-r-lg rounded-bl-lg">
<Loader3 />
</div>
</div>
</div>
)}
<div ref={scroll} />
</div>
</Modal.Body>
<form
onSubmit={handlSubmit}
className="flex w-full h-full gap-4 px-5 justify-center items-center"
>
<input
ref={qInput}
type="text"
placeholder="Ask me..."
className="w-full rounded-lg mb-5 ring-1 ring-gray-400 border-0"
value={query}
disabled={submit}
onChange={(e) => setQuery(e.target.value)}
/>
<button type="submit" className="mb-5 cursor-pointer">
<SendIcon />
</button>
</form>
</Modal>
</>
);
}

BotModal.propTypes = {
openModal: PropTypes.bool.isRequired,
setOpenModal: PropTypes.func.isRequired,
};
30 changes: 30 additions & 0 deletions client/src/components/Loader/Loader3/Loader3.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.load {
display: flex;
border-radius: 50%;
flex-direction: row;
}

.progress {
width: 0.5em;
height: 0.5em;
margin: 0.4em;
scale: 0;
border-radius: 50%;
background: rgb(82, 10, 10);
animation: loading_492 1s ease infinite;
animation-delay: 0.5s;
}

@keyframes loading_492 {
50% {
scale: 1;
}
}

.progress:nth-child(2) {
animation-delay: 1.3s;
}

.progress:nth-child(3) {
animation-delay: 1.7s;
}
11 changes: 11 additions & 0 deletions client/src/components/Loader/Loader3/Loader3.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import "./Loader3.css";

export default function Loader3() {
return (
<div className="load">
<div className="progress"></div>
<div className="progress"></div>
<div className="progress"></div>
</div>
);
}
2 changes: 1 addition & 1 deletion client/src/components/Nabar/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function Navbar() {

return (
<>
<div className="flex items-center justify-between sticky z-40 top-0 w-full px-10 py-1 bg-gradient-to-r from-[#2d1525] to-background">
<div className="flex items-center justify-between sticky z-40 top-0 w-full px-3 md:px-10 py-1 bg-gradient-to-r from-[#2d1525] to-background">
<Link to={"/"}>
<img src={Logo} className="w-24" alt="" />
</Link>
Expand Down
58 changes: 40 additions & 18 deletions client/src/components/UserHome/UserHome.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,50 @@ import MybodyCard from "../MyBodyCard/MybodyCard";
import MyLawsCard from "../MyLawsCard/MyLawsCard";
import MyMindCard from "../MyMindCard/MyMindCard";
import CommunityCard from "../CommunityCard/CommunityCard";
import Chat from "../../assets/Chat.svg";
import BotModal from "../BotModal/BotModal";

import { Link } from "react-router-dom";
import { useState } from "react";

export default function UserHome() {
const [openModal, setOpenModal] = useState(false);

return (
<div className="relative justify-center items-center flex overflow-hidden bg-gradient-to-r from-[#3e1734] to-background py-10 md:py-40">
<div className="flex flex-wrap gap-5 justify-center z-20 items-center">
<Link to={"/my-body"}>
<MybodyCard />
</Link>
<Link to={"/my-mind"}>
<MyMindCard />
</Link>
<Link to={"/my-rights"}>
<MyLawsCard />
</Link>
<CommunityCard />
<>
<BotModal openModal={openModal} setOpenModal={setOpenModal} />
<div className="relative justify-center items-center flex overflow-hidden bg-gradient-to-r from-[#3e1734] to-background py-20 md:py-40">
<div className="flex flex-wrap gap-5 justify-center z-20 items-center">
<Link to={"/my-body"}>
<MybodyCard />
</Link>
<Link to={"/my-mind"}>
<MyMindCard />
</Link>
<Link to={"/my-rights"}>
<MyLawsCard />
</Link>
<CommunityCard />
</div>
<img
src="https://cdn.dribbble.com/users/1595839/screenshots/11700339/media/5b39c07a6a721b6b440288c6c6ec5cb1.gif"
className="absolute opacity-10 top-0 hidden md:inline-block md:w-full z-10"
alt=""
/>
<div className="fixed chat-didi flex justify-center right-7 md:bottom-10 md:right-10 z-20">
<div className="bg-text my-tooltip mr-[-25px] pr-9 px-3 py-1 rounded-s-full">
<h1 className="text-secondary mt-2 font-semibold">
Chat with Didi
</h1>
</div>
<div
onClick={() => setOpenModal(true)}
className="w-12 h-12 cursor-pointer rounded-full flex items-center justify-center bg-text"
>
<img src={Chat} alt="" className="w-8 z-40 " />
</div>
</div>
</div>
<img
src="https://cdn.dribbble.com/users/1595839/screenshots/11700339/media/5b39c07a6a721b6b440288c6c6ec5cb1.gif"
className="absolute opacity-10 top-0 hidden md:inline-block md:w-full z-10"
alt=""
/>
</div>
</>
);
}
1 change: 1 addition & 0 deletions client/src/components/ViewMarkModal/ViewMarkModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default function ViewMarkModal({
<>
<Modal
size={"6xl"}
className="p-10"
show={openModal}
position={"top-center"}
onClose={() => {
Expand Down

0 comments on commit cf6d64d

Please sign in to comment.