From 4c6951977e007fd12783fa92c3e1d54d06497b80 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sat, 11 Feb 2023 13:27:02 -0500 Subject: [PATCH 01/11] TODOs updated, removed App.css, About page --- frontend/src/App.css | 4 -- frontend/src/App.tsx | 5 +- frontend/src/components/APIKeyModal.tsx | 8 ++- frontend/src/components/About.tsx | 58 +++++++++++++++++++ .../src/components/Navigation/Navigation.tsx | 8 ++- frontend/src/index.css | 4 ++ 6 files changed, 77 insertions(+), 10 deletions(-) delete mode 100644 frontend/src/App.css create mode 100644 frontend/src/components/About.tsx diff --git a/frontend/src/App.css b/frontend/src/App.css deleted file mode 100644 index a43cf76d..00000000 --- a/frontend/src/App.css +++ /dev/null @@ -1,4 +0,0 @@ -html, -body { - min-height: 100vh; -} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 2c0a6dae..dc0b2ca9 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -3,13 +3,13 @@ import { Routes, Route } from 'react-router-dom'; import Navigation from './components/Navigation/Navigation'; import DocsGPT from './components/DocsGPT'; import APIKeyModal from './components/APIKeyModal'; -import './App.css'; +import About from './components/About'; export default function App() { //Currently using primitive state management. Will most likely be replaced with Redux. const [isMobile, setIsMobile] = useState(true); const [isMenuOpen, setIsMenuOpen] = useState(true); - const [isApiModalOpen, setIsApiModalOpen] = useState(true); + const [isApiModalOpen, setIsApiModalOpen] = useState(false); const [apiKey, setApiKey] = useState(''); const handleResize = () => { @@ -49,6 +49,7 @@ export default function App() { /> } /> + } /> ); diff --git a/frontend/src/components/APIKeyModal.tsx b/frontend/src/components/APIKeyModal.tsx index 4a23bb72..7c82a43b 100644 --- a/frontend/src/components/APIKeyModal.tsx +++ b/frontend/src/components/APIKeyModal.tsx @@ -11,6 +11,10 @@ export default function APIKeyModal({ apiKey: string; setApiKey: React.Dispatch>; }) { + //TODO - Add form validation + //TODO - Connect to backend + //TODO - Add link to OpenAI API Key page + const [formError, setFormError] = useState(false); const handleResetKey = () => { @@ -28,7 +32,7 @@ export default function APIKeyModal({ isApiModalOpen ? 'visible' : 'hidden' } absolute z-30 h-screen w-screen bg-gray-alpha`} > -
+

OpenAI API Key

Before you can start using DocsGPT we need you to provide an API key @@ -54,7 +58,7 @@ export default function APIKeyModal({ Save

- + ); } diff --git a/frontend/src/components/About.tsx b/frontend/src/components/About.tsx new file mode 100644 index 00000000..e1173cac --- /dev/null +++ b/frontend/src/components/About.tsx @@ -0,0 +1,58 @@ +export default function About({ isMenuOpen }: { isMenuOpen: boolean }) { + //TODO - Add hyperlinks to text + //TODO - Styling + + return ( + //Parent div for all content shown through App.tsx routing needs to have this styling. +
+
+

About DocsGPT 🦖

+

+ Find the information in your documentation through AI-powered + open-source chatbot. Powered by GPT-3, Faiss and LangChain. +

+ +
+

+ If you want to add your own documentation, please follow the + instruction below: +

+

+ 1. Navigate to{' '} + /application folder +

+

+ 2. Install dependencies from{' '} + + pip install -r requirements.txt + +

+

+ 3. Prepare a .env file. + Copy .env_sample and + create .env with your + OpenAI API token +

+

+ 4. Run the app with{' '} + python app.py +

+
+ +

+ Currently It uses python pandas documentation, so it will respond to + information relevant to pandas. If you want to train it on different + documentation - please follow this guide. +

+ +

+ If you want to launch it on your own server - follow this guide. +

+
+
+ ); +} diff --git a/frontend/src/components/Navigation/Navigation.tsx b/frontend/src/components/Navigation/Navigation.tsx index e086bf88..ce4ba114 100644 --- a/frontend/src/components/Navigation/Navigation.tsx +++ b/frontend/src/components/Navigation/Navigation.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import { NavLink } from 'react-router-dom'; import Arrow1 from './imgs/arrow.svg'; import Key from './imgs/key.svg'; import Info from './imgs/info.svg'; @@ -57,10 +58,13 @@ function DesktopNavigation({
-
+ info

About

-
+
link diff --git a/frontend/src/index.css b/frontend/src/index.css index 54f31b12..8c23069d 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -15,6 +15,8 @@ html { line-height: 1.15; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ + min-height: 100vh; + overflow-x: hidden; } /* Sections @@ -26,6 +28,8 @@ html { body { margin: 0; + min-height: 100vh; + overflow-x: hidden; } /** From c95b436cf105420673cebdec746eb09f2c2869c0 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sat, 11 Feb 2023 19:18:01 -0500 Subject: [PATCH 02/11] About page, App fix, Mobile nav started --- frontend/src/App.tsx | 13 +++- frontend/src/components/About.tsx | 22 ++++-- frontend/src/components/DocsGPT.tsx | 7 -- frontend/src/components/DocsGPT/DocsGPT.tsx | 24 ++++++ .../src/components/Navigation/Navigation.tsx | 77 ++++++++++++++++++- .../src/components/Navigation/imgs/exit.svg | 10 +++ .../components/Navigation/imgs/hamburger.svg | 3 + 7 files changed, 138 insertions(+), 18 deletions(-) delete mode 100644 frontend/src/components/DocsGPT.tsx create mode 100644 frontend/src/components/DocsGPT/DocsGPT.tsx create mode 100644 frontend/src/components/Navigation/imgs/exit.svg create mode 100644 frontend/src/components/Navigation/imgs/hamburger.svg diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index dc0b2ca9..c0a3a9c0 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { Routes, Route } from 'react-router-dom'; import Navigation from './components/Navigation/Navigation'; -import DocsGPT from './components/DocsGPT'; +import DocsGPT from './components/DocsGPT/DocsGPT'; import APIKeyModal from './components/APIKeyModal'; import About from './components/About'; @@ -17,6 +17,7 @@ export default function App() { setIsMobile(false); } else { setIsMobile(true); + setIsMenuOpen(false); } }; @@ -48,8 +49,14 @@ export default function App() { setIsApiModalOpen={setIsApiModalOpen} /> - } /> - } /> + } + /> + } + />
); diff --git a/frontend/src/components/About.tsx b/frontend/src/components/About.tsx index e1173cac..4972afc3 100644 --- a/frontend/src/components/About.tsx +++ b/frontend/src/components/About.tsx @@ -1,17 +1,29 @@ -export default function About({ isMenuOpen }: { isMenuOpen: boolean }) { +export default function About({ + isMenuOpen, + isMobile, +}: { + isMenuOpen: boolean; + isMobile: boolean; +}) { //TODO - Add hyperlinks to text //TODO - Styling return ( - //Parent div for all content shown through App.tsx routing needs to have this styling. + //Parent div for all content shown through App.tsx routing needs to have this styling. Might change when state management is updated.

About DocsGPT 🦖

-

+

Find the information in your documentation through AI-powered open-source chatbot. Powered by GPT-3, Faiss and LangChain.

@@ -23,7 +35,7 @@ export default function About({ isMenuOpen }: { isMenuOpen: boolean }) {

1. Navigate to{' '} - /application folder + /application folder

2. Install dependencies from{' '} diff --git a/frontend/src/components/DocsGPT.tsx b/frontend/src/components/DocsGPT.tsx deleted file mode 100644 index 15df78e7..00000000 --- a/frontend/src/components/DocsGPT.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function DocsGPT({ isMenuOpen }: { isMenuOpen: boolean }) { - return ( -

- Docs GPT Chat Placeholder -
- ); -} diff --git a/frontend/src/components/DocsGPT/DocsGPT.tsx b/frontend/src/components/DocsGPT/DocsGPT.tsx new file mode 100644 index 00000000..37098cb5 --- /dev/null +++ b/frontend/src/components/DocsGPT/DocsGPT.tsx @@ -0,0 +1,24 @@ +export default function DocsGPT({ + isMenuOpen, + isMobile, +}: { + isMenuOpen: boolean; + isMobile: boolean; +}) { + return ( + //Parent div for all content shown through App.tsx routing needs to have this styling. Might change when state management is updated. +
+ Docs GPT Chat Placeholder +
+ ); +} diff --git a/frontend/src/components/Navigation/Navigation.tsx b/frontend/src/components/Navigation/Navigation.tsx index ce4ba114..73610a4b 100644 --- a/frontend/src/components/Navigation/Navigation.tsx +++ b/frontend/src/components/Navigation/Navigation.tsx @@ -1,12 +1,77 @@ import React, { useState } from 'react'; import { NavLink } from 'react-router-dom'; import Arrow1 from './imgs/arrow.svg'; +import Hamburger from './imgs/hamburger.svg'; import Key from './imgs/key.svg'; import Info from './imgs/info.svg'; import Link from './imgs/link.svg'; +import Exit from './imgs/exit.svg'; -function MobileNavigation() { - return
Mobile Navigation
; +function MobileNavigation({ + isMenuOpen, + setIsMenuOpen, + setIsApiModalOpen, +}: { + isMenuOpen: boolean; + setIsMenuOpen: React.Dispatch>; + setIsApiModalOpen: React.Dispatch>; +}) { + //TODO - Need to replace Chat button to open secondary nav with scrollable past chats option and new chat at top + return ( +
+
+ {isMenuOpen ? ( + <> + + + ) : ( + <> + + + )} +
+ {isMenuOpen && ( + + )} +
+ ); } function DesktopNavigation({ @@ -94,7 +159,13 @@ export default function Navigation({ setIsApiModalOpen: React.Dispatch>; }) { if (isMobile) { - return ; + return ( + + ); } else { return ( + + + + + + + + + diff --git a/frontend/src/components/Navigation/imgs/hamburger.svg b/frontend/src/components/Navigation/imgs/hamburger.svg new file mode 100644 index 00000000..cfed15f4 --- /dev/null +++ b/frontend/src/components/Navigation/imgs/hamburger.svg @@ -0,0 +1,3 @@ + + + From cca92ca32f4d878d969169b2d2210103d328db21 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 12 Feb 2023 10:54:41 -0500 Subject: [PATCH 03/11] fixes --- frontend/src/components/APIKeyModal.tsx | 2 +- frontend/src/components/Navigation/Navigation.tsx | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/APIKeyModal.tsx b/frontend/src/components/APIKeyModal.tsx index 7c82a43b..505f2494 100644 --- a/frontend/src/components/APIKeyModal.tsx +++ b/frontend/src/components/APIKeyModal.tsx @@ -32,7 +32,7 @@ export default function APIKeyModal({ isApiModalOpen ? 'visible' : 'hidden' } absolute z-30 h-screen w-screen bg-gray-alpha`} > -
+

OpenAI API Key

Before you can start using DocsGPT we need you to provide an API key diff --git a/frontend/src/components/Navigation/Navigation.tsx b/frontend/src/components/Navigation/Navigation.tsx index 73610a4b..5ba273dd 100644 --- a/frontend/src/components/Navigation/Navigation.tsx +++ b/frontend/src/components/Navigation/Navigation.tsx @@ -17,6 +17,7 @@ function MobileNavigation({ setIsApiModalOpen: React.Dispatch>; }) { //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 return (

Github

+
setIsApiModalOpen(true)} + > + info +

Reset Key

+
)}
From b01ca543135f5435262dc47f94ad56944289f796 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Sun, 12 Feb 2023 11:00:18 -0500 Subject: [PATCH 04/11] small margin fix --- frontend/src/components/About.tsx | 2 +- frontend/src/components/DocsGPT/DocsGPT.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/About.tsx b/frontend/src/components/About.tsx index 4972afc3..2edfde68 100644 --- a/frontend/src/components/About.tsx +++ b/frontend/src/components/About.tsx @@ -14,7 +14,7 @@ export default function About({ className={`${ isMobile ? isMenuOpen - ? 'mt-72' + ? 'mt-80' : 'mt-16' : isMenuOpen ? 'md:ml-72 lg:ml-96' diff --git a/frontend/src/components/DocsGPT/DocsGPT.tsx b/frontend/src/components/DocsGPT/DocsGPT.tsx index 37098cb5..704c3914 100644 --- a/frontend/src/components/DocsGPT/DocsGPT.tsx +++ b/frontend/src/components/DocsGPT/DocsGPT.tsx @@ -11,7 +11,7 @@ export default function DocsGPT({ className={`${ isMobile ? isMenuOpen - ? 'mt-72' + ? 'mt-80' : 'mt-16' : isMenuOpen ? 'md:ml-72 lg:ml-96' From cbe924235593dcabb573458d223da652c237eee5 Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Tue, 14 Feb 2023 21:39:53 -0500 Subject: [PATCH 05/11] installed redux --- frontend/package-lock.json | 270 ++++++++++++++++++++++++++++++++++--- frontend/package.json | 2 + 2 files changed, 252 insertions(+), 20 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c86fdb06..f63a726f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,8 +8,10 @@ "name": "frontend", "version": "0.0.0", "dependencies": { + "@reduxjs/toolkit": "^1.9.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-redux": "^8.0.5", "react-router-dom": "^6.8.1" }, "devDependencies": { @@ -343,6 +345,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", @@ -897,6 +910,29 @@ "node": ">= 8" } }, + "node_modules/@reduxjs/toolkit": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz", + "integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==", + "dependencies": { + "immer": "^9.0.16", + "redux": "^4.2.0", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.7" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@remix-run/router": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.3.2.tgz", @@ -905,6 +941,15 @@ "node": ">=14" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -920,14 +965,12 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { "version": "18.0.27", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -938,7 +981,7 @@ "version": "18.0.10", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "*" } @@ -946,8 +989,7 @@ "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { "version": "7.3.13", @@ -955,6 +997,11 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.51.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz", @@ -1856,8 +1903,7 @@ "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", - "dev": true + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/debug": { "version": "4.3.4", @@ -3224,6 +3270,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/human-signals": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", @@ -3257,6 +3311,15 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "9.0.19", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz", + "integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -4754,8 +4817,50 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-redux": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", + "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react-refresh": { "version": "0.14.0", @@ -4817,6 +4922,27 @@ "node": ">=8.10.0" } }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "peerDependencies": { + "redux": "^4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -4846,6 +4972,11 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/reselect": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz", + "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -5501,6 +5632,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5956,6 +6095,14 @@ "@babel/helper-plugin-utils": "^7.19.0" } }, + "@babel/runtime": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "requires": { + "regenerator-runtime": "^0.13.11" + } + }, "@babel/template": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", @@ -6265,11 +6412,31 @@ "fastq": "^1.6.0" } }, + "@reduxjs/toolkit": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz", + "integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==", + "requires": { + "immer": "^9.0.16", + "redux": "^4.2.0", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.7" + } + }, "@remix-run/router": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.3.2.tgz", "integrity": "sha512-t54ONhl/h75X94SWsHGQ4G/ZrCEguKSRQr7DrjTciJXW0YU1QhlwYeycvK5JgkzlxmvrK7wq1NB/PLtHxoiDcA==" }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -6285,14 +6452,12 @@ "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "@types/react": { "version": "18.0.27", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", - "dev": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -6303,7 +6468,7 @@ "version": "18.0.10", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", - "dev": true, + "devOptional": true, "requires": { "@types/react": "*" } @@ -6311,8 +6476,7 @@ "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "@types/semver": { "version": "7.3.13", @@ -6320,6 +6484,11 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "@typescript-eslint/eslint-plugin": { "version": "5.51.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz", @@ -6934,8 +7103,7 @@ "csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", - "dev": true + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "debug": { "version": "4.3.4", @@ -7928,6 +8096,14 @@ "has-symbols": "^1.0.2" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "human-signals": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", @@ -7946,6 +8122,11 @@ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "immer": { + "version": "9.0.19", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz", + "integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==" + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -8920,8 +9101,27 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-redux": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", + "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==", + "requires": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } }, "react-refresh": { "version": "0.14.0", @@ -8964,6 +9164,25 @@ "picomatch": "^2.2.1" } }, + "redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "requires": {} + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -8981,6 +9200,11 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "reselect": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz", + "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -9441,6 +9665,12 @@ "punycode": "^2.1.0" } }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index b00008ff..c63a305d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,8 +19,10 @@ ] }, "dependencies": { + "@reduxjs/toolkit": "^1.9.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-redux": "^8.0.5", "react-router-dom": "^6.8.1" }, "devDependencies": { From c44e1804bfd6d75342e1d6d4a9ed27714471630d Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Tue, 14 Feb 2023 21:40:49 -0500 Subject: [PATCH 06/11] changed image folder location --- frontend/src/{components/Navigation => }/imgs/arrow.svg | 0 frontend/src/{components/Navigation => }/imgs/exit.svg | 0 frontend/src/{components/Navigation => }/imgs/hamburger.svg | 0 frontend/src/{components/Navigation => }/imgs/info.svg | 0 frontend/src/{components/Navigation => }/imgs/key.svg | 0 frontend/src/{components/Navigation => }/imgs/link.svg | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename frontend/src/{components/Navigation => }/imgs/arrow.svg (100%) rename frontend/src/{components/Navigation => }/imgs/exit.svg (100%) rename frontend/src/{components/Navigation => }/imgs/hamburger.svg (100%) rename frontend/src/{components/Navigation => }/imgs/info.svg (100%) rename frontend/src/{components/Navigation => }/imgs/key.svg (100%) rename frontend/src/{components/Navigation => }/imgs/link.svg (100%) diff --git a/frontend/src/components/Navigation/imgs/arrow.svg b/frontend/src/imgs/arrow.svg similarity index 100% rename from frontend/src/components/Navigation/imgs/arrow.svg rename to frontend/src/imgs/arrow.svg diff --git a/frontend/src/components/Navigation/imgs/exit.svg b/frontend/src/imgs/exit.svg similarity index 100% rename from frontend/src/components/Navigation/imgs/exit.svg rename to frontend/src/imgs/exit.svg diff --git a/frontend/src/components/Navigation/imgs/hamburger.svg b/frontend/src/imgs/hamburger.svg similarity index 100% rename from frontend/src/components/Navigation/imgs/hamburger.svg rename to frontend/src/imgs/hamburger.svg diff --git a/frontend/src/components/Navigation/imgs/info.svg b/frontend/src/imgs/info.svg similarity index 100% rename from frontend/src/components/Navigation/imgs/info.svg rename to frontend/src/imgs/info.svg diff --git a/frontend/src/components/Navigation/imgs/key.svg b/frontend/src/imgs/key.svg similarity index 100% rename from frontend/src/components/Navigation/imgs/key.svg rename to frontend/src/imgs/key.svg diff --git a/frontend/src/components/Navigation/imgs/link.svg b/frontend/src/imgs/link.svg similarity index 100% rename from frontend/src/components/Navigation/imgs/link.svg rename to frontend/src/imgs/link.svg From 5e5f13b6648435ef33fa4bda985fc61a14b59a7d Mon Sep 17 00:00:00 2001 From: TaylorS15 Date: Tue, 14 Feb 2023 21:43:14 -0500 Subject: [PATCH 07/11] major changes state management now handled with redux responsiveness uses custom hook (hooks.ts) --- frontend/src/App.tsx | 59 ++---------- frontend/src/components/APIKeyModal.tsx | 41 ++++----- frontend/src/components/About.tsx | 19 ++-- .../Conversation.tsx} | 17 ++-- .../{Navigation => }/Navigation.tsx | 91 +++++++------------ .../src/components/Navigation/PastChat.tsx | 1 - frontend/src/hooks.ts | 22 +++++ frontend/src/index.css | 1 + frontend/src/main.tsx | 6 +- frontend/src/store.ts | 48 ++++++++++ 10 files changed, 156 insertions(+), 149 deletions(-) rename frontend/src/components/{DocsGPT/DocsGPT.tsx => Conversation/Conversation.tsx} (51%) rename frontend/src/components/{Navigation => }/Navigation.tsx (68%) delete mode 100644 frontend/src/components/Navigation/PastChat.tsx create mode 100644 frontend/src/hooks.ts create mode 100644 frontend/src/store.ts diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index c0a3a9c0..d6467e2f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,62 +1,17 @@ -import { useEffect, useState } from 'react'; import { Routes, Route } from 'react-router-dom'; -import Navigation from './components/Navigation/Navigation'; -import DocsGPT from './components/DocsGPT/DocsGPT'; +import Navigation from './components/Navigation'; +import Conversation from './components/Conversation/Conversation'; import APIKeyModal from './components/APIKeyModal'; import About from './components/About'; export default function App() { - //Currently using primitive state management. Will most likely be replaced with Redux. - const [isMobile, setIsMobile] = useState(true); - const [isMenuOpen, setIsMenuOpen] = useState(true); - const [isApiModalOpen, setIsApiModalOpen] = useState(false); - const [apiKey, setApiKey] = useState(''); - - const handleResize = () => { - if (window.innerWidth > 768 && isMobile) { - setIsMobile(false); - } else { - setIsMobile(true); - setIsMenuOpen(false); - } - }; - - useEffect(() => { - window.addEventListener('resize', handleResize); - handleResize(); - - return () => { - window.removeEventListener('resize', handleResize); - }; - }, []); - return ( -
- - +
+ + - } - /> - } - /> + } /> + } />
); diff --git a/frontend/src/components/APIKeyModal.tsx b/frontend/src/components/APIKeyModal.tsx index 505f2494..07a8f061 100644 --- a/frontend/src/components/APIKeyModal.tsx +++ b/frontend/src/components/APIKeyModal.tsx @@ -1,30 +1,29 @@ import { useState } from 'react'; - -export default function APIKeyModal({ - isApiModalOpen, - setIsApiModalOpen, - apiKey, +import { useDispatch, useSelector } from 'react-redux'; +import { setApiKey, -}: { - isApiModalOpen: boolean; - setIsApiModalOpen: React.Dispatch>; - apiKey: string; - setApiKey: React.Dispatch>; -}) { - //TODO - Add form validation + toggleApiKeyModal, + selectIsApiKeyModalOpen, +} from '../store'; + +export default function APIKeyModal({}) { + //TODO - Add form validation? //TODO - Connect to backend //TODO - Add link to OpenAI API Key page + const dispatch = useDispatch(); + const isApiModalOpen = useSelector(selectIsApiKeyModalOpen); + const [key, setKey] = useState(''); const [formError, setFormError] = useState(false); - const handleResetKey = () => { - if (!apiKey) { + function handleSubmit() { + if (key.length < 1) { setFormError(true); - } else { - setFormError(false); - setIsApiModalOpen(false); + return; } - }; + dispatch(setApiKey(key)); + dispatch(toggleApiKeyModal()); + } return (
setApiKey(e.target.value)} + onChange={(e) => setKey(e.target.value)} />
{formError && (

Please enter a valid API key

)} @@ -38,7 +40,7 @@ function MobileNavigation({ <> @@ -71,7 +73,7 @@ function MobileNavigation({
setIsApiModalOpen(true)} + onClick={() => dispatch(toggleApiKeyModal())} > info

Reset Key

@@ -82,15 +84,10 @@ function MobileNavigation({ ); } -function DesktopNavigation({ - isMenuOpen, - setIsMenuOpen, - setIsApiModalOpen, -}: { - isMenuOpen: boolean; - setIsMenuOpen: React.Dispatch>; - setIsApiModalOpen: React.Dispatch>; -}) { +function DesktopNavigation() { + const dispatch = useDispatch(); + const isMenuOpen = useSelector(selectIsMenuOpen); + return (
-
- -
- ); -} +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 + + const dispatch = useDispatch(); + const isApiModalOpen = useSelector(selectIsApiKeyModalOpen); + const [key, setKey] = useState(''); + const [formError, setFormError] = useState(false); + + function handleSubmit() { + if (key.length < 1) { + setFormError(true); + return; + } + dispatch(setApiKey(key)); + dispatch(toggleApiKeyModal()); + } + + return ( +
+
+

OpenAI API Key

+

+ Before you can start using DocsGPT we need you to provide an API key + for llm. Currently, we support only OpenAI but soon many more. You can + find it here. +

+ setKey(e.target.value)} + /> +
+ {formError && ( +

Please enter a valid API key

+ )} + +
+
+
+ ); +} diff --git a/frontend/src/components/About.tsx b/frontend/src/components/About.tsx index 533b3945..ddf6d8eb 100644 --- a/frontend/src/components/About.tsx +++ b/frontend/src/components/About.tsx @@ -1,71 +1,54 @@ -import { useSelector } from 'react-redux'; -import { useMediaQuery } from '../hooks'; -import { selectIsMenuOpen } from '../store'; - -//TODO - Add hyperlinks to text -//TODO - Styling - -export default function About() { - const isMobile = useMediaQuery('(max-width: 768px)'); - const isMenuOpen = useSelector(selectIsMenuOpen); - - return ( - //Parent div for all content shown through App.tsx routing needs to have this styling. Might change when state management is updated. -
-
-

About DocsGPT 🦖

-

- Find the information in your documentation through AI-powered - open-source chatbot. Powered by GPT-3, Faiss and LangChain. -

- -
-

- If you want to add your own documentation, please follow the - instruction below: -

-

- 1. Navigate to{' '} - /application folder -

-

- 2. Install dependencies from{' '} - - pip install -r requirements.txt - -

-

- 3. Prepare a .env file. - Copy .env_sample and - create .env with your - OpenAI API token -

-

- 4. Run the app with{' '} - python app.py -

-
- -

- Currently It uses python pandas documentation, so it will respond to - information relevant to pandas. If you want to train it on different - documentation - please follow this guide. -

- -

- If you want to launch it on your own server - follow this guide. -

-
-
- ); -} +//TODO - Add hyperlinks to text +//TODO - Styling + +export default function About() { + return ( + //Parent div for all content shown through App.tsx routing needs to have this styling. Might change when state management is updated. +
+
+

About DocsGPT 🦖

+

+ Find the information in your documentation through AI-powered + open-source chatbot. Powered by GPT-3, Faiss and LangChain. +

+ +
+

+ If you want to add your own documentation, please follow the + instruction below: +

+

+ 1. Navigate to{' '} + /application folder +

+

+ 2. Install dependencies from{' '} + + pip install -r requirements.txt + +

+

+ 3. Prepare a .env file. + Copy .env_sample and + create .env with your + OpenAI API token +

+

+ 4. Run the app with{' '} + python app.py +

+
+ +

+ Currently It uses python pandas documentation, so it will respond to + information relevant to pandas. If you want to train it on different + documentation - please follow this guide. +

+ +

+ If you want to launch it on your own server - follow this guide. +

+
+
+ ); +} diff --git a/frontend/src/components/Conversation/Conversation.tsx b/frontend/src/components/Conversation/Conversation.tsx index d797e94c..909662f3 100644 --- a/frontend/src/components/Conversation/Conversation.tsx +++ b/frontend/src/components/Conversation/Conversation.tsx @@ -1,25 +1,7 @@ -import { useMediaQuery } from '../../hooks'; -import { selectIsMenuOpen } from '../../store'; -import { useSelector } from 'react-redux'; - -export default function Conversation() { - const isMobile = useMediaQuery('(max-width: 768px)'); - const isMenuOpen = useSelector(selectIsMenuOpen); - - return ( - //Parent div for all content shown through App.tsx routing needs to have this styling. -
- Docs GPT Chat Placeholder -
- ); -} +export default function Conversation() { + return ( +
+ Docs GPT Chat Placeholder +
+ ); +} diff --git a/frontend/src/components/Navigation.tsx b/frontend/src/components/Navigation.tsx index de53ddd4..6405e449 100644 --- a/frontend/src/components/Navigation.tsx +++ b/frontend/src/components/Navigation.tsx @@ -1,163 +1,99 @@ -import { useDispatch, useSelector } from 'react-redux'; -import { NavLink } from 'react-router-dom'; -import { useMediaQuery } from '../hooks'; -import { - toggleApiKeyModal, - selectIsMenuOpen, - toggleIsMenuOpen, -} from '../store'; -import Arrow1 from '../imgs/arrow.svg'; -import Hamburger from '../imgs/hamburger.svg'; -import Key from '../imgs/key.svg'; -import Info from '../imgs/info.svg'; -import Link from '../imgs/link.svg'; -import Exit from '../imgs/exit.svg'; - -//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 - -function MobileNavigation({}) { - const dispatch = useDispatch(); - const isMenuOpen = useSelector(selectIsMenuOpen); - - return ( -
-
- {isMenuOpen ? ( - <> - - - ) : ( - <> - - - )} -
- {isMenuOpen && ( - - )} -
- ); -} - -function DesktopNavigation() { - const dispatch = useDispatch(); - const isMenuOpen = useSelector(selectIsMenuOpen); - - return ( -
-
- -
- - {isMenuOpen && ( - <> -
- -
-
dispatch(toggleApiKeyModal())} - > - key -

Reset Key

-
-
- -
- - info -

About

-
- -
- link -

Discord

-
- -
- link -

Github

-
-
- - )} -
- ); -} - -export default function Navigation() { - const isMobile = useMediaQuery('(max-width: 768px)'); - - if (isMobile) { - return ; - } else { - return ; - } -} +import { useDispatch, useSelector } from 'react-redux'; +import { NavLink } from 'react-router-dom'; +import { useMediaQuery } from '../hooks'; +import { toggleApiKeyModal } from '../store'; +import Arrow1 from '../imgs/arrow.svg'; +import Hamburger from '../imgs/hamburger.svg'; +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'; + +//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 + +export default function Navigation({ + navState, + setNavState, +}: { + navState: NavState; + setNavState: (val: NavState) => void; +}) { + const openNav = ( +
+
+ +
+
+ +
+
{ + return; + }} + > + key +

Reset Key

+
+
+ +
+ + info +

About

+
+ +
+ link +

Discord

+
+ +
+ link +

Github

+
+
+
+ ); + + const closedNav = ( + <> +
+
+ +
+
+ + + ); + + return navState === 'OPEN' ? openNav : closedNav; +} diff --git a/frontend/src/models/misc.ts b/frontend/src/models/misc.ts new file mode 100644 index 00000000..43cf45d6 --- /dev/null +++ b/frontend/src/models/misc.ts @@ -0,0 +1 @@ +export type NavState = 'OPEN' | 'CLOSED'; diff --git a/frontend/src/store.ts b/frontend/src/store.ts index e5dcda3f..2f5f76e9 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -1,48 +1,42 @@ -import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit'; - -interface State { - isApiKeyModalOpen: boolean; - apiKey: string; - isMenuOpen: boolean; -} - -const initialState: State = { - isApiKeyModalOpen: false, - apiKey: '', - isMenuOpen: false, -}; - -export const slice = createSlice({ - name: 'app', - initialState, - reducers: { - toggleApiKeyModal: (state) => { - state.isApiKeyModalOpen = !state.isApiKeyModalOpen; - console.log('showApiKeyModal', state.isApiKeyModalOpen); - }, - setApiKey: (state, action: PayloadAction) => { - state.apiKey = action.payload; - console.log('setApiKey', action.payload); - }, - toggleIsMenuOpen: (state) => { - state.isMenuOpen = !state.isMenuOpen; - }, - }, -}); - -export const { toggleApiKeyModal, setApiKey, toggleIsMenuOpen } = slice.actions; - -const store = configureStore({ - reducer: { - app: slice.reducer, - }, -}); - -type RootState = ReturnType; - -export const selectIsApiKeyModalOpen = (state: RootState) => - state.app.isApiKeyModalOpen; -export const selectApiKey = (state: RootState) => state.app.apiKey; -export const selectIsMenuOpen = (state: RootState) => state.app.isMenuOpen; - -export default store; +import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit'; + +interface State { + isApiKeyModalOpen: boolean; + apiKey: string; +} + +const initialState: State = { + isApiKeyModalOpen: false, + apiKey: '', +}; + +export const slice = createSlice({ + name: 'app', + initialState, + reducers: { + toggleApiKeyModal: (state) => { + state.isApiKeyModalOpen = !state.isApiKeyModalOpen; + console.log('showApiKeyModal', state.isApiKeyModalOpen); + }, + setApiKey: (state, action: PayloadAction) => { + state.apiKey = action.payload; + console.log('setApiKey', action.payload); + }, + }, +}); + +export const { toggleApiKeyModal, setApiKey } = slice.actions; + +const store = configureStore({ + reducer: { + app: slice.reducer, + }, +}); + +type RootState = ReturnType; + +export const selectIsApiKeyModalOpen = (state: RootState) => + state.app.isApiKeyModalOpen; +export const selectApiKey = (state: RootState) => state.app.apiKey; + +export default store; From 350ccad077303576ec7a65943d0fa2dd13ae3708 Mon Sep 17 00:00:00 2001 From: ajaythapliyal Date: Sat, 18 Feb 2023 00:25:21 +0530 Subject: [PATCH 10/11] makes the api key modal work --- frontend/src/App.tsx | 21 +++++-- frontend/src/components/APIKeyModal.tsx | 76 ++++++++++++++++--------- frontend/src/components/Navigation.tsx | 18 +++--- frontend/src/models/misc.ts | 2 +- frontend/src/store.ts | 8 ++- 5 files changed, 82 insertions(+), 43 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 48eb5ee2..dc71e004 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 692ff486..41b4c166 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 6405e449..c895a673 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 43cf45d6..27a149d3 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 2f5f76e9..d3d3c177 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; From cb50795ac10e561d64435afbb0f1909175fc2553 Mon Sep 17 00:00:00 2001 From: ajaythapliyal Date: Sat, 18 Feb 2023 00:58:04 +0530 Subject: [PATCH 11/11] reorganizes the code, introduces preference slice --- frontend/src/{components => }/About.tsx | 0 frontend/src/App.tsx | 10 ++--- frontend/src/{components => }/Navigation.tsx | 16 +++---- frontend/src/{imgs => assets}/arrow.svg | 0 frontend/src/{imgs => assets}/exit.svg | 0 frontend/src/{imgs => assets}/hamburger.svg | 0 frontend/src/{imgs => assets}/info.svg | 0 frontend/src/{imgs => assets}/key.svg | 0 frontend/src/{imgs => assets}/link.svg | 0 .../Conversation.tsx | 0 frontend/src/hooks.ts | 22 ---------- .../APIKeyModal.tsx | 2 +- frontend/src/preferences/preferenceSlice.ts | 29 ++++++++++++ frontend/src/store.ts | 44 ++----------------- 14 files changed, 45 insertions(+), 78 deletions(-) rename frontend/src/{components => }/About.tsx (100%) rename frontend/src/{components => }/Navigation.tsx (88%) rename frontend/src/{imgs => assets}/arrow.svg (100%) rename frontend/src/{imgs => assets}/exit.svg (100%) rename frontend/src/{imgs => assets}/hamburger.svg (100%) rename frontend/src/{imgs => assets}/info.svg (100%) rename frontend/src/{imgs => assets}/key.svg (100%) rename frontend/src/{imgs => assets}/link.svg (100%) rename frontend/src/{components/Conversation => conversation}/Conversation.tsx (100%) delete mode 100644 frontend/src/hooks.ts rename frontend/src/{components => preferences}/APIKeyModal.tsx (98%) create mode 100644 frontend/src/preferences/preferenceSlice.ts diff --git a/frontend/src/components/About.tsx b/frontend/src/About.tsx similarity index 100% rename from frontend/src/components/About.tsx rename to frontend/src/About.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index dc71e004..a91b5c00 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,11 +1,11 @@ import { Routes, Route } from 'react-router-dom'; -import Navigation from './components/Navigation'; -import Conversation from './components/Conversation/Conversation'; -import APIKeyModal from './components/APIKeyModal'; -import About from './components/About'; +import Navigation from './Navigation'; +import Conversation from './conversation/Conversation'; +import APIKeyModal from './preferences/APIKeyModal'; +import About from './About'; import { useState } from 'react'; import { ActiveState } from './models/misc'; -import { selectApiKeyStatus } from './store'; +import { selectApiKeyStatus } from './preferences/preferenceSlice'; import { useSelector } from 'react-redux'; export default function App() { diff --git a/frontend/src/components/Navigation.tsx b/frontend/src/Navigation.tsx similarity index 88% rename from frontend/src/components/Navigation.tsx rename to frontend/src/Navigation.tsx index c895a673..cde5accb 100644 --- a/frontend/src/components/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -1,14 +1,10 @@ -import { useDispatch, useSelector } from 'react-redux'; import { NavLink } from 'react-router-dom'; -import { useMediaQuery } from '../hooks'; -import { toggleApiKeyModal } from '../store'; -import Arrow1 from '../imgs/arrow.svg'; -import Hamburger from '../imgs/hamburger.svg'; -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 { ActiveState } from '../models/misc'; +import Arrow1 from './assets/arrow.svg'; +import Hamburger from './assets/hamburger.svg'; +import Key from './assets/key.svg'; +import Info from './assets/info.svg'; +import Link from './assets/link.svg'; +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 diff --git a/frontend/src/imgs/arrow.svg b/frontend/src/assets/arrow.svg similarity index 100% rename from frontend/src/imgs/arrow.svg rename to frontend/src/assets/arrow.svg diff --git a/frontend/src/imgs/exit.svg b/frontend/src/assets/exit.svg similarity index 100% rename from frontend/src/imgs/exit.svg rename to frontend/src/assets/exit.svg diff --git a/frontend/src/imgs/hamburger.svg b/frontend/src/assets/hamburger.svg similarity index 100% rename from frontend/src/imgs/hamburger.svg rename to frontend/src/assets/hamburger.svg diff --git a/frontend/src/imgs/info.svg b/frontend/src/assets/info.svg similarity index 100% rename from frontend/src/imgs/info.svg rename to frontend/src/assets/info.svg diff --git a/frontend/src/imgs/key.svg b/frontend/src/assets/key.svg similarity index 100% rename from frontend/src/imgs/key.svg rename to frontend/src/assets/key.svg diff --git a/frontend/src/imgs/link.svg b/frontend/src/assets/link.svg similarity index 100% rename from frontend/src/imgs/link.svg rename to frontend/src/assets/link.svg diff --git a/frontend/src/components/Conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx similarity index 100% rename from frontend/src/components/Conversation/Conversation.tsx rename to frontend/src/conversation/Conversation.tsx diff --git a/frontend/src/hooks.ts b/frontend/src/hooks.ts deleted file mode 100644 index 45bfb83e..00000000 --- a/frontend/src/hooks.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { useState, useEffect } from 'react'; - -export function useMediaQuery(query: string): boolean { - const [matches, setMatches] = useState(false); - - useEffect(() => { - const media = window.matchMedia(query); - - if (media.matches !== matches) { - setMatches(media.matches); - } - - const listener = () => { - setMatches(media.matches); - }; - - media.addEventListener('resize', listener); - return () => media.removeEventListener('resize', listener); - }, [matches, query]); - - return matches; -} diff --git a/frontend/src/components/APIKeyModal.tsx b/frontend/src/preferences/APIKeyModal.tsx similarity index 98% rename from frontend/src/components/APIKeyModal.tsx rename to frontend/src/preferences/APIKeyModal.tsx index 41b4c166..b440500a 100644 --- a/frontend/src/components/APIKeyModal.tsx +++ b/frontend/src/preferences/APIKeyModal.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useDispatch } from 'react-redux'; import { ActiveState } from '../models/misc'; -import { setApiKey } from '../store'; +import { setApiKey } from './preferenceSlice'; export default function APIKeyModal({ modalState, diff --git a/frontend/src/preferences/preferenceSlice.ts b/frontend/src/preferences/preferenceSlice.ts new file mode 100644 index 00000000..6121f9d9 --- /dev/null +++ b/frontend/src/preferences/preferenceSlice.ts @@ -0,0 +1,29 @@ +import { createSlice } from '@reduxjs/toolkit'; +import store from '../store'; + +interface Preference { + apiKey: string; +} + +const initialState: Preference = { + apiKey: '', +}; + +export const prefSlice = createSlice({ + name: 'preference', + initialState, + reducers: { + setApiKey: (state, action) => { + state.apiKey = action.payload; + }, + }, +}); + +export const { setApiKey } = prefSlice.actions; +export default prefSlice.reducer; + +type RootState = ReturnType; + +export const selectApiKey = (state: RootState) => state.preference.apiKey; +export const selectApiKeyStatus = (state: RootState) => + !!state.preference.apiKey; diff --git a/frontend/src/store.ts b/frontend/src/store.ts index d3d3c177..706e2ee4 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -1,48 +1,12 @@ -import { - configureStore, - createSelector, - createSlice, - PayloadAction, -} from '@reduxjs/toolkit'; +// import { configureStore, createSlice } from '@reduxjs/toolkit'; -interface State { - isApiKeyModalOpen: boolean; - apiKey: string; -} - -const initialState: State = { - isApiKeyModalOpen: false, - apiKey: '', -}; - -export const slice = createSlice({ - name: 'app', - initialState, - reducers: { - toggleApiKeyModal: (state) => { - state.isApiKeyModalOpen = !state.isApiKeyModalOpen; - console.log('showApiKeyModal', state.isApiKeyModalOpen); - }, - setApiKey: (state, action: PayloadAction) => { - state.apiKey = action.payload; - console.log('setApiKey', action.payload); - }, - }, -}); - -export const { toggleApiKeyModal, setApiKey } = slice.actions; +import { configureStore } from '@reduxjs/toolkit'; +import { prefSlice } from './preferences/preferenceSlice'; const store = configureStore({ reducer: { - app: slice.reducer, + preference: prefSlice.reducer, }, }); -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;