Skip to content

Commit

Permalink
Merge pull request #1528 from ManishMadan2882/basic-ui
Browse files Browse the repository at this point in the history
Basic UI
  • Loading branch information
dartpain authored Jan 13, 2025
2 parents 628784d + 54819e2 commit 99e0766
Show file tree
Hide file tree
Showing 23 changed files with 619 additions and 327 deletions.
2 changes: 1 addition & 1 deletion application/api/user/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ def get(self):
user = "local"
data = [
{
"name": "default",
"name": "Default",
"date": "default",
"model": settings.EMBEDDINGS_NAME,
"location": "remote",
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ export default function Hero({
<Fragment key={key}>
<button
onClick={() => handleQuestion({ question: demo.query })}
className="w-full rounded-full border border-silver px-6 py-4 text-left hover:border-gray-4000 dark:hover:border-gray-3000 xl:min-w-[24vw]"
className="w-full rounded-full border border-silver px-6 py-4 text-left hover:border-gray-4000 dark:hover:border-gray-3000 xl:min-w-[24vw] bg-white dark:bg-raisin-black focus:outline-none focus:ring-2 focus:ring-purple-taupe"
>
<p className="mb-1 font-semibold text-black dark:text-silver">
<p className="mb-1 font-semibold text-black-1000 dark:text-bright-gray">
{demo.header}
</p>
<span className="text-gray-400">{demo.query}</span>
<span className="text-gray-700 dark:text-gray-300">
{demo.query}
</span>
</button>
</Fragment>
),
Expand Down
39 changes: 13 additions & 26 deletions frontend/src/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ import {
handleAbort,
} from './conversation/conversationSlice';
import ConversationTile from './conversation/ConversationTile';
import { useDarkTheme, useMediaQuery, useOutsideAlerter } from './hooks';
import { useDarkTheme, useMediaQuery } from './hooks';
import useDefaultDocument from './hooks/useDefaultDocument';
import DeleteConvModal from './modals/DeleteConvModal';
import { ActiveState, Doc } from './models/misc';
import APIKeyModal from './preferences/APIKeyModal';
import { getConversations, getDocs } from './preferences/preferenceApi';
import {
selectApiKeyStatus,
Expand Down Expand Up @@ -68,8 +67,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
const [isDocsListOpen, setIsDocsListOpen] = useState(false);
const { t } = useTranslation();
const isApiKeySet = useSelector(selectApiKeyStatus);
const [apiKeyModalState, setApiKeyModalState] =
useState<ActiveState>('INACTIVE');

const [uploadModalState, setUploadModalState] =
useState<ActiveState>('INACTIVE');
Expand Down Expand Up @@ -192,12 +189,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
console.error(err);
});
}
useOutsideAlerter(navRef, () => {
if (isMobile && navOpen && apiKeyModalState === 'INACTIVE') {
setNavOpen(false);
setIsDocsListOpen(false);
}
}, [navOpen, isDocsListOpen, apiKeyModalState]);

/*
Needed to fix bug where if mobile nav was closed and then window was resized to desktop, nav would still be closed but the button to open would be gone, as per #1 on issue #146
Expand All @@ -220,7 +211,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={Expand}
alt="menu toggle"
alt="Toggle navigation menu"
className={`${
!navOpen ? 'rotate-180' : 'rotate-0'
} m-auto transition-all duration-200`}
Expand All @@ -234,7 +225,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={openNewChat}
alt="open new chat icon"
alt="Start new chat"
className="cursor-pointer"
/>
</button>
Expand Down Expand Up @@ -263,7 +254,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
}}
>
<a href="/" className="flex gap-1.5">
<img className="mb-2 h-10" src={DocsGPT3} alt="" />
<img className="mb-2 h-10" src={DocsGPT3} alt="DocsGPT Logo" />
<p className="my-auto text-2xl font-semibold">DocsGPT</p>
</a>
</div>
Expand All @@ -275,7 +266,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={Expand}
alt="menu toggle"
alt="Toggle navigation menu"
className={`${
!navOpen ? 'rotate-180' : 'rotate-0'
} m-auto transition-all duration-200`}
Expand All @@ -298,7 +289,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={Add}
alt="new"
alt="Create new chat"
className="opacity-80 group-hover:opacity-100"
/>
<p className=" text-sm text-dove-gray group-hover:text-neutral-600 dark:text-chinese-silver dark:group-hover:text-bright-gray">
Expand All @@ -314,7 +305,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
<img
src={isDarkTheme ? SpinnerDark : Spinner}
className="animate-spin cursor-pointer bg-transparent"
alt="Loading..."
alt="Loading conversations"
/>
</div>
)}
Expand Down Expand Up @@ -365,6 +356,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
<img
className="mt-2 h-9 w-9 hover:cursor-pointer"
src={UploadIcon}
alt="Upload document"
onClick={() => {
setUploadModalState('ACTIVE');
if (isMobile) {
Expand Down Expand Up @@ -392,7 +384,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={SettingGear}
alt="icon"
alt="Settings"
className="ml-2 w-5 filter dark:invert"
/>
<p className="my-auto text-sm text-eerie-black dark:text-white">
Expand All @@ -414,7 +406,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={Discord}
alt="discord"
alt="Join Discord community"
className="m-2 w-6 self-center filter dark:invert"
/>
</NavLink>
Expand All @@ -427,7 +419,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={Twitter}
alt="x"
alt="Follow us on Twitter"
className="m-2 w-5 self-center filter dark:invert"
/>
</NavLink>
Expand All @@ -440,7 +432,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={Github}
alt="github"
alt="View on GitHub"
className="m-2 w-6 self-center filter dark:invert"
/>
</NavLink>
Expand All @@ -457,18 +449,13 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
>
<img
src={Hamburger}
alt="menu toggle"
alt="Toggle mobile menu"
className="w-7 filter dark:invert"
/>
</button>
<div className="text-[#949494] font-medium text-[20px]">DocsGPT</div>
</div>
</div>
<APIKeyModal
modalState={apiKeyModalState}
setModalState={setApiKeyModalState}
isCancellable={isApiKeySet}
/>
<DeleteConvModal
modalState={modalStateDeleteConv}
setModalState={setModalStateDeleteConv}
Expand Down
18 changes: 13 additions & 5 deletions frontend/src/components/SettingsBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,31 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
<div className="md:hidden z-10">
<button
onClick={() => scrollTabs(-1)}
className="flex h-6 w-6 items-center rounded-full justify-center transition-all hover:bg-gray-100"
className="flex h-6 w-6 items-center rounded-full justify-center transition-all hover:bg-gray-200 dark:hover:bg-gray-700"
aria-label="Scroll tabs left"
>
<img src={ArrowLeft} alt="left-arrow" className="h-3" />
</button>
</div>
<div
ref={containerRef}
className="flex flex-nowrap overflow-x-auto no-scrollbar md:space-x-4 scroll-smooth snap-x"
role="tablist"
aria-label="Settings tabs"
>
{tabs.map((tab, index) => (
<button
key={index}
onClick={() => setActiveTab(tab)}
className={`snap-start h-9 rounded-3xl px-4 font-bold hover:text-neutral-600 dark:hover:text-white/60 ${
className={`snap-start h-9 rounded-3xl px-4 font-bold transition-colors ${
activeTab === tab
? 'bg-neutral-100 text-neutral-600 dark:bg-dark-charcoal dark:text-white/60'
: 'text-gray-6000'
? 'bg-neutral-200 text-neutral-900 dark:bg-dark-charcoal dark:text-white'
: 'text-neutral-700 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-white'
}`}
role="tab"
aria-selected={activeTab === tab}
aria-controls={`${tab.toLowerCase()}-panel`}
id={`${tab.toLowerCase()}-tab`}
>
{tab}
</button>
Expand All @@ -85,7 +92,8 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
<div className="md:hidden z-10">
<button
onClick={() => scrollTabs(1)}
className="flex h-6 w-6 rounded-full items-center justify-center hover:bg-gray-100"
className="flex h-6 w-6 rounded-full items-center justify-center hover:bg-gray-200 dark:hover:bg-gray-700"
aria-label="Scroll tabs right"
>
<img src={ArrowRight} alt="right-arrow" className="h-3" />
</button>
Expand Down
30 changes: 22 additions & 8 deletions frontend/src/conversation/Conversation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -386,33 +386,47 @@ export default function Conversation() {
{...getRootProps()}
className="flex w-full items-center rounded-[40px] border border-silver bg-white dark:bg-raisin-black"
>
<input {...getInputProps()}></input>
<label htmlFor="file-upload" className="sr-only">
{t('modals.uploadDoc.label')}
</label>
<input {...getInputProps()} id="file-upload" />
<label htmlFor="message-input" className="sr-only">
{t('inputPlaceholder')}
</label>
<textarea
id="inputbox"
id="message-input"
ref={inputRef}
tabIndex={1}
placeholder={t('inputPlaceholder')}
className={`inputbox-style w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-full bg-transparent py-5 text-base leading-tight opacity-100 focus:outline-none dark:bg-transparent dark:text-bright-gray`}
className={`inputbox-style w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-full bg-transparent py-5 text-base leading-tight opacity-100 focus:outline-none dark:bg-transparent dark:text-bright-gray dark:placeholder-bright-gray dark:placeholder-opacity-50`}
onInput={handleInput}
onKeyDown={(e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleQuestionSubmission();
}
}}
aria-label={t('inputPlaceholder')}
></textarea>
{status === 'loading' ? (
<img
src={isDarkTheme ? SpinnerDark : Spinner}
className="relative right-[38px] bottom-[24px] -mr-[30px] animate-spin cursor-pointer self-end bg-transparent"
></img>
alt={t('loading')}
/>
) : (
<div className="mx-1 cursor-pointer rounded-full p-3 text-center hover:bg-gray-3000 dark:hover:bg-dark-charcoal">
<img
className="ml-[4px] h-6 w-6 text-white "
<button
onClick={() => handleQuestionSubmission()}
src={isDarkTheme ? SendDark : Send}
></img>
aria-label={t('send')}
className="flex items-center justify-center"
>
<img
className="ml-[4px] h-6 w-6 text-white"
src={isDarkTheme ? SendDark : Send}
alt={t('send')}
/>
</button>
</div>
)}
</div>
Expand Down
36 changes: 23 additions & 13 deletions frontend/src/conversation/ConversationBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import rehypeKatex from 'rehype-katex';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import { useTranslation } from 'react-i18next';

import DocsGPT3 from '../assets/cute_docsgpt3.svg';
import Dislike from '../assets/dislike.svg?react';
Expand Down Expand Up @@ -62,6 +63,7 @@ const ConversationBubble = forwardRef<
},
ref,
) {
const { t } = useTranslation();
// const bubbleRef = useRef<HTMLDivElement | null>(null);
const chunks = useSelector(selectChunks);
const selectedDocs = useSelector(selectSelectedDocs);
Expand Down Expand Up @@ -113,13 +115,13 @@ const ConversationBubble = forwardRef<
{isEditClicked && (
<div ref={editableQueryRef} className="w-[75%] flex flex-col">
<textarea
placeholder="Type the updated query..."
placeholder={t('conversation.edit.placeholder')}
onChange={(e) => {
setEditInputBox(e.target.value);
}}
rows={1}
value={editInputBox}
className="ml-2 mr-12 text-[15px] resize-y h-12 min-h-max rounded-3xl p-3 no-scrollbar leading-relaxed dark:border-[0.5px] dark:border-white dark:bg-raisin-black dark:text-white px-[18px] border-[1.5px] border-black"
className="ml-2 mr-12 text-[15px] resize-y h-12 min-h-max rounded-3xl p-3 no-scrollbar leading-relaxed dark:border-[0.5px] dark:border-white dark:bg-raisin-black dark:text-white px-[18px] border-[1.5px] border-black"
/>
<div
className={`flex flex-row-reverse justify-end gap-1 mt-3 text-sm font-medium`}
Expand Down Expand Up @@ -185,12 +187,14 @@ const ConversationBubble = forwardRef<
avatar={
<img
src={Sources}
alt="Sources"
alt={t('conversation.sources.title')}
className="h-full w-full object-fill"
/>
}
/>
<p className="text-base font-semibold">Sources</p>
<p className="text-base font-semibold">
{t('conversation.sources.title')}
</p>
</div>
<div className="grid grid-cols-2 gap-2 lg:grid-cols-4">
{Array.from({ length: 4 }).map((_, index) => (
Expand All @@ -217,12 +221,14 @@ const ConversationBubble = forwardRef<
avatar={
<img
src={Sources}
alt="Sources"
alt={t('conversation.sources.title')}
className="h-full w-full object-fill"
/>
}
/>
<p className="text-base font-semibold">Sources</p>
<p className="text-base font-semibold">
{t('conversation.sources.title')}
</p>
</div>
<div className="fade-in ml-3 mr-5 max-w-[90vw] md:max-w-[70vw] lg:max-w-[50vw]">
<div className="grid grid-cols-2 gap-2 lg:grid-cols-4">
Expand Down Expand Up @@ -289,9 +295,11 @@ const ConversationBubble = forwardRef<
className="flex h-28 cursor-pointer flex-col-reverse rounded-[20px] bg-gray-1000 p-4 text-purple-30 hover:bg-[#F1F1F1] hover:text-[#6D3ECC] dark:bg-gun-metal dark:hover:bg-[#2C2E3C] dark:hover:text-[#8C67D7]"
onClick={() => setIsSidebarOpen(true)}
>
<p className="ellipsis-text h-22 text-xs">{`View ${
sources?.length ? sources.length - 3 : 0
} more`}</p>
<p className="ellipsis-text h-22 text-xs">
{t('conversation.sources.view_more', {
count: sources?.length ? sources.length - 3 : 0,
})}
</p>
</div>
)}
</div>
Expand All @@ -306,12 +314,14 @@ const ConversationBubble = forwardRef<
avatar={
<img
src={DocsGPT3}
alt="DocsGPT"
alt={t('conversation.answer')}
className="h-full w-full object-cover"
/>
}
/>
<p className="text-base font-semibold">Answer</p>
<p className="text-base font-semibold">
{t('conversation.answer')}
</p>
</div>
<div
className={`fade-in-bubble ml-2 mr-5 flex max-w-[90vw] rounded-[28px] bg-gray-1000 py-[14px] px-7 dark:bg-gun-metal md:max-w-[70vw] lg:max-w-[50vw] ${
Expand Down Expand Up @@ -419,7 +429,7 @@ const ConversationBubble = forwardRef<
${type !== 'ERROR' ? 'group-hover:lg:visible' : 'hidden'}`}
>
<div>
<SpeakButton text={message} /> {/* Add SpeakButton here */}
<SpeakButton text={message} />
</div>
</div>
{type === 'ERROR' && (
Expand Down Expand Up @@ -557,7 +567,7 @@ function AllSources(sources: AllSourcesProps) {
{source.source && source.source !== 'local' ? (
<img
src={Link}
alt="Link"
alt={'Link'}
className="h-3 w-3 cursor-pointer object-fill"
onClick={() =>
window.open(source.source, '_blank', 'noopener, noreferrer')
Expand Down
Loading

0 comments on commit 99e0766

Please sign in to comment.