diff --git a/docs/package.json b/docs/package.json index 0865c320..048f9a3f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,7 +7,7 @@ "license": "MIT", "dependencies": { "@vercel/analytics": "^1.1.1", - "docsgpt": "^0.3.0", + "docsgpt": "^0.3.6", "next": "^14.0.4", "nextra": "^2.13.2", "nextra-theme-docs": "^2.13.2", diff --git a/docs/pages/Extensions/react-widget.md b/docs/pages/Extensions/react-widget.md index de585581..63688994 100644 --- a/docs/pages/Extensions/react-widget.md +++ b/docs/pages/Extensions/react-widget.md @@ -10,7 +10,6 @@ First, make sure you have Node.js and npm installed in your project. Then go to In the file where you want to use the widget, import it and include the CSS file: ```js import { DocsGPTWidget } from "docsgpt"; -import "docsgpt/dist/style.css"; ``` @@ -20,18 +19,28 @@ Now, you can use the widget in your component like this : apiHost="https://your-docsgpt-api.com" selectDocs="local/docs.zip" apiKey="" + avatar = "https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png", + title = "Get AI assistance", + description = "DocsGPT's AI Chatbot is here to help", + heroTitle = "Welcome to DocsGPT !", + heroDescription="This chatbot is built with DocsGPT and utilises GenAI, + please review important information using sources." /> ``` -DocsGPTWidget takes 3 **props**: +DocsGPTWidget takes 8 **props** with default fallback values: 1. `apiHost` — The URL of your DocsGPT API. 2. `selectDocs` — The documentation source that you want to use for your widget (e.g. `default` or `local/docs1.zip`). 3. `apiKey` — Usually, it's empty. +4. `avatar`: Specifies the URL of the avatar or image representing the chatbot. +5. `title`: Sets the title text displayed in the chatbot interface. +6. `description`: Provides a brief description of the chatbot's purpose or functionality. +7. `heroTitle`: Displays a welcome title when users interact with the chatbot. +8. `heroDescription`: Provide additional introductory text or information about the chatbot's capabilities. ### How to use DocsGPTWidget with [Nextra](https://nextra.site/) (Next.js + MDX) Install your widget as described above and then go to your `pages/` folder and create a new file `_app.js` with the following content: ```js import { DocsGPTWidget } from "docsgpt"; -import "docsgpt/dist/style.css"; export default function MyApp({ Component, pageProps }) { return ( diff --git a/extensions/react-widget/package.json b/extensions/react-widget/package.json index 10469f21..bcf90e12 100644 --- a/extensions/react-widget/package.json +++ b/extensions/react-widget/package.json @@ -1,8 +1,8 @@ { "name": "docsgpt", - "version": "0.3.0", + "version": "0.3.6", "private": false, - "description": "docsgpt ai assistant", + "description": "DocsGPT 🦖 is an innovative open-source tool designed to simplify the retrieval of information from project documentation using advanced GPT models 🤖.", "source": "./src/index.html", "main": "dist/main.js", "module": "dist/module.js", diff --git a/extensions/react-widget/src/components/DocsGPTWidget.tsx b/extensions/react-widget/src/components/DocsGPTWidget.tsx index 2bc57e5f..a84ca675 100644 --- a/extensions/react-widget/src/components/DocsGPTWidget.tsx +++ b/extensions/react-widget/src/components/DocsGPTWidget.tsx @@ -1,12 +1,13 @@ "use client"; import { Fragment, useEffect, useRef, useState } from 'react' -import { PaperPlaneIcon, RocketIcon, ExclamationTriangleIcon, Cross1Icon } from '@radix-ui/react-icons'; +import { PaperPlaneIcon, RocketIcon, ExclamationTriangleIcon, Cross2Icon } from '@radix-ui/react-icons'; import { MESSAGE_TYPE } from '../models/types'; import { Query, Status } from '../models/types'; import MessageIcon from '../assets/message.svg' import { fetchAnswerStreaming } from '../requests/streamingApi'; import styled, { keyframes } from 'styled-components'; const WidgetContainer = styled.div` + display: block; position: fixed; right: 10px; bottom: 10px; @@ -15,24 +16,25 @@ const WidgetContainer = styled.div` flex-direction: column; align-items: center; text-align: left; - width: 356px; - height: 405px; `; const StyledContainer = styled.div` - position: absolute; + display: block; + position: relative; bottom: 0; left: 0; - width: 100%; + width: 352px; + height: 407px; + max-height: 407px; border-radius: 0.75rem; - background-color: rgb(34, 35, 39); - border: 1px solid gray; + background-color: #222327; font-family: sans-serif; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 2px 4px rgba(0, 0, 0, 0.1); transition: visibility 0.3s, opacity 0.3s; `; const FloatingButton = styled.div` - position: absolute; + position: fixed; display: flex; + z-index: 500; justify-content: center; align-items: center; bottom: 1rem; @@ -61,8 +63,9 @@ const CancelButton = styled.button` outline: none; color: inherit; transition: opacity 0.3s ease; + opacity: 0.6; &:hover { - opacity: 0.5; + opacity: 1; } .white-filter { filter: invert(100%); @@ -72,7 +75,9 @@ const CancelButton = styled.button` const Header = styled.div` display: flex; align-items: center; - padding: 0.75rem; + padding-inline: 0.75rem; + padding-top: 1rem; + padding-bottom: 0.5rem; `; const IconWrapper = styled.div` @@ -98,8 +103,8 @@ const Description = styled.p` margin-top: 0; `; const Conversation = styled.div` - height: 18rem; - padding: 0.5rem; + height: 16rem; + padding-inline: 0.5rem; border-radius: 0.375rem; text-align: left; overflow-y: auto; @@ -109,19 +114,19 @@ const Conversation = styled.div` const MessageBubble = styled.div<{ type: MESSAGE_TYPE }>` display: flex; + font-size: 16px; justify-content: ${props => props.type === 'QUESTION' ? 'flex-end' : 'flex-start'}; margin: 0.5rem; `; const Message = styled.p<{ type: MESSAGE_TYPE }>` background: ${props => props.type === 'QUESTION' ? 'linear-gradient(to bottom right, #8860DB, #6D42C5)' : - props => props.type === 'ANSWER' ? - '#38383b' : - ''}; - - color: ${props => props.type != 'ERROR' ? '#ffff' : '#b91c1c'}; - border:${props => props.type !== 'ERROR' ? 'none' : '1px solid #b91c1c'}; + '#38383b'}; + color: #ffff; + border: none; max-width: 80%; + + margin: 4px; display: block; padding: 0.75rem; border-radius: 0.375rem; @@ -151,21 +156,23 @@ const DotAnimation = styled.div` display: inline-block; animation: ${dotBounce} 1s infinite ease-in-out; `; - // delay classes as styled components const Delay = styled(DotAnimation) <{ delay: number }>` animation-delay: ${props => props.delay + 'ms'}; `; const PromptContainer = styled.form` background-color: transparent; - padding: 12px 8px; - opacity: 1; - height: 40px; + height: 36px; + position: absolute; + bottom: 25px; + left: 24px; + right: 24px; display: flex; - justify-content: space-between; + justify-content: space-evenly; `; const StyledInput = styled.input` - width: 80%; + width: 260px; + height: 36px; border: 1px solid #686877; padding-left: 12px; background-color: transparent; @@ -175,19 +182,24 @@ const StyledInput = styled.input` outline: none; `; const StyledButton = styled.button` - color: #ccc; + display: flex; + justify-content: center; + align-items: center; background-image: linear-gradient(to bottom right, #5AF0EC, #E80D9D); border-radius: 6px; - width: 40px; + width: 36px; + height: 36px; + margin-left:8px; + padding: 0px; border: none; cursor: pointer; outline: none; &:hover{ - opacity: 80%; + opacity: 90%; } &:disabled { opacity: 60%; - }` + }`; const HeroContainer = styled.div` position: absolute; top: 50%; @@ -208,7 +220,6 @@ const HeroWrapper = styled.div` font-weight: normal; padding: 6px; display: flex; - justify-content: space-between; ` const HeroTitle = styled.h3` @@ -217,16 +228,12 @@ const HeroTitle = styled.h3` margin-bottom: 5px; padding: 2px; `; - const HeroDescription = styled.p` color: #fff; font-size: 14px; line-height: 1.5; `; -const Avatar = styled.img<{width:number,height:number}>` -max-width: ${props => props.width}; -` -const Hero = ({title,description}:{title:string,description:string}) => { +const Hero = ({ title, description }: { title: string, description: string }) => { return ( <> @@ -247,13 +254,13 @@ const Hero = ({title,description}:{title:string,description:string}) => { }; export const DocsGPTWidget = ({ apiHost = 'https://gptcloud.arc53.com', - selectDocs = 'default', + selectDocs = 'default', apiKey = 'docsgpt-public', avatar = 'https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png', title = 'Get AI assistance', description = 'DocsGPT\'s AI Chatbot is here to help', heroTitle = 'Welcome to DocsGPT !', - heroDescription='This chatbot is built with DocsGPT and utilises GenAI, please review important information using sources.' + heroDescription = 'This chatbot is built with DocsGPT and utilises GenAI, please review important information using sources.' }) => { const [prompt, setPrompt] = useState(''); @@ -334,17 +341,17 @@ export const DocsGPTWidget = ({ return ( <> - setOpen(true)} hidden={open}> - - + {!open && setOpen(true)} hidden={open}> + + } {open &&
setOpen(false)}> - +
- docs-gpt + docs-gpt {title} @@ -352,7 +359,6 @@ export const DocsGPTWidget = ({
-
{ queries.length > 0 ? queries?.map((query, index) => { @@ -399,22 +405,20 @@ export const DocsGPTWidget = ({ } ) }) - : + : } - setPrompt(event.target.value)} type='text' placeholder="What do you want to do?" /> - + - - -
}
diff --git a/extensions/react-widget/src/index.html b/extensions/react-widget/src/index.html index 9928934f..353464c4 100644 --- a/extensions/react-widget/src/index.html +++ b/extensions/react-widget/src/index.html @@ -4,7 +4,7 @@ - React (Parcel + TypeScript) + DocsGPT Widget