diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 48eb5ee..dc71e00 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4,21 +4,32 @@ import Conversation from './components/Conversation/Conversation'; import APIKeyModal from './components/APIKeyModal'; import About from './components/About'; 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() { - const [navState, setNavState] = useState('OPEN'); + const isApiKeySet = useSelector(selectApiKeyStatus); + const [navState, setNavState] = useState('ACTIVE'); + const [apiKeyModalState, setApiKeyModalState] = useState( + isApiKeySet ? 'INACTIVE' : 'ACTIVE', + ); return (
- + setNavState(val)} + setNavState={(val: ActiveState) => setNavState(val)} + setApiKeyModalState={setApiKeyModalState} />
diff --git a/frontend/src/components/APIKeyModal.tsx b/frontend/src/components/APIKeyModal.tsx index 692ff48..41b4c16 100644 --- a/frontend/src/components/APIKeyModal.tsx +++ b/frontend/src/components/APIKeyModal.tsx @@ -1,34 +1,42 @@ import { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { - setApiKey, - toggleApiKeyModal, - selectIsApiKeyModalOpen, -} from '../store'; - -export default function APIKeyModal() { - //TODO - Add form validation? - //TODO - Connect to backend - //TODO - Add link to OpenAI API Key page +import { useDispatch } from 'react-redux'; +import { ActiveState } from '../models/misc'; +import { setApiKey } from '../store'; +export default function APIKeyModal({ + modalState, + setModalState, + isCancellable = true, +}: { + modalState: ActiveState; + setModalState: (val: ActiveState) => void; + isCancellable?: boolean; +}) { const dispatch = useDispatch(); - const isApiModalOpen = useSelector(selectIsApiKeyModalOpen); const [key, setKey] = useState(''); - const [formError, setFormError] = useState(false); + const [isError, setIsError] = useState(false); function handleSubmit() { - if (key.length < 1) { - setFormError(true); - return; + if (key.length <= 1) { + setIsError(true); + } else { + dispatch(setApiKey(key)); + setModalState('INACTIVE'); + setKey(''); + setIsError(false); } - dispatch(setApiKey(key)); - dispatch(toggleApiKeyModal()); + } + + function handleCancel() { + setKey(''); + setIsError(false); + setModalState('INACTIVE'); } return (
@@ -46,16 +54,28 @@ export default function APIKeyModal() { placeholder="API Key" onChange={(e) => setKey(e.target.value)} /> -
- {formError && ( -

Please enter a valid API key

+
+
+ + {isCancellable && ( + + )} +
+ {isError && ( +

+ Please enter a valid API key +

)} -
diff --git a/frontend/src/components/Navigation.tsx b/frontend/src/components/Navigation.tsx index 6405e44..c895a67 100644 --- a/frontend/src/components/Navigation.tsx +++ b/frontend/src/components/Navigation.tsx @@ -8,7 +8,7 @@ import Key from '../imgs/key.svg'; import Info from '../imgs/info.svg'; import Link from '../imgs/link.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 add Discord and Github links @@ -16,16 +16,18 @@ import { NavState } from '../models/misc'; export default function Navigation({ navState, setNavState, + setApiKeyModalState, }: { - navState: NavState; - setNavState: (val: NavState) => void; + navState: ActiveState; + setNavState: (val: ActiveState) => void; + setApiKeyModalState: (val: ActiveState) => void; }) { const openNav = (
); - return navState === 'OPEN' ? openNav : closedNav; + return navState === 'ACTIVE' ? openNav : closedNav; } diff --git a/frontend/src/models/misc.ts b/frontend/src/models/misc.ts index 43cf45d..27a149d 100644 --- a/frontend/src/models/misc.ts +++ b/frontend/src/models/misc.ts @@ -1 +1 @@ -export type NavState = 'OPEN' | 'CLOSED'; +export type ActiveState = 'ACTIVE' | 'INACTIVE'; diff --git a/frontend/src/store.ts b/frontend/src/store.ts index 2f5f76e..d3d3c17 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -1,4 +1,9 @@ -import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { + configureStore, + createSelector, + createSlice, + PayloadAction, +} from '@reduxjs/toolkit'; interface State { isApiKeyModalOpen: boolean; @@ -38,5 +43,6 @@ type RootState = ReturnType; export const selectIsApiKeyModalOpen = (state: RootState) => state.app.isApiKeyModalOpen; export const selectApiKey = (state: RootState) => state.app.apiKey; +export const selectApiKeyStatus = (state: RootState) => !!state.app.apiKey; export default store;