Skip to content

Commit

Permalink
chatbox changes (#465)
Browse files Browse the repository at this point in the history
Co-authored-by: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com>
  • Loading branch information
sidhigrover and varshith257 authored Jun 7, 2024
1 parent 9e5d37e commit bc8ad66
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 102 deletions.
51 changes: 26 additions & 25 deletions chatbox.css
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
/* Import Google font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');

* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {

}


.chatbot-toggler {

position: fixed;
bottom: 30px;
right: 35px;
z-index: 2;
right: 30px;
outline: none;
border: none;
height: 50px;
Expand All @@ -24,7 +17,7 @@ body {
align-items: center;
justify-content: center;
border-radius: 50%;
background: #4178c0;
background: #55a5ea;
transition: all 0.2s ease;
}
body.show-chatbot .chatbot-toggler {
Expand All @@ -42,11 +35,12 @@ body.show-chatbot .chatbot-toggler span:last-child {
opacity: 1;
}
.chatbot {
z-index: 1;
position: fixed;
right: 35px;
bottom: 90px;
width: 420px;
bottom: 150px;
z-index: 2;
width: 500px;
height: 400px;
background: #fff;
border-radius: 15px;
overflow: hidden;
Expand All @@ -55,7 +49,7 @@ body.show-chatbot .chatbot-toggler span:last-child {
transform: scale(0.5);
transform-origin: bottom right;
box-shadow: 0 0 128px 0 rgba(0,0,0,0.1),
0 32px 64px -48px rgba(0,0,0,0.5);
0 32px 64px -48px #55a5ea;
transition: all 0.1s ease;
}
body.show-chatbot .chatbot {
Expand All @@ -68,8 +62,8 @@ body.show-chatbot .chatbot {
position: relative;
text-align: center;
color: #fff;
background: #4178c0;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
background: #55a5ea;
box-shadow: 0 2px 10px #55a5ea;
}
.chatbot header span {
position: absolute;
Expand All @@ -84,7 +78,7 @@ header h2 {
}
.chatbot .chatbox {
overflow-y: auto;
height: 510px;
height: 350px;
padding: 30px 20px 100px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar {
Expand Down Expand Up @@ -114,7 +108,7 @@ header h2 {
text-align: center;
line-height: 32px;
align-self: flex-end;
background: #4178c0;
background: #55a5ea;
border-radius: 4px;
margin: 0 10px 7px 0;
}
Expand All @@ -123,9 +117,11 @@ header h2 {
padding: 12px 16px;
border-radius: 10px 10px 0 10px;
max-width: 75%;
margin-bottom: 10px;
margin-left: 5px;
color: #fff;
font-size: 0.95rem;
background: #4178c0;
background: #55a5ea;
}
.chatbox .incoming p {
border-radius: 10px 10px 10px 0;
Expand Down Expand Up @@ -160,7 +156,7 @@ header h2 {
}
.chat-input span {
align-self: flex-end;
color: #4178c0;
color:#333;
cursor: pointer;
height: 55px;
display: flex;
Expand All @@ -171,18 +167,23 @@ header h2 {
.chat-input textarea:valid ~ span {
visibility: visible;
}
.hero img{
z-index: -1;
}

@media (max-width: 490px) {
.chatbot-toggler {
right: 20px;
bottom: 20px;
right: 35px;
bottom: 90px;
z-index: 3;
}
.chatbot {
right: 0;
bottom: 0;
height: 100%;
border-radius: 0;
width: 100%;
z-index: 4;
}
.chatbot .chatbox {
height: 90%;
Expand All @@ -194,4 +195,4 @@ header h2 {
.chatbot header span {
display: block;
}
}
}
126 changes: 59 additions & 67 deletions chatboxx.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,41 @@ const chatInput = document.querySelector(".chat-input textarea");
const sendChatBtn = document.querySelector(".chat-input span");

let userMessage = null; // Variable to store user's message
let appointmentStep = 0; // Variable to track the appointment scheduling steps
let selectedDoctor = null; // Variable to store the selected doctor
let appointmentDetails = {}; // Object to store appointment details

const inputInitHeight = chatInput.scrollHeight;

const predefinedQA = {
"Hi": "Hello",
"Hey":"Hello",
"How are you?": "I'm just a bot, but I'm doing great! How can I assist you today?",
"What is your name?": "I am a chatbot created to assist you.",
"Tell me a joke.": "Why don't scientists trust atoms? Because they make up everything!",
"What is RapiDoc?": "RapiDoc is an online platform which enables you to get information about your nearest hospitals and healthcare facilities. It aims to address health-related issues. It is a one-stop destination for all your medical needs.",
"How can RapiDoc help me?": "RapiDoc helps you find the nearest hospitals and healthcare facilities, ensuring you have access to necessary medical information and services quickly and easily.",
"What services does RapiDoc provide?": "RapiDoc provides information on nearby hospitals, healthcare facilities, and various medical services to address your health-related needs.",
"Make an appointment": "Sure, here are some doctors available for appointments:\n1. Dr. Vikas Chopra\n2. Dr. Ajay Aggarwal\n3. Dr. Soni Gupta\nPlease type the number of the doctor you want to make an appointment with."
};

const doctorsList = {
"1": "Dr. Vikas Chopra",
"2": "Dr. Ajay Aggarwal",
"3": "Dr. Soni Gupta"
const predefinedAnswers = {
"What types of health checkup packages does Rapidoc offer?": "Rapidoc offers a variety of health checkup packages, including basic health screenings, comprehensive full-body checkups, and specialized tests tailored to specific health concerns.",
"How can I book a health checkup through Rapidoc?": "You can easily book a health checkup through our platform by selecting your preferred package and scheduling a convenient appointment time. Our user-friendly interface guides you through the booking process.",
"What should I expect during my health checkup?": "During your health checkup, you will undergo a series of tests and screenings based on the package you selected. Our medical professionals will provide a detailed analysis of your results and personalized recommendations.",
"How do I find out the availability of emergency wards?": "Rapidoc provides real-time updates on the availability of emergency wards in various hospitals. Simply use our platform to check the current status and find the nearest available ward.",
"Can I book appointments with specialists through Rapidoc?": "Yes, you can book appointments with a wide range of specialists through Rapidoc. Our platform allows you to select the specialist you need and schedule an appointment at your convenience.",
"What personalized healthcare services does Rapidoc offer?": "Rapidoc offers personalized healthcare services including tailored treatment plans, ongoing health management, and consultations with various specialists to meet your unique health needs.",
"How does Rapidoc ensure the quality of its services?": "Rapidoc collaborates with certified medical professionals and accredited hospitals to ensure high-quality healthcare services. Our comprehensive health checkups and personalized care plans are designed to meet rigorous standards.",
"Is Rapidoc available in my area?": "Rapidoc is continually expanding its network. Please check our platform for the most up-to-date information on available locations and services in your area.",
"How do I get started with Rapidoc?": "Getting started with Rapidoc is easy. Visit our website, create an account, and explore our range of health services. You can book appointments, check emergency ward availability, and access personalized healthcare all through our platform.",
"What are the benefits of using Rapidoc for my healthcare needs?": "Rapidoc offers convenient and comprehensive healthcare solutions, including thorough health checkups, real-time emergency ward updates, seamless appointment bookings, and personalized healthcare services—all designed to enhance your well-being and streamline your healthcare experience."
};

const createChatLi = (message, className) => {
// Create a chat <li> element with passed message and className
const chatLi = document.createElement("li");
chatLi.classList.add("chat", `${className}`);
let chatContent = className === "outgoing" ? `<p></p>` : `<span class="material-symbols-outlined">smart_toy</span><p></p>`;
chatLi.innerHTML = chatContent;
chatLi.querySelector("p").textContent = message;
return chatLi;
if (className === "question") {
chatLi.style.cursor = "pointer";
}
return chatLi; // return chat <li> element
}


const generateResponse = (chatElement) => {
const API_URL = "https://api.openai.com/v1/chat/completions";
const messageElement = chatElement.querySelector("p");

// Define the properties and message for the API request
const requestOptions = {
method: "POST",
headers: {
Expand All @@ -50,10 +48,11 @@ const generateResponse = (chatElement) => {
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [{ role: "user", content: userMessage }],
messages: [{role: "user", content: userMessage}],
})
}

// Send POST request to API, get response and set the reponse as paragraph text
fetch(API_URL, requestOptions).then(res => res.json()).then(data => {
messageElement.textContent = data.choices[0].message.content.trim();
}).catch(() => {
Expand All @@ -62,62 +61,24 @@ const generateResponse = (chatElement) => {
}).finally(() => chatbox.scrollTo(0, chatbox.scrollHeight));
}

const handleAppointment = (userMessage) => {
if (appointmentStep === 0) {
selectedDoctor = doctorsList[userMessage];
if (!selectedDoctor) {
chatbox.appendChild(createChatLi("Invalid doctor number. Please try again.", "incoming"));
return;
}
chatbox.appendChild(createChatLi(`You selected ${selectedDoctor}. Please enter the date for your appointment (YYYY-MM-DD).`, "incoming"));
appointmentStep++;
} else if (appointmentStep === 1) {
const date = userMessage;
if (!date.match(/^\d{4}-\d{2}-\d{2}$/)) {
chatbox.appendChild(createChatLi("Invalid date format. Please enter the date in YYYY-MM-DD format.", "incoming"));
return;
}
appointmentDetails.date = date;
chatbox.appendChild(createChatLi("Please enter the time for your appointment (HH:MM).", "incoming"));
appointmentStep++;
} else if (appointmentStep === 2) {
const time = userMessage;
if (!time.match(/^\d{2}:\d{2}$/)) {
chatbox.appendChild(createChatLi("Invalid time format. Please enter the time in HH:MM format.", "incoming"));
return;
}
appointmentDetails.time = time;
chatbox.appendChild(createChatLi(`Appointment scheduled with ${selectedDoctor} on ${appointmentDetails.date} at ${appointmentDetails.time}.`, "incoming"));
appointmentStep = 0;
selectedDoctor = null;
appointmentDetails = {};
}
}

const handleChat = () => {
userMessage = chatInput.value.trim();
userMessage = chatInput.value.trim(); // Get user entered message and remove extra whitespace
if (!userMessage) return;

// Clear the input textarea and set its height to default
chatInput.value = "";
chatInput.style.height = `${inputInitHeight}px`;

// Append the user's message to the chatbox
chatbox.appendChild(createChatLi(userMessage, "outgoing"));
chatbox.scrollTo(0, chatbox.scrollHeight);

if (appointmentStep > 0) {
handleAppointment(userMessage);
} else if (predefinedQA[userMessage]) {
setTimeout(() => {
const incomingChatLi = createChatLi(predefinedQA[userMessage], "incoming");
chatbox.appendChild(incomingChatLi);
chatbox.scrollTo(0, chatbox.scrollHeight);
}, 600);
} else if (Object.keys(doctorsList).includes(userMessage)) {
setTimeout(() => {
handleAppointment(userMessage);
}, 600);
} else {
// Check if the message matches a predefined question
if (userMessage == "Hi" || userMessage == "hi" || userMessage == "HI")
showQuestionList();
else {
setTimeout(() => {
// Display "Thinking..." message while waiting for the response
const incomingChatLi = createChatLi("Thinking...", "incoming");
chatbox.appendChild(incomingChatLi);
chatbox.scrollTo(0, chatbox.scrollHeight);
Expand All @@ -127,11 +88,14 @@ const handleChat = () => {
}

chatInput.addEventListener("input", () => {
// Adjust the height of the input textarea based on its content
chatInput.style.height = `${inputInitHeight}px`;
chatInput.style.height = `${chatInput.scrollHeight}px`;
});

chatInput.addEventListener("keydown", (e) => {
// If Enter key is pressed without Shift key and the window
// width is greater than 800px, handle the chat
if (e.key === "Enter" && !e.shiftKey && window.innerWidth > 800) {
e.preventDefault();
handleChat();
Expand All @@ -141,3 +105,31 @@ chatInput.addEventListener("keydown", (e) => {
sendChatBtn.addEventListener("click", handleChat);
closeBtn.addEventListener("click", () => document.body.classList.remove("show-chatbot"));
chatbotToggler.addEventListener("click", () => document.body.classList.toggle("show-chatbot"));

function showWelcomeMessage() {
const welcomeChatLi = createChatLi("Hi! Welcome to RapiDoc! Chatbot. Say Hi to display menu.");
chatbox.appendChild(welcomeChatLi);
chatbox.scrollTo(0, chatbox.scrollHeight);
}

// Function to display list of questions
function showQuestionList() {
for (const question in predefinedAnswers) {
const questionChatLi = createChatLi(question, "question");
questionChatLi.addEventListener("click", () => showAnswer(question));
questionChatLi.style.cursor = "pointer";
chatbox.appendChild(questionChatLi);
}
chatbox.scrollTo(0, chatbox.scrollHeight);
}

// Function to display answer based on clicked question
function showAnswer(clickedQuestion) {
const answer = predefinedAnswers[clickedQuestion];
const answerChatLi = createChatLi(answer, "incoming");
chatbox.appendChild(answerChatLi);
chatbox.scrollTo(0, chatbox.scrollHeight);
}

// Call showWelcomeMessage and showQuestionList initially
showWelcomeMessage();
27 changes: 17 additions & 10 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -226,17 +226,24 @@
</nav>
</div>
</header>
<ul class="chatbox">
<li class="chat incoming">
<span class="material-symbols-outlined">smart_toy</span>
<p>Hi there 👋<br>How can I help you today?</p>
</li>
</ul>
<div class="chat-input">
<textarea placeholder="Enter a message..." spellcheck="false" required></textarea>
<span id="send-btn" class="material-symbols-rounded">send</span>
<!--chatbox-->
<button class="chatbot-toggler">
<span class="material-symbols-rounded">mode_comment</span>
<span class="material-symbols-outlined">close</span>
</button>
<div class="chatbot">
<header>
<h2>Chatbot</h2>
<span class="close-btn material-symbols-outlined">close</span>
</header>
<ul class="chatbox">

</ul>
<div class="chat-input">
<textarea placeholder="Enter a message..." spellcheck="false" required></textarea>
<span id="send-btn" class="material-symbols-rounded">send</span>
</div>
</div>
</div>


<!-- ############# Header ############# -->
Expand Down

0 comments on commit bc8ad66

Please sign in to comment.