mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-30 09:03:15 +00:00
lint
This commit is contained in:
@@ -5,7 +5,7 @@ import DocsGPT3 from './assets/cute_docsgpt3.svg';
|
||||
export default function About() {
|
||||
return (
|
||||
<div className="mx-5 grid min-h-screen md:mx-36">
|
||||
<article className="place-items-left mx-auto my-auto flex w-full max-w-6xl flex-col gap-4 rounded-3xl bg-gray-100 dark:bg-gun-metal p-6 text-jet dark:text-bright-gray lg:p-6 xl:p-10">
|
||||
<article className="place-items-left mx-auto my-auto flex w-full max-w-6xl flex-col gap-4 rounded-3xl bg-gray-100 p-6 text-jet dark:bg-gun-metal dark:text-bright-gray lg:p-6 xl:p-10">
|
||||
<div className="flex items-center">
|
||||
<p className="mr-2 text-3xl">About DocsGPT</p>
|
||||
<img className="h14 mb-2" src={DocsGPT3} alt="DocsGPT" />
|
||||
@@ -31,23 +31,34 @@ export default function About() {
|
||||
</p>
|
||||
<p className="mt-4 ml-2">
|
||||
1. Navigate to{' '}
|
||||
<span className="bg-gray-200 dark:bg-outer-space italic"> /application</span> folder
|
||||
<span className="bg-gray-200 italic dark:bg-outer-space">
|
||||
{' '}
|
||||
/application
|
||||
</span>{' '}
|
||||
folder
|
||||
</p>
|
||||
<p className="mt-4 ml-2">
|
||||
2. Install dependencies from{' '}
|
||||
<span className="bg-gray-200 dark:bg-outer-space italic">
|
||||
<span className="bg-gray-200 italic dark:bg-outer-space">
|
||||
pip install -r requirements.txt
|
||||
</span>
|
||||
</p>
|
||||
<p className="mt-4 ml-2">
|
||||
3. Prepare a <span className="bg-gray-200 dark:bg-outer-space italic">.env</span> file.
|
||||
Copy <span className="bg-gray-200 dark:bg-outer-space italic">.env_sample</span> and
|
||||
create <span className="bg-gray-200 dark:bg-outer-space italic">.env</span> with your
|
||||
OpenAI API token
|
||||
3. Prepare a{' '}
|
||||
<span className="bg-gray-200 italic dark:bg-outer-space">.env</span>{' '}
|
||||
file. Copy{' '}
|
||||
<span className="bg-gray-200 italic dark:bg-outer-space">
|
||||
.env_sample
|
||||
</span>{' '}
|
||||
and create{' '}
|
||||
<span className="bg-gray-200 italic dark:bg-outer-space">.env</span>{' '}
|
||||
with your OpenAI API token
|
||||
</p>
|
||||
<p className="mt-4 ml-2">
|
||||
4. Run the app with{' '}
|
||||
<span className="bg-gray-200 dark:bg-outer-space italic">python app.py</span>
|
||||
<span className="bg-gray-200 italic dark:bg-outer-space">
|
||||
python app.py
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import About from './About';
|
||||
import PageNotFound from './PageNotFound';
|
||||
import { inject } from '@vercel/analytics';
|
||||
import { useMediaQuery } from './hooks';
|
||||
import { useState} from 'react';
|
||||
import { useState } from 'react';
|
||||
import Setting from './Setting';
|
||||
|
||||
inject();
|
||||
@@ -32,4 +32,4 @@ export default function App() {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,14 @@ import DocsGPT3 from './assets/cute_docsgpt3.svg';
|
||||
export default function Hero({ className = '' }: { className?: string }) {
|
||||
// const isMobile = window.innerWidth <= 768;
|
||||
const { isMobile } = useMediaQuery();
|
||||
const [isDarkTheme] = useDarkTheme()
|
||||
const [isDarkTheme] = useDarkTheme();
|
||||
return (
|
||||
<div className={`mt-14 ${isMobile ? 'mb-2' : 'mb-12'} flex flex-col text-black-1000 dark:text-bright-gray`}>
|
||||
<div
|
||||
className={`mt-14 ${
|
||||
isMobile ? 'mb-2' : 'mb-12'
|
||||
} flex flex-col text-black-1000 dark:text-bright-gray`}
|
||||
>
|
||||
<div className=" mb-2 flex items-center justify-center sm:mb-10">
|
||||
|
||||
<p className="mr-2 text-4xl font-semibold">DocsGPT</p>
|
||||
<img className="mb-2 h-14" src={DocsGPT3} alt="DocsGPT" />
|
||||
</div>
|
||||
@@ -36,20 +39,24 @@ export default function Hero({ className = '' }: { className?: string }) {
|
||||
</>
|
||||
)}
|
||||
<div
|
||||
className={`sections ${isMobile ? '' : 'mt-1'
|
||||
} flex flex-wrap items-center justify-center gap-2 sm:gap-1 md:gap-0`}
|
||||
className={`sections ${
|
||||
isMobile ? '' : 'mt-1'
|
||||
} flex flex-wrap items-center justify-center gap-2 sm:gap-1 md:gap-0`}
|
||||
>
|
||||
{/* first */}
|
||||
<div className="h-auto md:h-60 rounded-[50px] bg-gradient-to-l from-[#6EE7B7]/70 dark:from-[#D16FF8] via-[#3B82F6] dark:via-[#48E6E0] to-[#9333EA]/50 dark:to-[#C85EF6] p-1 md:rounded-tr-none md:rounded-br-none">
|
||||
<div className="h-auto rounded-[50px] bg-gradient-to-l from-[#6EE7B7]/70 via-[#3B82F6] to-[#9333EA]/50 p-1 dark:from-[#D16FF8] dark:via-[#48E6E0] dark:to-[#C85EF6] md:h-60 md:rounded-tr-none md:rounded-br-none">
|
||||
<div
|
||||
className={`h-full rounded-[45px] bg-white dark:bg-dark-charcoal p-${isMobile ? '3.5' : '6 py-8'
|
||||
} md:rounded-tr-none md:rounded-br-none`}
|
||||
className={`h-full rounded-[45px] bg-white dark:bg-dark-charcoal p-${
|
||||
isMobile ? '3.5' : '6 py-8'
|
||||
} md:rounded-tr-none md:rounded-br-none`}
|
||||
>
|
||||
{/* Add Mobile check here */}
|
||||
{isMobile ? (
|
||||
<div className="flex justify-center">
|
||||
<img
|
||||
src={isDarkTheme ? "/message-text-dark.svg" : "/message-text.svg"}
|
||||
src={
|
||||
isDarkTheme ? '/message-text-dark.svg' : '/message-text.svg'
|
||||
}
|
||||
alt="lock"
|
||||
className="h-[24px] w-[24px] "
|
||||
/>
|
||||
@@ -60,7 +67,9 @@ export default function Hero({ className = '' }: { className?: string }) {
|
||||
) : (
|
||||
<>
|
||||
<img
|
||||
src={isDarkTheme ? "/message-text-dark.svg" : "/message-text.svg"}
|
||||
src={
|
||||
isDarkTheme ? '/message-text-dark.svg' : '/message-text.svg'
|
||||
}
|
||||
alt="lock"
|
||||
className="h-[24px] w-[24px]"
|
||||
/>
|
||||
@@ -84,22 +93,31 @@ export default function Hero({ className = '' }: { className?: string }) {
|
||||
</div>
|
||||
</div>
|
||||
{/* second */}
|
||||
<div className="h-auto md:h-60 rounded-[50px] bg-gradient-to-r from-[#6EE7B7]/70 dark:from-[#D16FF8] via-[#3B82F6] dark:via-[#48E6E0] to-[#9333EA]/50 dark:to-[#C85EF6] p-1 md:rounded-none md:py-1 md:px-0">
|
||||
<div className="h-auto rounded-[50px] bg-gradient-to-r from-[#6EE7B7]/70 via-[#3B82F6] to-[#9333EA]/50 p-1 dark:from-[#D16FF8] dark:via-[#48E6E0] dark:to-[#C85EF6] md:h-60 md:rounded-none md:py-1 md:px-0">
|
||||
<div
|
||||
className={`h-full rounded-[45px] bg-white dark:bg-dark-charcoal p-${isMobile ? '3.5' : '6 py-6'
|
||||
} md:rounded-none`}
|
||||
className={`h-full rounded-[45px] bg-white dark:bg-dark-charcoal p-${
|
||||
isMobile ? '3.5' : '6 py-6'
|
||||
} md:rounded-none`}
|
||||
>
|
||||
{/* Add Mobile check here */}
|
||||
{isMobile ? (
|
||||
<div className="flex justify-center ">
|
||||
<img src={isDarkTheme ? "/lock-dark.svg" : "/lock.svg"} alt="lock" className="h-[24px] w-[24px]" />
|
||||
<img
|
||||
src={isDarkTheme ? '/lock-dark.svg' : '/lock.svg'}
|
||||
alt="lock"
|
||||
className="h-[24px] w-[24px]"
|
||||
/>
|
||||
<h2 className="mb-0 pl-1 text-lg font-bold">
|
||||
Secure Data Storage
|
||||
</h2>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<img src={isDarkTheme ? "/lock-dark.svg" : "/lock.svg"} alt="lock" className="h-[24px] w-[24px]" />
|
||||
<img
|
||||
src={isDarkTheme ? '/lock-dark.svg' : '/lock.svg'}
|
||||
alt="lock"
|
||||
className="h-[24px] w-[24px]"
|
||||
/>
|
||||
<h2 className="mt-2 mb-3 text-lg font-bold">
|
||||
Secure Data Storage
|
||||
</h2>
|
||||
@@ -120,16 +138,21 @@ export default function Hero({ className = '' }: { className?: string }) {
|
||||
</div>
|
||||
</div>
|
||||
{/* third */}
|
||||
<div className="h-auto md:h-60 rounded-[50px] bg-gradient-to-l from-[#6EE7B7]/70 dark:from-[#D16FF8] via-[#3B82F6] dark:via-[#48E6E0] to-[#9333EA]/50 dark:to-[#C85EF6] p-1 md:rounded-tl-none md:rounded-bl-none ">
|
||||
<div className="h-auto rounded-[50px] bg-gradient-to-l from-[#6EE7B7]/70 via-[#3B82F6] to-[#9333EA]/50 p-1 dark:from-[#D16FF8] dark:via-[#48E6E0] dark:to-[#C85EF6] md:h-60 md:rounded-tl-none md:rounded-bl-none ">
|
||||
<div
|
||||
className={`h-full firefox rounded-[45px] bg-white dark:bg-dark-charcoal p-${isMobile ? '3.5' : '6 px-6 '
|
||||
} lg:rounded-tl-none lg:rounded-bl-none`}
|
||||
className={`firefox h-full rounded-[45px] bg-white dark:bg-dark-charcoal p-${
|
||||
isMobile ? '3.5' : '6 px-6 '
|
||||
} lg:rounded-tl-none lg:rounded-bl-none`}
|
||||
>
|
||||
{/* Add Mobile check here */}
|
||||
{isMobile ? (
|
||||
<div className="flex justify-center">
|
||||
<img
|
||||
src={isDarkTheme ? "message-programming-dark.svg" : "/message-programming.svg"}
|
||||
src={
|
||||
isDarkTheme
|
||||
? 'message-programming-dark.svg'
|
||||
: '/message-programming.svg'
|
||||
}
|
||||
alt="lock"
|
||||
className="h-[24px] w-[24px]"
|
||||
/>
|
||||
@@ -140,7 +163,11 @@ export default function Hero({ className = '' }: { className?: string }) {
|
||||
) : (
|
||||
<>
|
||||
<img
|
||||
src={isDarkTheme ? "/message-programming-dark.svg" : "/message-programming.svg"}
|
||||
src={
|
||||
isDarkTheme
|
||||
? '/message-programming-dark.svg'
|
||||
: '/message-programming.svg'
|
||||
}
|
||||
alt="lock"
|
||||
className="h-[24px] w-[24px]"
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import Arrow2 from './assets/dropdown-arrow.svg';
|
||||
import ArrowLeft from './assets/arrow-left.svg';
|
||||
import ArrowRight from './assets/arrow-right.svg';
|
||||
import Trash from './assets/trash.svg';
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
updateQuery,
|
||||
} from './conversationSlice';
|
||||
import Send from './../assets/send.svg';
|
||||
import SendDark from './../assets/send_dark.svg'
|
||||
import SendDark from './../assets/send_dark.svg';
|
||||
import Spinner from './../assets/spinner.svg';
|
||||
import { FEEDBACK, Query } from './conversationModels';
|
||||
import { sendFeedback } from './conversationApi';
|
||||
@@ -29,9 +29,8 @@ export default function Conversation() {
|
||||
const [eventInterrupt, setEventInterrupt] = useState(false);
|
||||
|
||||
const handleUserInterruption = () => {
|
||||
if (!eventInterrupt && status === "loading")
|
||||
setEventInterrupt(true)
|
||||
}
|
||||
if (!eventInterrupt && status === 'loading') setEventInterrupt(true);
|
||||
};
|
||||
useEffect(() => {
|
||||
!eventInterrupt && scrollIntoView();
|
||||
}, [queries.length, queries[queries.length - 1]]);
|
||||
@@ -48,8 +47,8 @@ export default function Conversation() {
|
||||
if (status !== 'idle') {
|
||||
fetchStream.current && fetchStream.current.abort(); //abort previous stream
|
||||
}
|
||||
}
|
||||
}, [status])
|
||||
};
|
||||
}, [status]);
|
||||
|
||||
useEffect(() => {
|
||||
const observerCallback: IntersectionObserverCallback = (entries) => {
|
||||
@@ -76,12 +75,12 @@ export default function Conversation() {
|
||||
behavior: 'smooth',
|
||||
block: 'start',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleQuestion = (question: string) => {
|
||||
question = question.trim();
|
||||
if (question === '') return;
|
||||
setEventInterrupt(false)
|
||||
setEventInterrupt(false);
|
||||
dispatch(addQuery({ prompt: question }));
|
||||
fetchStream.current = dispatch(fetchAnswer({ question }));
|
||||
};
|
||||
@@ -134,12 +133,13 @@ export default function Conversation() {
|
||||
<div
|
||||
onWheel={handleUserInterruption}
|
||||
onTouchMove={handleUserInterruption}
|
||||
className="flex flex-col justify-center w-full p-4 md:flex-row">
|
||||
className="flex w-full flex-col justify-center p-4 md:flex-row"
|
||||
>
|
||||
{queries.length > 0 && !hasScrolledToLast && (
|
||||
<button
|
||||
onClick={scrollIntoView}
|
||||
aria-label="scroll to bottom"
|
||||
className="fixed bottom-32 right-14 z-10 flex h-7 w-7 items-center justify-center rounded-full border-[0.5px] border-gray-alpha bg-gray-100 dark:bg-purple-taupe bg-opacity-50 md:h-9 md:w-9 md:bg-opacity-100 "
|
||||
className="fixed bottom-32 right-14 z-10 flex h-7 w-7 items-center justify-center rounded-full border-[0.5px] border-gray-alpha bg-gray-100 bg-opacity-50 dark:bg-purple-taupe md:h-9 md:w-9 md:bg-opacity-100 "
|
||||
>
|
||||
<img
|
||||
src={ArrowDown}
|
||||
@@ -155,7 +155,7 @@ export default function Conversation() {
|
||||
return (
|
||||
<Fragment key={index}>
|
||||
<ConversationBubble
|
||||
className={'last:mb-28 mb-7'}
|
||||
className={'mb-7 last:mb-28'}
|
||||
key={`${index}QUESTION`}
|
||||
message={query.prompt}
|
||||
type="QUESTION"
|
||||
@@ -167,10 +167,8 @@ export default function Conversation() {
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{queries.length === 0 && (
|
||||
<Hero className="mt-24 md:mt-52"></Hero>
|
||||
)}
|
||||
<div className="absolute bottom-0 flex w-11/12 md:w-[65%] flex-col items-end self-center bg-white dark:bg-raisin-black pt-4 md:fixed">
|
||||
{queries.length === 0 && <Hero className="mt-24 md:mt-52"></Hero>}
|
||||
<div className="absolute bottom-0 flex w-11/12 flex-col items-end self-center bg-white pt-4 dark:bg-raisin-black md:fixed md:w-[65%]">
|
||||
<div className="flex h-full w-full">
|
||||
<div
|
||||
id="inputbox"
|
||||
@@ -179,7 +177,7 @@ export default function Conversation() {
|
||||
placeholder="Type your message here..."
|
||||
contentEditable
|
||||
onPaste={handlePaste}
|
||||
className={`border-000000 overflow-x-hidden max-h-24 min-h-[2.6rem] w-full overflow-y-auto whitespace-pre-wrap rounded-3xl border bg-white dark:bg-raisin-black dark:text-bright-gray py-2 pl-4 pr-9 text-base leading-7 opacity-100 focus:outline-none`}
|
||||
className={`border-000000 max-h-24 min-h-[2.6rem] w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-3xl border bg-white py-2 pl-4 pr-9 text-base leading-7 opacity-100 focus:outline-none dark:bg-raisin-black dark:text-bright-gray`}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
@@ -210,7 +208,7 @@ export default function Conversation() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-gray-595959 dark:text-bright-gray bg-white dark:bg-raisin-black w-[100vw] self-center bg-transparent p-5 text-center text-xs md:w-full">
|
||||
<p className="text-gray-595959 w-[100vw] self-center bg-white bg-transparent p-5 text-center text-xs dark:bg-raisin-black dark:text-bright-gray md:w-full">
|
||||
DocsGPT uses GenAI, please review critial information using sources.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -63,9 +63,9 @@ const ConversationBubble = forwardRef<
|
||||
bubble = (
|
||||
<div
|
||||
ref={ref}
|
||||
className={`flex self-start flex-wrap ${className} group flex-col pr-20 dark:text-bright-gray`}
|
||||
className={`flex flex-wrap self-start ${className} group flex-col pr-20 dark:text-bright-gray`}
|
||||
>
|
||||
<div className="flex self-start flex-wrap lg:flex-nowrap">
|
||||
<div className="flex flex-wrap self-start lg:flex-nowrap">
|
||||
<Avatar
|
||||
className="mt-2 h-12 w-12 text-2xl"
|
||||
avatar={
|
||||
@@ -78,10 +78,11 @@ const ConversationBubble = forwardRef<
|
||||
/>
|
||||
|
||||
<div
|
||||
className={`ml-2 lg:max-w-[50vw] md:max-w-[70vw] max-w-[90vw] mr-5 flex rounded-3xl bg-gray-1000 dark:bg-gun-metal p-3.5 ${type === 'ERROR'
|
||||
? 'flex-row items-center rounded-full border border-transparent bg-[#FFE7E7] p-2 py-5 text-sm font-normal text-red-3000 dark:border-red-2000 dark:text-white'
|
||||
: 'flex-col rounded-3xl'
|
||||
}`}
|
||||
className={`ml-2 mr-5 flex max-w-[90vw] rounded-3xl bg-gray-1000 p-3.5 dark:bg-gun-metal md:max-w-[70vw] lg:max-w-[50vw] ${
|
||||
type === 'ERROR'
|
||||
? 'flex-row items-center rounded-full border border-transparent bg-[#FFE7E7] p-2 py-5 text-sm font-normal text-red-3000 dark:border-red-2000 dark:text-white'
|
||||
: 'flex-col rounded-3xl'
|
||||
}`}
|
||||
>
|
||||
{type === 'ERROR' && (
|
||||
<img src={Alert} alt="alert" className="mr-2 inline" />
|
||||
@@ -168,19 +169,21 @@ const ConversationBubble = forwardRef<
|
||||
{sources?.map((source, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`max-w-fit cursor-pointer rounded-[28px] py-1 px-4 ${openSource === index
|
||||
? 'bg-[#007DFF]'
|
||||
: 'bg-[#D7EBFD] hover:bg-[#BFE1FF]'
|
||||
}`}
|
||||
className={`max-w-fit cursor-pointer rounded-[28px] py-1 px-4 ${
|
||||
openSource === index
|
||||
? 'bg-[#007DFF]'
|
||||
: 'bg-[#D7EBFD] hover:bg-[#BFE1FF]'
|
||||
}`}
|
||||
onClick={() =>
|
||||
setOpenSource(openSource === index ? null : index)
|
||||
}
|
||||
>
|
||||
<p
|
||||
className={`truncate text-center text-base font-medium ${openSource === index
|
||||
? 'text-white'
|
||||
: 'text-[#007DFF]'
|
||||
}`}
|
||||
className={`truncate text-center text-base font-medium ${
|
||||
openSource === index
|
||||
? 'text-white'
|
||||
: 'text-[#007DFF]'
|
||||
}`}
|
||||
>
|
||||
{index + 1}. {source.title.substring(0, 45)}
|
||||
</p>
|
||||
@@ -191,16 +194,19 @@ const ConversationBubble = forwardRef<
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className='flex justify-center'>
|
||||
<div className="flex justify-center">
|
||||
<div
|
||||
className={`relative mr-5 items-center justify-center lg:invisible block
|
||||
${type !== 'ERROR' ? 'group-hover:lg:visible' : ''
|
||||
}`}
|
||||
className={`relative mr-5 block items-center justify-center lg:invisible
|
||||
${type !== 'ERROR' ? 'group-hover:lg:visible' : ''}`}
|
||||
>
|
||||
<div className="absolute left-2 top-4">
|
||||
<div
|
||||
className={`flex items-center justify-center rounded-full p-2
|
||||
${isCopyHovered ? 'bg-[#EEEEEE] dark:bg-purple-taupe' : 'bg-[#ffffff] dark:bg-transparent'}`}
|
||||
${
|
||||
isCopyHovered
|
||||
? 'bg-[#EEEEEE] dark:bg-purple-taupe'
|
||||
: 'bg-[#ffffff] dark:bg-transparent'
|
||||
}`}
|
||||
>
|
||||
{copied ? (
|
||||
<CheckMark
|
||||
@@ -222,22 +228,29 @@ const ConversationBubble = forwardRef<
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`relative mr-5 flex items-center justify-center ${!isLikeClicked ? 'lg:invisible' : ''
|
||||
} ${feedback === 'LIKE' || type !== 'ERROR'
|
||||
className={`relative mr-5 flex items-center justify-center ${
|
||||
!isLikeClicked ? 'lg:invisible' : ''
|
||||
} ${
|
||||
feedback === 'LIKE' || type !== 'ERROR'
|
||||
? 'group-hover:lg:visible'
|
||||
: ''
|
||||
}`}
|
||||
}`}
|
||||
>
|
||||
<div className="absolute left-6 top-4">
|
||||
<div
|
||||
className={`flex items-center justify-center rounded-full p-2 dark:bg-transparent ${isLikeHovered ? 'bg-[#EEEEEE] dark:bg-purple-taupe' : 'bg-[#ffffff] dark:bg-transparent'}`}
|
||||
className={`flex items-center justify-center rounded-full p-2 dark:bg-transparent ${
|
||||
isLikeHovered
|
||||
? 'bg-[#EEEEEE] dark:bg-purple-taupe'
|
||||
: 'bg-[#ffffff] dark:bg-transparent'
|
||||
}`}
|
||||
>
|
||||
<Like
|
||||
className={`cursor-pointer
|
||||
${isLikeClicked || feedback === 'LIKE'
|
||||
? 'fill-white-3000 stroke-purple-30 dark:fill-transparent'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
}`}
|
||||
${
|
||||
isLikeClicked || feedback === 'LIKE'
|
||||
? 'fill-white-3000 stroke-purple-30 dark:fill-transparent'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
}`}
|
||||
onClick={() => {
|
||||
handleFeedback?.('LIKE');
|
||||
setIsLikeClicked(true);
|
||||
@@ -250,22 +263,28 @@ const ConversationBubble = forwardRef<
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`mr-13 relative flex items-center justify-center ${!isDislikeClicked ? 'lg:invisible' : ''
|
||||
} ${feedback === 'DISLIKE' || type !== 'ERROR'
|
||||
className={`mr-13 relative flex items-center justify-center ${
|
||||
!isDislikeClicked ? 'lg:invisible' : ''
|
||||
} ${
|
||||
feedback === 'DISLIKE' || type !== 'ERROR'
|
||||
? 'group-hover:lg:visible'
|
||||
: ''
|
||||
}`}
|
||||
}`}
|
||||
>
|
||||
<div className="absolute left-10 top-4">
|
||||
<div
|
||||
|
||||
className={`flex items-center justify-center rounded-full p-2 ${isDislikeHovered ? 'bg-[#EEEEEE] dark:bg-purple-taupe' : 'bg-[#ffffff] dark:bg-transparent'}`}
|
||||
className={`flex items-center justify-center rounded-full p-2 ${
|
||||
isDislikeHovered
|
||||
? 'bg-[#EEEEEE] dark:bg-purple-taupe'
|
||||
: 'bg-[#ffffff] dark:bg-transparent'
|
||||
}`}
|
||||
>
|
||||
<Dislike
|
||||
className={`cursor-pointer ${isDislikeClicked || feedback === 'DISLIKE'
|
||||
? 'fill-white-3000 dark:fill-transparent stroke-red-2000'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
}`}
|
||||
className={`cursor-pointer ${
|
||||
isDislikeClicked || feedback === 'DISLIKE'
|
||||
? 'fill-white-3000 stroke-red-2000 dark:fill-transparent'
|
||||
: 'fill-none stroke-gray-4000'
|
||||
}`}
|
||||
onClick={() => {
|
||||
handleFeedback?.('DISLIKE');
|
||||
setIsDislikeClicked(true);
|
||||
@@ -281,12 +300,12 @@ const ConversationBubble = forwardRef<
|
||||
</div>
|
||||
|
||||
{sources && openSource !== null && sources[openSource] && (
|
||||
<div className="ml-10 mt-12 lg:mt-2 max-w-[300px] sm:max-w-[800px] break-words rounded-xl bg-blue-200 dark:bg-gun-metal p-2">
|
||||
<div className="ml-10 mt-12 max-w-[300px] break-words rounded-xl bg-blue-200 p-2 dark:bg-gun-metal sm:max-w-[800px] lg:mt-2">
|
||||
<p className="m-1 w-3/4 truncate text-xs text-gray-500 dark:text-bright-gray">
|
||||
Source: {sources[openSource].title}
|
||||
</p>
|
||||
|
||||
<div className="m-2 rounded-xl border-2 border-gray-200 dark:border-chinese-silver bg-white dark:bg-dark-charcoal p-2">
|
||||
<div className="m-2 rounded-xl border-2 border-gray-200 bg-white p-2 dark:border-chinese-silver dark:bg-dark-charcoal">
|
||||
<p className="text-break text-black dark:text-bright-gray">
|
||||
{sources[openSource].text}
|
||||
</p>
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function ConversationTile({
|
||||
}: ConversationTileProps) {
|
||||
const conversationId = useSelector(selectConversationId);
|
||||
const tileRef = useRef<HTMLInputElement>(null);
|
||||
const [isDarkTheme]= useDarkTheme();
|
||||
const [isDarkTheme] = useDarkTheme();
|
||||
const [isEdit, setIsEdit] = useState(false);
|
||||
const [conversationName, setConversationsName] = useState('');
|
||||
// useOutsideAlerter(
|
||||
@@ -69,14 +69,21 @@ export default function ConversationTile({
|
||||
onClick={() => {
|
||||
selectConversation(conversation.id);
|
||||
}}
|
||||
className={`my-auto mx-4 mt-4 flex h-9 cursor-pointer items-center justify-between gap-4 rounded-3xl hover:bg-gray-100 dark:hover:bg-purple-taupe ${conversationId === conversation.id ? 'bg-gray-100 dark:bg-purple-taupe' : ''
|
||||
}`}
|
||||
className={`my-auto mx-4 mt-4 flex h-9 cursor-pointer items-center justify-between gap-4 rounded-3xl hover:bg-gray-100 dark:hover:bg-purple-taupe ${
|
||||
conversationId === conversation.id
|
||||
? 'bg-gray-100 dark:bg-purple-taupe'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`flex ${conversationId === conversation.id ? 'w-[75%]' : 'w-[95%]'
|
||||
} gap-4`}
|
||||
className={`flex ${
|
||||
conversationId === conversation.id ? 'w-[75%]' : 'w-[95%]'
|
||||
} gap-4`}
|
||||
>
|
||||
<img src={isDarkTheme ? MessageDark : Message} className="ml-4 w-5 dark:text-white" />
|
||||
<img
|
||||
src={isDarkTheme ? MessageDark : Message}
|
||||
className="ml-4 w-5 dark:text-white"
|
||||
/>
|
||||
{isEdit ? (
|
||||
<input
|
||||
autoFocus
|
||||
@@ -96,23 +103,24 @@ export default function ConversationTile({
|
||||
<img
|
||||
src={isEdit ? CheckMark2 : Edit}
|
||||
alt="Edit"
|
||||
className="mr-2 h-4 w-4 cursor-pointer hover:opacity-50 text-white"
|
||||
className="mr-2 h-4 w-4 cursor-pointer text-white hover:opacity-50"
|
||||
id={`img-${conversation.id}`}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
isEdit
|
||||
? handleSaveConversation({
|
||||
id: conversationId,
|
||||
name: conversationName,
|
||||
})
|
||||
id: conversationId,
|
||||
name: conversationName,
|
||||
})
|
||||
: handleEditConversation();
|
||||
}}
|
||||
/>
|
||||
<img
|
||||
src={isEdit ? Exit : Trash}
|
||||
alt="Exit"
|
||||
className={`mr-4 ${isEdit ? 'h-3 w-3' : 'h-4 w-4'
|
||||
}mt-px cursor-pointer hover:opacity-50`}
|
||||
className={`mr-4 ${
|
||||
isEdit ? 'h-3 w-3' : 'h-4 w-4'
|
||||
}mt-px cursor-pointer hover:opacity-50`}
|
||||
id={`img-${conversation.id}`}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
|
||||
@@ -5,7 +5,7 @@ const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com';
|
||||
|
||||
export function fetchAnswerApi(
|
||||
question: string,
|
||||
signal:AbortSignal,
|
||||
signal: AbortSignal,
|
||||
apiKey: string,
|
||||
selectedDocs: Doc,
|
||||
history: Array<any> = [],
|
||||
@@ -13,20 +13,20 @@ export function fetchAnswerApi(
|
||||
promptId: string | null,
|
||||
): Promise<
|
||||
| {
|
||||
result: any;
|
||||
answer: any;
|
||||
sources: any;
|
||||
conversationId: any;
|
||||
query: string;
|
||||
}
|
||||
result: any;
|
||||
answer: any;
|
||||
sources: any;
|
||||
conversationId: any;
|
||||
query: string;
|
||||
}
|
||||
| {
|
||||
result: any;
|
||||
answer: any;
|
||||
sources: any;
|
||||
query: string;
|
||||
conversationId: any;
|
||||
title: any;
|
||||
}
|
||||
result: any;
|
||||
answer: any;
|
||||
sources: any;
|
||||
query: string;
|
||||
conversationId: any;
|
||||
title: any;
|
||||
}
|
||||
> {
|
||||
let namePath = selectedDocs.name;
|
||||
if (selectedDocs.language === namePath) {
|
||||
@@ -89,7 +89,7 @@ export function fetchAnswerApi(
|
||||
|
||||
export function fetchAnswerSteaming(
|
||||
question: string,
|
||||
signal:AbortSignal,
|
||||
signal: AbortSignal,
|
||||
apiKey: string,
|
||||
selectedDocs: Doc,
|
||||
history: Array<any> = [],
|
||||
@@ -137,7 +137,7 @@ export function fetchAnswerSteaming(
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
signal
|
||||
signal,
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.body) throw Error('No response body');
|
||||
@@ -222,21 +222,20 @@ export function searchEndpoint(
|
||||
question: question,
|
||||
active_docs: docPath,
|
||||
conversation_id,
|
||||
history
|
||||
history,
|
||||
};
|
||||
return fetch(`${apiHost}/api/search`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(
|
||||
body
|
||||
),
|
||||
}).then((response) => response.json())
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
return data;
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
export function sendFeedback(
|
||||
prompt: string,
|
||||
|
||||
@@ -32,7 +32,6 @@ export const fetchAnswer = createAsyncThunk<Answer, { question: string }>(
|
||||
(event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
|
||||
// check if the 'end' event has been received
|
||||
if (data.type === 'end') {
|
||||
// set status to 'idle'
|
||||
@@ -45,13 +44,14 @@ export const fetchAnswer = createAsyncThunk<Answer, { question: string }>(
|
||||
console.error('Failed to fetch conversations: ', error);
|
||||
});
|
||||
|
||||
searchEndpoint( //search for sources post streaming
|
||||
searchEndpoint(
|
||||
//search for sources post streaming
|
||||
question,
|
||||
state.preference.apiKey,
|
||||
state.preference.selectedDocs!,
|
||||
state.conversation.conversationId,
|
||||
state.conversation.queries
|
||||
).then(sources => {
|
||||
state.conversation.queries,
|
||||
).then((sources) => {
|
||||
//dispatch streaming sources
|
||||
dispatch(
|
||||
updateStreamingSource({
|
||||
@@ -168,7 +168,6 @@ export const conversationSlice = createSlice({
|
||||
state,
|
||||
action: PayloadAction<{ index: number; query: Partial<Query> }>,
|
||||
) {
|
||||
|
||||
const { index, query } = action.payload;
|
||||
if (!state.queries[index].sources) {
|
||||
state.queries[index].sources = query?.sources;
|
||||
@@ -196,8 +195,7 @@ export const conversationSlice = createSlice({
|
||||
state.status = 'loading';
|
||||
})
|
||||
.addCase(fetchAnswer.rejected, (state, action) => {
|
||||
if(action.meta.aborted)
|
||||
{
|
||||
if (action.meta.aborted) {
|
||||
state.status = 'idle';
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,9 @@ export function useMediaQuery() {
|
||||
}
|
||||
|
||||
export function useDarkTheme() {
|
||||
const [isDarkTheme, setIsDarkTheme] = useState<boolean>(localStorage.getItem('selectedTheme') === "Dark" || false);
|
||||
const [isDarkTheme, setIsDarkTheme] = useState<boolean>(
|
||||
localStorage.getItem('selectedTheme') === 'Dark' || false,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Check if dark mode preference exists in local storage
|
||||
@@ -88,14 +90,13 @@ export function useDarkTheme() {
|
||||
if (isDarkTheme) {
|
||||
document.documentElement.classList.add('dark');
|
||||
document.documentElement.classList.add('dark:bg-raisin-black');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
}, [isDarkTheme])
|
||||
}, [isDarkTheme]);
|
||||
//method to toggle theme
|
||||
const toggleTheme: any = () => {
|
||||
setIsDarkTheme(!isDarkTheme)
|
||||
setIsDarkTheme(!isDarkTheme);
|
||||
};
|
||||
return [isDarkTheme, toggleTheme];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user