Skip to content

Commit

Permalink
feat: ai chat | prompts
Browse files Browse the repository at this point in the history
* feat: ai prompts are added

* feat: ai chat | fix and improve some design and format

---------

Co-authored-by: Kabir <[email protected]>
  • Loading branch information
sumanjeet0012 and kabir0x23 authored Jan 28, 2024
1 parent 5d25fe4 commit bab72bf
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 41 deletions.
104 changes: 73 additions & 31 deletions src/components/AIChat/AIChat.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { FaAngleLeft, FaAngleRight } from "react-icons/fa";
// import LoginBox from "../Common/LoginBox";
// import {useNavigate} from "react-router-dom";
import AuthPopup from "../../pages/AuthPopup/AuthPopup";
import Prompts from "./Prompts/Prompts";

const API_BASE_URL = getApiUrl("api/aiChat");

Expand All @@ -35,6 +36,40 @@ const AiChat = () => {
const [toggle, setToggle] = useState(false);
const [showAuthPopup, setShowAuthPopup] = useState(false);

const handleSendDummyMessage = async (dummyMessage) => {
setUserInput(dummyMessage);
setIsLoading(true);

if (!user) {
setShowAuthPopup(true);
setIsLoading(false);
return;
}

try {
const response = await axios.post(
`${API_BASE_URL}/ask/${selectedChatId}`,
{ prompt: dummyMessage },
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${user.token}`,
},
},
);

const { chats } = response.data;
setChats(chats);
setUserInput("");
} catch (error) {
toast("Please enter your API Key");
// toast(error.response.data);
console.error(error);
} finally {
setIsLoading(false);
}
};

const handleSendMessage = async (e) => {
e.preventDefault();
setIsLoading(true);
Expand All @@ -61,7 +96,8 @@ const AiChat = () => {
setChats(chats);
setUserInput("");
} catch (error) {
toast(error.response.data);
toast("Please enter your API Key");
// toast(error.response.data);
console.error(error);
} finally {
setIsLoading(false);
Expand Down Expand Up @@ -124,8 +160,6 @@ const AiChat = () => {
const handleDeleteChat = async (chatId) => {
setIsLoading(true);

console.log("chatId", chatId);
console.log("userId", user._id);
try {
await axios.delete(`${API_BASE_URL}/delete/${chatId}`, {
headers: {
Expand Down Expand Up @@ -162,9 +196,6 @@ const AiChat = () => {
setShowAuthPopup(false);
};

console.log("showAuthPopup", showAuthPopup);
console.log(selectedChatId);

return (
<Wrapper>
{showAuthPopup && <AuthPopup onClose={() => handleCloseAuthPopup()} />}
Expand Down Expand Up @@ -194,22 +225,28 @@ const AiChat = () => {

<ChatMessages messages={chat.messages} />

<ChatInput onSubmit={handleSendMessage}>
<input
type="text"
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
/>
{isLoading ? (
<button>
<CircleSpinner size={20} color={"#131313"} />
</button>
) : (
<button type="submit">
<BiSend size={25} />
</button>
<div>
{chat.title !== "New Chat" ? null : (
<Prompts handleSendDummyMessage={handleSendDummyMessage} />
)}
</ChatInput>

<ChatInput onSubmit={handleSendMessage}>
<input
type="text"
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
/>
{isLoading ? (
<button>
<CircleSpinner size={20} color={"#131313"} />
</button>
) : (
<button type="submit">
<BiSend size={25} />
</button>
)}
</ChatInput>
</div>
</ChatBox>
),
)
Expand All @@ -224,16 +261,21 @@ const AiChat = () => {
</ChatHeader>

<ChatInput onSubmit={handleSendMessage}>
<input type="text" value={userInput} onChange={(e) => setUserInput(e.target.value)} />
{isLoading ? (
<button>
<CircleSpinner size={20} color={"#131313"} />
</button>
) : (
<button type="submit">
<BiSend size={25} />
</button>
)}
<input
type="text"
value={"Start A New Chat "}
onChange={(e) => setUserInput(e.target.value)}
/>

{/* {isLoading ? ( */}
{/* <button> */}
{/* <CircleSpinner size={20} color={"#131313"}/> */}
{/* </button> */}
{/* ) : ( */}
{/* <button type="submit"> */}
{/* <BiSend size={25}/> */}
{/* </button> */}
{/* )} */}
</ChatInput>
</ChatBox>
)}
Expand Down
20 changes: 20 additions & 0 deletions src/components/AIChat/Prompts/PromptCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";

const PromptCard = ({ prompt, handleSendDummyMessage, index }) => {
return (
<button
key={index}
onClick={() => {
handleSendDummyMessage(`${prompt.title}, ${prompt.description}`);
}}
className="border-solid w-full p-2.5 border-2 border-[#252525] rounded-lg hover:outline-red-500 hover:bg-[#252525] "
>
<p>
{prompt.title} <br />
<span className="opacity-50">{prompt.description}</span>
</p>
</button>
);
};

export default PromptCard;
30 changes: 30 additions & 0 deletions src/components/AIChat/Prompts/Prompts.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useState, useEffect } from "react";
import promptsData from "./prompts.json";
import PromptCard from "./PromptCard";

const Prompts = ({ handleSendDummyMessage }) => {
const [prompts, setPrompts] = useState([]);

useEffect(() => {
// Shuffle the prompts array
const shuffledPrompts = promptsData.sort(() => Math.random() - 0.5).slice(0, 6);
setPrompts(shuffledPrompts);
}, []); // Empty dependency array ensures the effect runs only once

return (
<div>
<div className="grid grid-cols-1 lg:grid-cols-2 md:grid-cols-2 sm:grid-cols-1 w-full h-full mb-4 lg:flex-row md:flex-row sm:flex-col gap-2">
{prompts.map((prompt, index) => (
<PromptCard
key={index}
prompt={prompt}
index={index}
handleSendDummyMessage={handleSendDummyMessage}
/>
))}
</div>
</div>
);
};

export default Prompts;
51 changes: 51 additions & 0 deletions src/components/AIChat/Prompts/prompts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[
{
"title": "What is Cyber Security",
"description": "Explain in detail about it."
},
{
"title": "How to make website secure",
"description": "by adding an extra layer of security."
},
{
"title": "What is Data Breach",
"description": "How to prevent it."
},
{
"title": "What is Deep Web",
"description": "How to access it."
},
{
"title": "Importance of Encryption in Cyber Security",
"description": "How encryption helps protect data in cyber security."
},
{
"title": "Common Social Engineering Techniques",
"description": "Identify and protect against social engineering attacks."
},
{
"title": "Types of Malware and How to Combat Them",
"description": "Explore different types of malware and strategies to defend against them."
},
{
"title": "Best Practices for Password Security",
"description": "Tips for creating strong and secure passwords to enhance cyber security."
},
{
"title": "Web Application Security Best Practices",
"description": "Ensure the security of web applications through best practices."
},
{
"title": "SQL Injection and Prevention Measures",
"description": "Understand SQL injection attacks and how to prevent them in web applications."
},
{
"title": "Cross-Site Scripting (XSS) Vulnerabilities",
"description": "Identify and mitigate cross-site scripting vulnerabilities in websites."
},
{
"title": "Security Headers for Enhanced Web Security",
"description": "Implement security headers to enhance the security of web applications."
}
]

1 change: 0 additions & 1 deletion src/components/CheatSheets/HackBook/HackBook.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import CheatSheet from "../CheatSheet";
import hackBook from "./HackBookData/hackbook.json";

const HackBook = () => {
console.log(hackBook);
return <CheatSheet data={hackBook} heading={"Hack Book"} />;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const useImageUploadEvents = (prevContent, setContent, pageName) => {
const newFile = new File([reader.result], fileName, { type: file && file.type });
const formData = new FormData();
formData.append("image", newFile);
console.log(newFile);
const API_URL = getApiUrl("api/upload");
await axios.post(API_URL, formData);
const newImageUrl = cdnContentImagesUrl(`/${pageName}/${fileName.split("-")[1]}`);
Expand Down
1 change: 0 additions & 1 deletion src/components/Courses/NewCourses/Course.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const Course = () => {
// }

const changeImgSrc = (src) => {
console.log(src, "1");
document.getElementById("image").src = src;
};

Expand Down
1 change: 0 additions & 1 deletion src/components/Courses/NewCourses/NewCourses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ const NewCourses = () => {
} else {
setFilterContent(null);
}
console.log(filterContent);
};

return (
Expand Down
4 changes: 0 additions & 4 deletions src/components/Dashboard/FormData/InternshipResponse.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ const InternshipResponse = () => {
? filteredData.filter((data) => data.reasonType === selectedReasonType)
: filteredData;

console.log("isAuthorised:", isAuthorised);
console.log("isLoading:", isLoading);
console.log("formData:", formData);

if (!isAuthorised || isLoading || formData === null) {
return <NotFound />;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {
import Connections from "./Connections";

const Connection = ({ userDetail, userDetails }) => {
console.log("userDetail", userDetail);

const dispatch = useDispatch();
const { user } = useSelector((state) => state.auth);
const { connections: connectionData } = useSelector((state) => state.connectionData);
Expand Down

0 comments on commit bab72bf

Please sign in to comment.