mirror of https://github.com/arc53/DocsGPT
Merge pull request #100 from ajaythapliyal/feature/intro
Adds Hero welcome page, introduces conversation slice and wires conversation UI with reduxpull/102/head
commit
63859a814b
@ -0,0 +1,21 @@
|
|||||||
|
export default function Hero({ className = '' }: { className?: string }) {
|
||||||
|
return (
|
||||||
|
<div className={`flex flex-col ${className}`}>
|
||||||
|
<p className="mb-10 text-center text-4xl font-semibold">
|
||||||
|
DocsGPT <span className="text-3xl">🦖</span>
|
||||||
|
</p>
|
||||||
|
<p className="mb-3 text-center">
|
||||||
|
Welcome to DocsGPT, your technical documentation assistant!
|
||||||
|
</p>
|
||||||
|
<p className="mb-3 text-center">
|
||||||
|
Enter a query related to the information in the documentation you
|
||||||
|
selected to receive and we will provide you with the most relevant
|
||||||
|
answers.
|
||||||
|
</p>
|
||||||
|
<p className="text-center">
|
||||||
|
Start by entering your query in the input field below and we will do the
|
||||||
|
rest!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,28 +1,33 @@
|
|||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import Hero from '../Hero';
|
||||||
import ConversationBubble from './ConversationBubble';
|
import ConversationBubble from './ConversationBubble';
|
||||||
import ConversationInput from './ConversationInput';
|
import ConversationInput from './ConversationInput';
|
||||||
|
import { selectConversation } from './conversationSlice';
|
||||||
|
|
||||||
export default function Conversation() {
|
export default function Conversation() {
|
||||||
// uncomment below JSX to see the sample harcoded chat box
|
const messages = useSelector(selectConversation);
|
||||||
|
const endMessageRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => endMessageRef?.current?.scrollIntoView());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center p-6">
|
<div className="flex justify-center p-6">
|
||||||
{/* <div className="w-10/12 transition-all md:w-1/2">
|
<div className="w-10/12 transition-all md:w-1/2">
|
||||||
{new Array(10).fill(1).map((item, index) => {
|
{messages.map((message, index) => {
|
||||||
return (
|
return (
|
||||||
<ConversationBubble
|
<ConversationBubble
|
||||||
className="mt-5"
|
ref={index === messages.length - 1 ? endMessageRef : null}
|
||||||
|
className="mb-7"
|
||||||
key={index}
|
key={index}
|
||||||
user={index % 2 === 0 ? { avatar: '🦖' } : { avatar: '👤' }}
|
message={message.text}
|
||||||
message={
|
type={message.type}
|
||||||
index % 2 === 0
|
|
||||||
? 'A chatbot is a computer program that simulates human conversation through voice commands or text chats or both. It can be integrated with various messaging platforms like Facebook Messenger, WhatsApp, WeChat, etc.'
|
|
||||||
: 'what is DocsGPT'
|
|
||||||
}
|
|
||||||
isCurrentUser={index % 2 === 0 ? false : true}
|
|
||||||
></ConversationBubble>
|
></ConversationBubble>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
{messages.length === 0 && <Hero className="mt-24"></Hero>}
|
||||||
</div>
|
</div>
|
||||||
<ConversationInput className="fixed bottom-2 w-10/12 md:w-[50%]"></ConversationInput> */}
|
<ConversationInput className="fixed bottom-2 w-10/12 md:w-[50%]"></ConversationInput>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
|
import { forwardRef } from 'react';
|
||||||
import Avatar from '../Avatar';
|
import Avatar from '../Avatar';
|
||||||
import { User } from '../models/misc';
|
import { MESSAGE_TYPE } from './conversationModels';
|
||||||
|
|
||||||
export default function ConversationBubble({
|
const ConversationBubble = forwardRef<
|
||||||
user,
|
HTMLDivElement,
|
||||||
message,
|
{
|
||||||
isCurrentUser,
|
|
||||||
className,
|
|
||||||
}: {
|
|
||||||
user: User;
|
|
||||||
message: string;
|
message: string;
|
||||||
isCurrentUser: boolean;
|
type: MESSAGE_TYPE;
|
||||||
className: string;
|
className: string;
|
||||||
}) {
|
}
|
||||||
|
>(function ConversationBubble({ message, type, className }, ref) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
ref={ref}
|
||||||
className={`flex rounded-3xl ${
|
className={`flex rounded-3xl ${
|
||||||
isCurrentUser ? '' : 'bg-gray-1000'
|
type === 'QUESTION' ? '' : 'bg-gray-1000'
|
||||||
} py-7 px-5 ${className}`}
|
} py-7 px-5 ${className}`}
|
||||||
>
|
>
|
||||||
<Avatar avatar={user.avatar}></Avatar>
|
<Avatar avatar={type === 'QUESTION' ? '👤' : '🦖'}></Avatar>
|
||||||
<p className="ml-5">{message}</p>
|
<p className="ml-5">{message}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
|
export default ConversationBubble;
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
export type MESSAGE_TYPE = 'QUESTION' | 'ANSWER';
|
||||||
|
|
||||||
|
export interface Message {
|
||||||
|
text: string;
|
||||||
|
type: MESSAGE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConversationState {
|
||||||
|
conversation: Message[];
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
import store from '../store';
|
||||||
|
import { ConversationState, Message } from './conversationModels';
|
||||||
|
|
||||||
|
// harcoding the initial state just for demo
|
||||||
|
const initialState: ConversationState = {
|
||||||
|
conversation: [
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{ text: 'ChatGPT is large learning model', type: 'ANSWER' },
|
||||||
|
{ text: 'what is ChatGPT', type: 'QUESTION' },
|
||||||
|
{
|
||||||
|
text: 'ChatGPT is large learning model',
|
||||||
|
type: 'ANSWER',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const conversationSlice = createSlice({
|
||||||
|
name: 'conversation',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
addMessage(state, action: PayloadAction<Message>) {
|
||||||
|
state.conversation.push(action.payload);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { addMessage } = conversationSlice.actions;
|
||||||
|
|
||||||
|
type RootState = ReturnType<typeof store.getState>;
|
||||||
|
export const selectConversation = (state: RootState) =>
|
||||||
|
state.conversation.conversation;
|
||||||
|
|
||||||
|
export default conversationSlice.reducer;
|
Loading…
Reference in New Issue