Merge pull request #139 from arc53/feature/nicks-list1

pull/141/head
Alex 1 year ago committed by GitHub
commit ed79ad6b8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,15 +8,12 @@ import { ActiveState } from './models/misc';
export default function App() { export default function App() {
//TODO : below media query is disjoint from tailwind. Please wire it together. //TODO : below media query is disjoint from tailwind. Please wire it together.
const [navState, setNavState] = useState<ActiveState>( const [navState, setNavState] = useState<ActiveState>(
window.matchMedia('((min-width: 768px)').matches ? 'ACTIVE' : 'INACTIVE', window.matchMedia('(min-width: 768px)').matches ? 'ACTIVE' : 'INACTIVE',
); );
return ( return (
<div className="min-h-full min-w-full"> <div className="min-h-full min-w-full">
<Navigation <Navigation navState={navState} setNavState={setNavState} />
navState={navState}
setNavState={(val: ActiveState) => setNavState(val)}
/>
<div <div
className={`transition-all duration-200 ${ className={`transition-all duration-200 ${
navState === 'ACTIVE' ? 'ml-0 md:ml-72 lg:ml-60' : 'ml-0 md:ml-16' navState === 'ACTIVE' ? 'ml-0 md:ml-72 lg:ml-60' : 'ml-0 md:ml-16'

@ -1,4 +1,4 @@
import { useState } from 'react'; import { useRef, useState } from 'react';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import Arrow1 from './assets/arrow.svg'; import Arrow1 from './assets/arrow.svg';
import Arrow2 from './assets/dropdown-arrow.svg'; import Arrow2 from './assets/dropdown-arrow.svg';
@ -18,13 +18,14 @@ import {
selectSourceDocs, selectSourceDocs,
setSelectedDocs, setSelectedDocs,
} from './preferences/preferenceSlice'; } from './preferences/preferenceSlice';
import { useOutsideAlerter } from './hooks';
export default function Navigation({ export default function Navigation({
navState, navState,
setNavState, setNavState,
}: { }: {
navState: ActiveState; navState: ActiveState;
setNavState: (val: ActiveState) => void; setNavState: React.Dispatch<React.SetStateAction<ActiveState>>;
}) { }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const docs = useSelector(selectSourceDocs); const docs = useSelector(selectSourceDocs);
@ -41,9 +42,26 @@ export default function Navigation({
const [selectedDocsModalState, setSelectedDocsModalState] = const [selectedDocsModalState, setSelectedDocsModalState] =
useState<ActiveState>(isSelectedDocsSet ? 'INACTIVE' : 'ACTIVE'); useState<ActiveState>(isSelectedDocsSet ? 'INACTIVE' : 'ACTIVE');
const navRef = useRef(null);
useOutsideAlerter(
navRef,
() => {
if (
window.matchMedia('(max-width: 768px)').matches &&
navState === 'ACTIVE' &&
apiKeyModalState === 'INACTIVE'
) {
setNavState('INACTIVE');
setIsDocsListOpen(false);
}
},
[navState, isDocsListOpen, apiKeyModalState],
);
return ( return (
<> <>
<div <div
ref={navRef}
className={`${ className={`${
navState === 'INACTIVE' && '-ml-96 md:-ml-[14rem]' navState === 'INACTIVE' && '-ml-96 md:-ml-[14rem]'
} duration-20 fixed z-20 flex h-full w-72 flex-col border-r-2 bg-gray-50 transition-all`} } duration-20 fixed z-20 flex h-full w-72 flex-col border-r-2 bg-gray-50 transition-all`}

@ -67,16 +67,18 @@ export default function Conversation() {
className="relative right-[38px] bottom-[7px] -mr-[30px] animate-spin cursor-pointer self-end" className="relative right-[38px] bottom-[7px] -mr-[30px] animate-spin cursor-pointer self-end"
></img> ></img>
) : ( ) : (
<img <div className="relative right-[43px] bottom-[7px] -mr-[35px] h-[35px] w-[35px] cursor-pointer self-end rounded-full hover:bg-gray-3000">
onClick={() => { <img
if (inputRef.current?.textContent) { className="ml-[9px] mt-[9px]"
handleQuestion(inputRef.current.textContent); onClick={() => {
inputRef.current.textContent = ''; if (inputRef.current?.textContent) {
} handleQuestion(inputRef.current.textContent);
}} inputRef.current.textContent = '';
src={Send} }
className="relative right-[35px] bottom-[15px] -mr-[21px] cursor-pointer self-end" }}
></img> src={Send}
></img>
</div>
)} )}
</div> </div>
<p className="mt-3 w-10/12 self-center text-center text-xs text-gray-2000"> <p className="mt-3 w-10/12 self-center text-center text-xs text-gray-2000">

@ -0,0 +1,19 @@
import { useEffect, RefObject } from 'react';
export function useOutsideAlerter<T extends HTMLElement>(
ref: RefObject<T>,
handler: () => void,
additionalDeps: unknown[],
) {
useEffect(() => {
function handleClickOutside(this: Document, event: MouseEvent) {
if (ref.current && !ref.current.contains(event.target as Node)) {
handler();
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [ref, ...additionalDeps]);
}

@ -1,7 +1,8 @@
import { useState } from 'react'; import { useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { ActiveState } from '../models/misc'; import { ActiveState } from '../models/misc';
import { selectApiKey, setApiKey } from './preferenceSlice'; import { selectApiKey, setApiKey } from './preferenceSlice';
import { useOutsideAlerter } from './../hooks';
export default function APIKeyModal({ export default function APIKeyModal({
modalState, modalState,
@ -16,6 +17,20 @@ export default function APIKeyModal({
const apiKey = useSelector(selectApiKey); const apiKey = useSelector(selectApiKey);
const [key, setKey] = useState(apiKey); const [key, setKey] = useState(apiKey);
const [isError, setIsError] = useState(false); const [isError, setIsError] = useState(false);
const modalRef = useRef(null);
useOutsideAlerter(
modalRef,
() => {
if (
window.matchMedia('(max-width: 768px)').matches &&
modalState === 'ACTIVE'
) {
setModalState('INACTIVE');
}
},
[modalState],
);
function handleSubmit() { function handleSubmit() {
if (key.length <= 1) { if (key.length <= 1) {
@ -39,7 +54,10 @@ export default function APIKeyModal({
modalState === 'ACTIVE' ? 'visible' : 'hidden' modalState === 'ACTIVE' ? 'visible' : 'hidden'
} absolute z-30 h-screen w-screen bg-gray-alpha`} } absolute z-30 h-screen w-screen bg-gray-alpha`}
> >
<article className="mx-auto mt-24 flex w-[90vw] max-w-lg flex-col gap-4 rounded-lg bg-white p-6 shadow-lg"> <article
ref={modalRef}
className="mx-auto mt-24 flex w-[90vw] max-w-lg flex-col gap-4 rounded-lg bg-white p-6 shadow-lg"
>
<p className="text-xl text-jet">OpenAI API Key</p> <p className="text-xl text-jet">OpenAI API Key</p>
<p className="text-md leading-6 text-gray-500"> <p className="text-md leading-6 text-gray-500">
Before you can start using DocsGPT we need you to provide an API key Before you can start using DocsGPT we need you to provide an API key

Loading…
Cancel
Save