diff --git a/client/src/components/bot/Bot.jsx b/client/src/components/bot/Bot.jsx new file mode 100644 index 0000000..63736461 --- /dev/null +++ b/client/src/components/bot/Bot.jsx @@ -0,0 +1,23 @@ +import React, { useState } from 'react' +import MediHubBot from './MediHubBot' +import chatIcon from '../../assets/images/chat-bot.jpg' +import './bot.css'; + function Bot() { + + const [chatbotOpen,setChatbotOpen] = useState(false) + const handleChatClick = () =>{ + setChatbotOpen(!chatbotOpen) + } + + return ( +
+
+
+ Chat Icon +
+
+ {chatbotOpen? :""} +
+ ) +} +export default Bot \ No newline at end of file diff --git a/client/src/components/bot/MediHubBot.jsx b/client/src/components/bot/MediHubBot.jsx new file mode 100644 index 0000000..4f8fd27 --- /dev/null +++ b/client/src/components/bot/MediHubBot.jsx @@ -0,0 +1,165 @@ +import { useState, useEffect } from "react"; +import { + GoogleGenerativeAI, + HarmCategory, + HarmBlockThreshold, +} from "@google/generative-ai"; +import './bot.css'; + +function MediHubBot(props) { + const [messages, setMessages] = useState([]); + const [userInput, setUserInput] = useState(""); + const [chat, setChat] = useState(null); + const [theme, setTheme] = useState("light"); + const [error, setError] = useState(null); + const API_KEY = YOUR_API_KEY; + const MODEL_NAME = "gemini-1.0-pro-001"; + + const genAI = new GoogleGenerativeAI(API_KEY); + + const generationConfig = { + temperature: 0.9, + topK: 1, + topP: 1, + maxOutputTokens: 2048, + }; + + const safetySettings = [ + { + category: HarmCategory.HARM_CATEGORY_HARASSMENT, + threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, + }, + { + category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, + threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, + }, + { + category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, + threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, + }, + { + category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, + threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, + }, + ]; + + useEffect(() => { + if (props.show) { + document.body.classList.add("no-scroll"); + } else { + document.body.classList.remove("no-scroll"); + } + + const initChat = async () => { + try { + const newChat = await genAI + .getGenerativeModel({ model: MODEL_NAME }) + .startChat({ + generationConfig, + safetySettings, + history: [ + ...messages.map((msg) => ({ + text: msg.text, + role: msg.role, + })), + ], + }); + setChat(newChat); + } catch (error) { + setError("Failed to initialize chat. Please try again."); + } + }; + if (props.show) { + initChat(); + } + }, [props.show]); + + const handleSendMessage = async () => { + try { + const userMessage = { + text: userInput, + role: "user", + timestamp: new Date(), + }; + + setMessages((prevMessages) => [...prevMessages, userMessage]); + setUserInput(""); + + if (chat) { + const input_prompt = ` + If ${userInput} is informal like "hi"/"hello" etc ,respond like a general chatbot informally and greet back the user.Else, + Identify answer based on the given exam question by the user through ${userInput} and also list possible correct answer for the same. + If the user is asking general question etc through ${userInput} provide assistance for the same. + Don't give * in response please. + Generate response in proper points on new line. + + `; + const result = await chat.sendMessage(input_prompt); + const botMessage = { + text: result.response.text(), + role: "bot", + timestamp: new Date(), + }; + + setMessages((prevMessages) => [...prevMessages, botMessage]); + } + } catch (error) { + setError("Failed to send message. Please try again."); + } + }; + + const handleKeyPress = (e) => { + if (e.key === "Enter") { + e.preventDefault(); //prevents adding a new line in input field + handleSendMessage(); + } + }; + return ( +
+
+

Medihub Bot

+
+
+ {messages.map((msg, index) => ( +
+
+ {msg.text} +
+
+ ))} +
+ {error &&
{error}
} +
+ setUserInput(e.target.value)} + onKeyDown={handleKeyPress} + className={`flex p-2 text-sm rounded-l-md border-t border-b border-l text-black focus:outline-none focus:border-bg-blue-500`} + /> + +
+
+ ); +} + +export default MediHubBot; \ No newline at end of file diff --git a/client/src/components/bot/bot.css b/client/src/components/bot/bot.css new file mode 100644 index 0000000..92b9e8d --- /dev/null +++ b/client/src/components/bot/bot.css @@ -0,0 +1,257 @@ +/* Container for the chatbot icon */ +.bot-container { + position: fixed; + bottom: 20px; + /* Adjust as needed */ + right: 20px; + /* Adjust as needed */ + z-index: 1000; + /* Ensure it stays on top of other elements */ + cursor: pointer; +} + +/* Styles for the chatbot button */ +.bot-button { + width: 48px; + /* Adjust size as needed */ + height: 48px; + /* Adjust size as needed */ + border-radius: 50%; + background-color: white; + box-shadow: 0px 4px 6px rgba(0, 128, 0, 0.4); + /* Adjust shadow and color as needed */ + display: flex; + justify-content: center; + align-items: center; + margin: 2px; +} + +.bot-button img { + width: 100%; + height: 100%; + border-radius: 50%; +} + +/* MediHubBot.css */ +.no-scroll { + overflow: hidden; +} + +.flex { + display: flex; +} + +.flex-col { + flex-direction: column; +} + +.fixed { + position: fixed; +} + +.centered { + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.h-\[70vh\] { + height: 70vh; +} + +.w-\[18\.5rem\] { + width: 18.5rem; +} + +.p-4 { + padding: 1rem; +} + +.shadow-md { + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.shadow-emerald-200 { + box-shadow: 0 4px 6px rgba(167, 243, 208, 1); +} + +.bg-white { + background-color: white; +} + +.rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +} + +.rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.justify-between { + justify-content: space-between; +} + +.items-center { + align-items: center; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.text-2xl { + font-size: 1.5rem; +} + +.font-bold { + font-weight: bold; +} + +.text-dark_theme { + color: #333; + /* Adjust to your dark theme color */ +} + +.flex-1 { + flex: 1; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.bg-gray-100 { + background-color: #f7fafc; +} + +.rounded-md { + border-radius: 0.375rem; +} + +.p-2 { + padding: 0.5rem; +} + +.text-right { + text-align: right; +} + +.text-left { + text-align: left; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.text-xs { + font-size: 0.75rem; +} + +.text-white { + color: white; +} + +.ml-32 { + margin-left: 8rem; +} + +.p-1 { + padding: 0.25rem; +} + +.rounded-l-lg { + border-bottom-left-radius: 0.5rem; + border-top-left-radius: 0.5rem; +} + +.bg-dark_theme { + background-color: #333; + /* Adjust to your dark theme color */ +} + +.bg-light_theme { + background-color: #e2e8f0; + /* Adjust to your light theme color */ +} + +.text-gray-800 { + color: #2d3748; +} + +.rounded-b-lg { + border-bottom-left-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.text-red-500 { + color: #f56565; +} + +.text-sm { + font-size: 0.875rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.w-full { + width: 100%; +} + +.rounded-l-md { + border-top-left-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; +} + +.border-t { + border-top-width: 1px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-l { + border-left-width: 1px; +} + +.text-black { + color: black; +} + +.focus\:outline-none:focus { + outline: none; +} + +.focus\:border-bg-blue-500:focus { + border-color: #4299e1; +} + +.rounded-r-md { + border-top-right-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; +} + +.hover\:bg-opacity-80:hover { + background-color: rgba(0, 0, 0, 0.8); + /* Adjust to your hover opacity color */ +} + +.focus\:outline-none:focus { + outline: none; +} + +.bg-dark_theme { + background-color: #333; + /* Adjust to your dark theme color */ +} \ No newline at end of file