Merge pull request #100 from ajaythapliyal/feature/intro

Adds Hero welcome page, introduces conversation slice and wires conversation UI with redux
pull/102/head
Alex 2 years ago committed by GitHub
commit 63859a814b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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;

@ -1,11 +1,11 @@
// import { configureStore, createSlice } from '@reduxjs/toolkit';
import { configureStore } from '@reduxjs/toolkit'; import { configureStore } from '@reduxjs/toolkit';
import { conversationSlice } from './conversation/conversationSlice';
import { prefSlice } from './preferences/preferenceSlice'; import { prefSlice } from './preferences/preferenceSlice';
const store = configureStore({ const store = configureStore({
reducer: { reducer: {
preference: prefSlice.reducer, preference: prefSlice.reducer,
conversation: conversationSlice.reducer,
}, },
}); });

Loading…
Cancel
Save