86 | }
87 | >
88 | }
89 | // custom hookd, wanted to practice recoil, react(custom hooks), tailwind, ui ux and revise node express basically every thing
90 | // learned b/w week 9and 13 so created this component instead tell me a better way to get strong hold of these concepts
91 |
92 | // i have created a complete chatbot component10xAnswers because why not with the backend for your next project so you dont need to
93 | // worry about creating chatbot in your peoject, just add the prompt add backend url(dont worry if you dont want to build be just for
94 | // this i will be providing url to) hit and generate your responses, this is completely customizable and draggable too, open sourced
95 | // for you to look the codebase, built using react and recoil for optmizing state management, users can edit their questions,copy,
96 | // with complete support of markkdown rendering, for codes and tables try it out, also with a custom hook to display if the bot is up
97 | // for chat by checking internet connectivity status, soon will be adding ,media and voice modes along with more themes
98 |
99 | //installation and usage is very simple just do npm i 10xanswers
100 | // import { ChatBot } from '10xanswers';
101 |
102 | // for default bot the come out of the box tho you can preety much customize it
103 |
104 | //
138 |
139 | // inner styling changes or features you can either ping me up on x discord or github or you can contribute repo its open source
140 |
141 | // you can fix the starting state of the window
142 |
143 | // in developement after changing any prop of the chat, changes will only be visiible after reloding
144 |
145 | //you will be sending a post request to the backend url with contents in this payload
146 | /*{
147 | method: "POST",
148 | body: {
149 | "contents": [{
150 | "parts":[{"text": "User question"}]
151 | }]
152 | }
153 | }
154 | */
155 |
156 | // if user has own url and prompt set to "none", a direct request will go out to the be for user to
157 | // process the request on the be and generate his own prompt, "it is advised for user to build their backend with proper
158 | // prompting and manage history of chats for better usage, else if no prompt provided or left empty, the default prompt will be sent
159 | // to the mentioned url. Example of prompt: `You are 10xAnswers, an intelligent and highly versatile chatbot created by Rajveer Singh (x.com/rajveeerrsingh) using cutting-edge large language models (LLMs).
160 | // Your purpose is to assist users with precision, accuracy, and clarity. You excel at answering complex questions, solving coding challenges, offering creative solutions, and providing
161 | // insightful suggestions in any domain. Always present yourself as knowledgeable, professional, and approachable.
162 |
163 | // Guidelines for your responses:
164 | // 1. Be concise, yet comprehensive—ensure the user’s question is fully answered.
165 | // 2. Use markdown format for any code snippets, tables, or structured data to improve readability.
166 | // 3. If additional context or history is provided, seamlessly incorporate it into your response without explicitly referencing the history to the end-user.
167 | // 4. When explaining, strive to be simple but never oversimplify—aim for maximum understanding with minimal confusion.
168 |
169 | // End every interaction with a tone that encourages further queries, making the user feel valued and empowered. Let them know that you’re here to help with anything they need.
170 |
171 | // Current Question: ${question}.
172 | // History of User Questions and Context: ${chatHistory} here if available; otherwise, proceed as if this is the first question].
173 |
174 | // If this is your first interaction, make sure to leave a great first impression!`,
175 |
176 | // if custom prompt is provided with geminiApi/url it will be sent to the backend/geminni bot, you are advised to generate a prompt and should not worry about chat history as i will be storing
177 | // and sending it from front end this is the example of what the prompt will look like: `User is sending you some prompt about how you should act/behave along with the question he wants answered. Answer the question keeping the prompt text in mind.
178 |
179 | // Prompt: ${prompt}.
180 | // Question: ${question}.
181 | // History of User Questions and Context: ${chatHistory}.
182 |
183 | // Respond directly and concisely based on the history. If the history is empty, consider this as the first question. Don't let the end-user know about this history. Use markdown for formatting code or other structured content where necessary.`
184 |
185 | // if user is passing backend url to hit and prompt set to "none", the question is sent in a specific format provided i recommend storing history of all the
186 | // questions and responses on be and sending them along with your requests from backend no gemini key required in this method. If user
187 | // sends prompt and geminiApi req will be sent to gemini with the history of questions, i recommend writing prompts that specifies
188 | // about history and the array of all the questions asked will be added in the end of prompt you provided, for better history management
189 |
190 | // i have to guide user to how to generate prompt based on this structure
191 |
192 |
193 | // ---------- Ultimate thing to do -> did this from fe
194 | // not implementing history from be just now bc, there will be many users using same be
195 | // and all data will be stored here, which will result in wierd responses from ai, what i can do now is either
196 | // issue auth token to identify user and maintain his history or ask user to send history from fe, co=hoosing the
197 | // second one for now -------------
198 |
199 | // LAST STREACH ------------------------------------------------->
200 | // on homepage let users tweak the settings and have the code
201 | // make it persistant
202 |
203 | // figure out why extra re-rendering
204 | // revise week11
205 |
206 | // light mode? -> not now
207 | // documentation and package file-> done
208 | // now figure out a way to send history and prompt to be -> done
209 | // cook up its be -> done
210 | // npm-package out of it -> done
211 | // HIGH PRIORITY=> fix bugs: prolly about the ids assigning -> done
212 | // THE MAIN THING: Figure out why would anyone use it??? Something sarchesmic?? Some responses that are not provided by anyone -> done
213 | // gotta fix border radius of heading -> done
214 | // add a circle for chatbot close -> done
215 | // allow user to change bot icon -> done
216 | // backend service -> done
217 | // figure out a way to not ask users to wrap inside recoil root -> done
218 |
219 |
220 | // workflow=> question typed and enter is pressed from input element, this will generate an atom with an unique id which will update
221 | // everytime a question is entered, and the chat history is being updated with the question id, now chat area renders the chat
222 | // history(which contains the question id and answer id) and renders the chat component and question component for those ids, now
223 | // question component simply fetch the value of atom from respective atomFamily using those ids to render them, chat coponent
224 | // generated a new answer id, for the question id and question received, and updated the chatHistory with the answer id mapped to
225 | // the respective question id, this change of chathistory array triggers the re-render of all the answer and chat components onscreen.
226 |
227 | // edit-workflow=> when the question is edited its id remains the same, just the question changes, which re-renders this answer
228 | // component because the parameters passed to the answer atom family changes, a new atom is created with new id and the id for
229 | // the answer in "allChats" atom is updated ofr the same question to the new id generated and thus the whole chats gets re-rendered
--------------------------------------------------------------------------------
/src/components/inputArea.jsx:
--------------------------------------------------------------------------------
1 | import { useRef } from 'react'
2 | import { useRecoilState, useSetRecoilState } from 'recoil'
3 | import 'highlight.js/styles/github-dark.css';
4 | import { v4 as uuidv4 } from 'uuid';
5 | import { questionFamily } from '../store/atoms/questionFamily';
6 | import { allChats } from '../store/atoms/allChats';
7 | import '../styles/style.css'
8 |
9 | export default function Input(){
10 |
11 | let inputElement=useRef()
12 | let submitBtn=useRef()
13 | let id=useRef(uuidv4());
14 | let setQuestion=useSetRecoilState(questionFamily(id.current))
15 | let [history,setChatHistory]=useRecoilState(allChats);
16 | // have to figure out why this code is breaking whe useSetRecoilState is used, because there's no re-rendering is
17 | // happening in this causing overall no, change in id leading it to breaking
18 |
19 | function handleKeyDown(event){
20 | inputElement.current.value.trim().length!=0?submitBtn.current.classList.remove("disabled"):submitBtn.current.classList.add("disabled")
21 | if (event.key === 'shiftKey') {
22 | event.preventDefault()
23 | if(inputElement.current.value.trim().length!=0){
24 | setQuestion(q=>({...q,question: inputElement.current.value}))
25 | setChatHistory(history=>[...history,{question:id.current,answer:null}])
26 | id.current=uuidv4();
27 | inputElement.current.value="";
28 | submitBtn.current.classList.add("disabled")
29 | }
30 | }
31 | if (event.key === 'Enter') {
32 | event.preventDefault()
33 | if(inputElement.current.value.trim().length!=0){
34 | setQuestion(q=>({...q,question: inputElement.current.value}))
35 | setChatHistory(history=>[...history,{question:id.current,answer:null}])
36 | id.current=uuidv4();
37 | inputElement.current.value="";
38 | submitBtn.current.classList.add("disabled")
39 | }
40 | }
41 | }
42 |
43 | function handleSubmit(){
44 | if(inputElement.current.value!=""){
45 | setQuestion(q=>({...q,question: inputElement.current.value}))
46 | setChatHistory(history=>[...history,{question:id.current,answer:null}])
47 | id.current=uuidv4();
48 | inputElement.current.value="";
49 | submitBtn.current.classList.add("disabled")
50 | }
51 | }
52 |
53 | return