makes the api key modal work

This commit is contained in:
ajaythapliyal 2023-02-18 00:25:21 +05:30
parent 1b6a58520c
commit 350ccad077
5 changed files with 82 additions and 43 deletions

View File

@ -4,21 +4,32 @@ import Conversation from './components/Conversation/Conversation';
import APIKeyModal from './components/APIKeyModal'; import APIKeyModal from './components/APIKeyModal';
import About from './components/About'; import About from './components/About';
import { useState } from 'react'; import { useState } from 'react';
import { NavState } from './models/misc'; import { ActiveState } from './models/misc';
import { selectApiKeyStatus } from './store';
import { useSelector } from 'react-redux';
export default function App() { export default function App() {
const [navState, setNavState] = useState<NavState>('OPEN'); const isApiKeySet = useSelector(selectApiKeyStatus);
const [navState, setNavState] = useState<ActiveState>('ACTIVE');
const [apiKeyModalState, setApiKeyModalState] = useState<ActiveState>(
isApiKeySet ? 'INACTIVE' : 'ACTIVE',
);
return ( return (
<div className="min-h-full min-w-full transition-all"> <div className="min-h-full min-w-full transition-all">
<APIKeyModal /> <APIKeyModal
modalState={apiKeyModalState}
setModalState={setApiKeyModalState}
isCancellable={isApiKeySet}
/>
<Navigation <Navigation
navState={navState} navState={navState}
setNavState={(val: NavState) => setNavState(val)} setNavState={(val: ActiveState) => setNavState(val)}
setApiKeyModalState={setApiKeyModalState}
/> />
<div <div
className={`${ className={`${
navState === 'OPEN' ? 'ml-0 md:ml-72 lg:ml-96' : ' ml-0 md:ml-16' navState === 'ACTIVE' ? 'ml-0 md:ml-72 lg:ml-96' : ' ml-0 md:ml-16'
}`} }`}
> >
<Routes> <Routes>

View File

@ -1,34 +1,42 @@
import { useState } from 'react'; import { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch } from 'react-redux';
import { import { ActiveState } from '../models/misc';
setApiKey, import { setApiKey } from '../store';
toggleApiKeyModal,
selectIsApiKeyModalOpen,
} from '../store';
export default function APIKeyModal() {
//TODO - Add form validation?
//TODO - Connect to backend
//TODO - Add link to OpenAI API Key page
export default function APIKeyModal({
modalState,
setModalState,
isCancellable = true,
}: {
modalState: ActiveState;
setModalState: (val: ActiveState) => void;
isCancellable?: boolean;
}) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const isApiModalOpen = useSelector(selectIsApiKeyModalOpen);
const [key, setKey] = useState(''); const [key, setKey] = useState('');
const [formError, setFormError] = useState(false); const [isError, setIsError] = useState(false);
function handleSubmit() { function handleSubmit() {
if (key.length < 1) { if (key.length <= 1) {
setFormError(true); setIsError(true);
return; } else {
}
dispatch(setApiKey(key)); dispatch(setApiKey(key));
dispatch(toggleApiKeyModal()); setModalState('INACTIVE');
setKey('');
setIsError(false);
}
}
function handleCancel() {
setKey('');
setIsError(false);
setModalState('INACTIVE');
} }
return ( return (
<div <div
className={`${ className={`${
isApiModalOpen ? '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 className="mx-auto mt-24 flex w-[90vw] max-w-lg flex-col gap-4 rounded-lg bg-white p-6 shadow-lg">
@ -46,16 +54,28 @@ export default function APIKeyModal() {
placeholder="API Key" placeholder="API Key"
onChange={(e) => setKey(e.target.value)} onChange={(e) => setKey(e.target.value)}
/> />
<div className="flex justify-between"> <div className="flex flex-row-reverse">
{formError && ( <div>
<p className="text-sm text-red-500">Please enter a valid API key</p>
)}
<button <button
onClick={() => handleSubmit()} onClick={() => handleSubmit()}
className="ml-auto h-10 w-20 rounded-lg bg-violet-800 text-white transition-all hover:bg-violet-700" className="ml-auto h-10 w-20 rounded-lg bg-violet-800 text-white transition-all hover:bg-violet-700"
> >
Save Save
</button> </button>
{isCancellable && (
<button
onClick={() => handleCancel()}
className="ml-5 h-10 w-20 rounded-lg border border-violet-700 bg-white text-violet-800 transition-all hover:bg-violet-700 hover:text-white"
>
Cancel
</button>
)}
</div>
{isError && (
<p className="mr-auto text-sm text-red-500">
Please enter a valid API key
</p>
)}
</div> </div>
</article> </article>
</div> </div>

View File

@ -8,7 +8,7 @@ import Key from '../imgs/key.svg';
import Info from '../imgs/info.svg'; import Info from '../imgs/info.svg';
import Link from '../imgs/link.svg'; import Link from '../imgs/link.svg';
import Exit from '../imgs/exit.svg'; import Exit from '../imgs/exit.svg';
import { NavState } from '../models/misc'; import { ActiveState } from '../models/misc';
//TODO - Need to replace Chat button to open secondary nav with scrollable past chats option and new chat at top //TODO - Need to replace Chat button to open secondary nav with scrollable past chats option and new chat at top
//TODO - Need to add Discord and Github links //TODO - Need to add Discord and Github links
@ -16,16 +16,18 @@ import { NavState } from '../models/misc';
export default function Navigation({ export default function Navigation({
navState, navState,
setNavState, setNavState,
setApiKeyModalState,
}: { }: {
navState: NavState; navState: ActiveState;
setNavState: (val: NavState) => void; setNavState: (val: ActiveState) => void;
setApiKeyModalState: (val: ActiveState) => void;
}) { }) {
const openNav = ( const openNav = (
<div className="fixed h-full w-72 flex-col border-r-2 border-gray-100 bg-gray-50 transition-all md:visible md:flex lg:w-96"> <div className="fixed h-full w-72 flex-col border-r-2 border-gray-100 bg-gray-50 transition-all md:visible md:flex lg:w-96">
<div className={'h-16 w-full border-b-2 border-gray-100'}> <div className={'h-16 w-full border-b-2 border-gray-100'}>
<button <button
className="float-right mr-5 mt-5 h-5 w-5" className="float-right mr-5 mt-5 h-5 w-5"
onClick={() => setNavState('CLOSED')} onClick={() => setNavState('INACTIVE')}
> >
<img <img
src={Arrow1} src={Arrow1}
@ -40,7 +42,7 @@ export default function Navigation({
<div <div
className="my-auto mx-4 flex h-12 cursor-pointer gap-4 rounded-md hover:bg-gray-100" className="my-auto mx-4 flex h-12 cursor-pointer gap-4 rounded-md hover:bg-gray-100"
onClick={() => { onClick={() => {
return; setApiKeyModalState('ACTIVE');
}} }}
> >
<img src={Key} alt="key" className="ml-2 w-6" /> <img src={Key} alt="key" className="ml-2 w-6" />
@ -76,7 +78,7 @@ export default function Navigation({
<div className={'h-16 w-16 border-b-2 border-gray-100'}> <div className={'h-16 w-16 border-b-2 border-gray-100'}>
<button <button
className="float-right mr-5 mt-5 h-5 w-5" className="float-right mr-5 mt-5 h-5 w-5"
onClick={() => setNavState('OPEN')} onClick={() => setNavState('ACTIVE')}
> >
<img <img
src={Arrow1} src={Arrow1}
@ -88,12 +90,12 @@ export default function Navigation({
</div> </div>
<button <button
className="fixed mt-5 ml-6 h-6 w-6 md:hidden" className="fixed mt-5 ml-6 h-6 w-6 md:hidden"
onClick={() => setNavState('OPEN')} onClick={() => setNavState('ACTIVE')}
> >
<img src={Hamburger} alt="menu toggle" className="w-7" /> <img src={Hamburger} alt="menu toggle" className="w-7" />
</button> </button>
</> </>
); );
return navState === 'OPEN' ? openNav : closedNav; return navState === 'ACTIVE' ? openNav : closedNav;
} }

View File

@ -1 +1 @@
export type NavState = 'OPEN' | 'CLOSED'; export type ActiveState = 'ACTIVE' | 'INACTIVE';

View File

@ -1,4 +1,9 @@
import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit'; import {
configureStore,
createSelector,
createSlice,
PayloadAction,
} from '@reduxjs/toolkit';
interface State { interface State {
isApiKeyModalOpen: boolean; isApiKeyModalOpen: boolean;
@ -38,5 +43,6 @@ type RootState = ReturnType<typeof store.getState>;
export const selectIsApiKeyModalOpen = (state: RootState) => export const selectIsApiKeyModalOpen = (state: RootState) =>
state.app.isApiKeyModalOpen; state.app.isApiKeyModalOpen;
export const selectApiKey = (state: RootState) => state.app.apiKey; export const selectApiKey = (state: RootState) => state.app.apiKey;
export const selectApiKeyStatus = (state: RootState) => !!state.app.apiKey;
export default store; export default store;