diff --git a/src/components/FAQbot/Chatbot.jsx b/src/components/FAQbot/Chatbot.jsx new file mode 100644 index 0000000..647d949 --- /dev/null +++ b/src/components/FAQbot/Chatbot.jsx @@ -0,0 +1,347 @@ +import { useState, useEffect, useRef } from "react"; + +const QUESTIONS = { + "What is DevTinder?": { + text: + "DevTinder is a modern web app that connects developers based on their skills, interests, and project goals — like 'Tinder for Developers'.", + followUps: [ + { + question: "Is DevTinder free?", + text: "Yes, DevTinder is 100% free for all developers.", + }, + { + question: "Who is DevTinder for?", + text: + "Whether you're a student, freelancer, or pro — if you're building something, DevTinder is for you.", + }, + ], + }, + "How does team matching work?": { + text: + "You can find and join dev teams for hackathons and projects. It's currently in development (75%).", + followUps: [ + { + question: "When will it be available?", + text: + "Team Matching is in development and should roll out in the next major update.", + }, + ], + }, + "What is the Blogs section about?": { + text: + "In the Blogs section, users will be able to read & share technical blogs and tutorials — currently 50% done.", + followUps: [ + { + question: "Can I contribute a blog?", + text: "Yes, contribution will be open when the feature goes live.", + }, + ], + }, + "What’s in the Full Profile Preview?": { + text: + "It allows users to view developer profiles with detailed info like skills, GitHub links, and project history. Planning phase is at 50%.", + followUps: [ + { + question: "Will profiles be public?", + text: + "Only basic details will be public; full preview will require permission.", + }, + ], + }, + "Is there real-time code collaboration?": { + text: + "Real-time collaborative coding is being designed. It will let developers code together instantly — currently in design (45%).", + followUps: [ + { + question: "Will it support multiple languages?", + text: + "Yes, the plan includes support for popular languages and live preview.", + }, + ], + }, + "What’s Project Ideas Hub?": { + text: + "It’s a feature to explore and share innovative project ideas with others — planning phase (25%).", + followUps: [ + { + question: "Can I submit ideas anonymously?", + text: "Yes, anonymous submission will be supported.", + }, + ], + }, + "How does Skill Assessment work?": { + text: + "We're researching AI-powered skill testing and recommendations to help you find your best matches — early research phase.", + followUps: [ + { + question: "Will there be quizzes or coding rounds?", + text: "Yes, assessments may include coding tasks, quizzes, and GitHub metrics.", + }, + ], + }, +}; + +const questionOptions = Object.keys(QUESTIONS); + +export default function ChatBot() { + const [isOpen, setIsOpen] = useState(false); + const [chat, setChat] = useState([]); + const [isTyping, setIsTyping] = useState(false); + const [isLoadingOptions, setIsLoadingOptions] = useState(false); + const [isFirstLoad, setIsFirstLoad] = useState(true); + const chatRef = useRef(null); + + const scrollToBottom = () => { + chatRef.current?.scrollIntoView({ behavior: "smooth" }); + }; + + useEffect(() => { + scrollToBottom(); + }, [chat, isOpen]); + + const handleQuestionClick = (q) => { + const selected = QUESTIONS[q]; + if (!selected) return; + + setIsLoadingOptions(false); + setChat((prev) => [...prev, { from: "user", text: q }]); + setIsTyping(true); + setTimeout(() => { + setChat((prev) => [...prev, { from: "bot", text: selected.text }]); + setIsTyping(false); + + setTimeout(() => { + setChat((prev) => [ + ...prev, + { from: "bot", followUps: selected.followUps, parentQuestion: q, showMainMenuButton: true },]); + }, 1100); + }, 1100); + }; + + const handleFollowUpClick = (parentQuestion, followUp) => { + setChat((prev) => [...prev, { from: "user", text: followUp.question }]); + + setIsTyping(true); + setTimeout(() => { + setIsTyping(false); + setChat((prev) => [...prev, { from: "bot", text: followUp.text }]); + setTimeout(() => { + setChat((prev) => [ + ...prev, + { from: "bot", text: "You can navigate to the main menu for more options.", isMainMenuPrompt: true }, + ]); + }, 500); + }, 1000); + }; + + const renderInitialQuestions = () => { + setIsLoadingOptions(false); + + if (isFirstLoad) { + setChat([]); + setChat([ + { + from: "bot", + text: "✨ Welcome to DevTinder ❤️❤️! I'm Nova, your assistant. I'm here to help you get started. What would you like to know?", + isWelcome: true, + }, + ]); + + setTimeout(() => { + setIsLoadingOptions(true); + }, 500); + + setTimeout(() => { + setIsLoadingOptions(false); + setChat((prevChat) => [ + ...prevChat, + { from: "bot", initialOptions: questionOptions, isStaggered: true } + ]); + setIsFirstLoad(false); + }, 3500); + } else { + setChat((prevChat) => [ + ...prevChat, + { from: "bot", initialOptions: questionOptions, isStaggered: false } + ]); + } + }; + + const resetChatbot = () => { + setIsOpen(false); + setChat([]); + setIsTyping(false); + setIsLoadingOptions(false); + setIsFirstLoad(true); + }; + + return ( +
+ {!isOpen && ( + + )} + + {isOpen && (
+
+ Nova - DevTinder Assistant + +
+ +
+ {chat.map((msg, idx) => ( +
+ {!msg.followUps && !msg.initialOptions && !msg.isMainMenuPrompt && ( +
+ {msg.text} +
+ )} + + {msg.followUps && ( +
+ {msg.followUps.map((fup, i) => ( + + ))} + +
+ )} + {msg.isMainMenuPrompt && ( +
+
+ {msg.text} +
+ +
+ )} + + {msg.initialOptions && ( +
+ {msg.initialOptions.map((opt, index) => ( + + ))} +
+ )} +
+ ))} + + {isLoadingOptions && ( +
+
+ Looking for questions... +
+ )} + + {isTyping && (
Nova is typing.....
)} + +
+
+
+ )} + +
+ ); +} diff --git a/src/pages/Body.jsx b/src/pages/Body.jsx index 8ccf5c8..f4ef675 100644 --- a/src/pages/Body.jsx +++ b/src/pages/Body.jsx @@ -7,6 +7,7 @@ import { setUser } from "../utils/userSlicer.js"; import { useNavigate } from "react-router"; import { useEffect, useCallback } from "react"; import { createApiUrl, API_ENDPOINTS } from "../utils/apiConfig"; +import Chatbot from "../components/FAQbot/Chatbot.jsx"; const Body = () => { @@ -52,6 +53,7 @@ const Body = () => {
+
)