From 101f8c4bacbdefdee2b85cd286bb28bdba772a83 Mon Sep 17 00:00:00 2001 From: Dm1tr1y147 Date: Sun, 20 Sep 2020 01:32:48 +0500 Subject: [PATCH] Globally refactored project structure, added login and upload document forms --- src/App.tsx | 32 +++++-- src/{ => components/lists}/Card/index.tsx | 2 +- src/{ => components/lists}/Card/main.css | 0 .../navigation}/Header/animations.ts | 0 .../navigation}/Header/index.tsx | 2 +- .../navigation}/Header/main.css | 0 .../navigation}/Header/utils.ts | 11 ++- .../navigation}/Logotype/index.tsx | 2 +- .../navigation}/Logotype/logo.png | Bin .../navigation}/Logotype/main.css | 0 .../navigation}/Navbar/animations.ts | 0 .../navigation}/Navbar/filter.svg | 0 .../navigation}/Navbar/handlers.ts | 2 +- .../navigation}/Navbar/index.tsx | 4 +- .../navigation}/Navbar/main.css | 0 .../navigation}/Navbar/search.svg | 0 .../navigation}/Navbar/utils.ts | 2 +- src/components/uploadForm/Select/index.tsx | 25 ++++++ src/components/uploadForm/Select/main.css | 0 src/utils.ts | 25 +++++- src/views/Admin/LogInForm/handlers.ts | 13 +++ src/views/Admin/LogInForm/index.tsx | 40 +++++++++ src/views/Admin/LogInForm/main.css | 0 src/views/Admin/UploadForm/index.tsx | 78 ++++++++++++++++++ src/views/Admin/UploadForm/main.css | 0 src/views/Admin/UploadForm/selectOptions.json | 20 +++++ src/views/Admin/index.tsx | 7 ++ src/views/Admin/main.css | 0 src/{ => views}/Home/handlers.ts | 2 +- src/{ => views}/Home/index.tsx | 4 +- src/{ => views}/Home/main.css | 0 src/{ => views}/NothingFound/icon.svg | 0 src/{ => views}/NothingFound/index.tsx | 2 +- src/{ => views}/NothingFound/main.css | 0 src/{ => views}/SubjectList/index.tsx | 6 +- src/{ => views}/SubjectList/main.css | 0 36 files changed, 256 insertions(+), 23 deletions(-) rename src/{ => components/lists}/Card/index.tsx (90%) rename src/{ => components/lists}/Card/main.css (100%) rename src/{ => components/navigation}/Header/animations.ts (100%) rename src/{ => components/navigation}/Header/index.tsx (95%) rename src/{ => components/navigation}/Header/main.css (100%) rename src/{ => components/navigation}/Header/utils.ts (83%) rename src/{ => components/navigation}/Logotype/index.tsx (92%) rename src/{ => components/navigation}/Logotype/logo.png (100%) rename src/{ => components/navigation}/Logotype/main.css (100%) rename src/{ => components/navigation}/Navbar/animations.ts (100%) rename src/{ => components/navigation}/Navbar/filter.svg (100%) rename src/{ => components/navigation}/Navbar/handlers.ts (96%) rename src/{ => components/navigation}/Navbar/index.tsx (98%) rename src/{ => components/navigation}/Navbar/main.css (100%) rename src/{ => components/navigation}/Navbar/search.svg (100%) rename src/{ => components/navigation}/Navbar/utils.ts (91%) create mode 100644 src/components/uploadForm/Select/index.tsx create mode 100644 src/components/uploadForm/Select/main.css create mode 100644 src/views/Admin/LogInForm/handlers.ts create mode 100644 src/views/Admin/LogInForm/index.tsx create mode 100644 src/views/Admin/LogInForm/main.css create mode 100644 src/views/Admin/UploadForm/index.tsx create mode 100644 src/views/Admin/UploadForm/main.css create mode 100644 src/views/Admin/UploadForm/selectOptions.json create mode 100644 src/views/Admin/index.tsx create mode 100644 src/views/Admin/main.css rename src/{ => views}/Home/handlers.ts (90%) rename src/{ => views}/Home/index.tsx (97%) rename src/{ => views}/Home/main.css (100%) rename src/{ => views}/NothingFound/icon.svg (100%) rename src/{ => views}/NothingFound/index.tsx (92%) rename src/{ => views}/NothingFound/main.css (100%) rename src/{ => views}/SubjectList/index.tsx (89%) rename src/{ => views}/SubjectList/main.css (100%) diff --git a/src/App.tsx b/src/App.tsx index 87851cf..f70283c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,13 +2,15 @@ import React, { useEffect, useRef, useState } from 'react'; import { Switch, Route, useHistory } from 'react-router-dom'; import './App.css'; -import Header from './Header'; -import Home from './Home'; -import Navbar from './Navbar'; -import { queryIsEmpty } from './Navbar/utils'; -import SubjectList from './SubjectList'; +import Header from './components/navigation/Header'; +import Home from './views/Home'; +import Navbar from './components/navigation/Navbar'; +import { queryIsEmpty } from './components/navigation/Navbar/utils'; +import SubjectList from './views/SubjectList'; import { ILoadingState, IFilterQuery } from './types'; -import NothingFound from './NothingFound'; +import NothingFound from './views/NothingFound'; +import UploadForm from './views/Admin/UploadForm'; +import LogInForm from './views/Admin/LogInForm'; const useDidUpdate: typeof useEffect = (func, dependencies) => { const didMountRef = useRef(false); @@ -28,6 +30,8 @@ const useDidUpdate: typeof useEffect = (func, dependencies) => { const App = () => { const history = useHistory(); + const [token, setToken] = useState(localStorage.getItem('token')); + const [loading, setLoading] = useState({ fetching: true, error: '' @@ -49,7 +53,11 @@ const App = () => { return ( <> -
+
@@ -64,6 +72,16 @@ const App = () => { setLoading={setLoading} /> + + + + + + diff --git a/src/Card/index.tsx b/src/components/lists/Card/index.tsx similarity index 90% rename from src/Card/index.tsx rename to src/components/lists/Card/index.tsx index bdb7f8f..f7b3b15 100644 --- a/src/Card/index.tsx +++ b/src/components/lists/Card/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { IData } from '../types'; +import { IData } from '../../../types'; import './main.css'; diff --git a/src/Card/main.css b/src/components/lists/Card/main.css similarity index 100% rename from src/Card/main.css rename to src/components/lists/Card/main.css diff --git a/src/Header/animations.ts b/src/components/navigation/Header/animations.ts similarity index 100% rename from src/Header/animations.ts rename to src/components/navigation/Header/animations.ts diff --git a/src/Header/index.tsx b/src/components/navigation/Header/index.tsx similarity index 95% rename from src/Header/index.tsx rename to src/components/navigation/Header/index.tsx index a766749..59eafab 100644 --- a/src/Header/index.tsx +++ b/src/components/navigation/Header/index.tsx @@ -2,7 +2,7 @@ import React, { Dispatch, SetStateAction } from 'react'; import { motion } from 'framer-motion'; import { useLocation } from 'react-router-dom'; -import { IFilterQuery, ILoadingState } from '../types'; +import { IFilterQuery, ILoadingState } from '../../../types'; import './main.css'; import Logotype from '../Logotype'; import { genName } from './utils'; diff --git a/src/Header/main.css b/src/components/navigation/Header/main.css similarity index 100% rename from src/Header/main.css rename to src/components/navigation/Header/main.css diff --git a/src/Header/utils.ts b/src/components/navigation/Header/utils.ts similarity index 83% rename from src/Header/utils.ts rename to src/components/navigation/Header/utils.ts index f35b2a7..43201ea 100644 --- a/src/Header/utils.ts +++ b/src/components/navigation/Header/utils.ts @@ -1,4 +1,4 @@ -import { IFilterQuery } from '../types'; +import { IFilterQuery } from '../../../types'; const genName = ( searchQuery: IFilterQuery, @@ -8,6 +8,15 @@ const genName = ( if (error) { return error.toString(); } + + if (path === '/u') { + return 'Upload form'; + } + + if (path === '/l') { + return 'login'; + } + if (path === '/list' && searchQuery) { let result = ''; diff --git a/src/Logotype/index.tsx b/src/components/navigation/Logotype/index.tsx similarity index 92% rename from src/Logotype/index.tsx rename to src/components/navigation/Logotype/index.tsx index c1fa348..30ccf27 100644 --- a/src/Logotype/index.tsx +++ b/src/components/navigation/Logotype/index.tsx @@ -2,7 +2,7 @@ import React, { Dispatch, SetStateAction } from 'react'; import { Link } from 'react-router-dom'; import { emptyQuery } from '../Navbar/utils'; -import { IFilterQuery } from '../types'; +import { IFilterQuery } from '../../../types'; import LogoImage from './logo.png'; import './main.css'; diff --git a/src/Logotype/logo.png b/src/components/navigation/Logotype/logo.png similarity index 100% rename from src/Logotype/logo.png rename to src/components/navigation/Logotype/logo.png diff --git a/src/Logotype/main.css b/src/components/navigation/Logotype/main.css similarity index 100% rename from src/Logotype/main.css rename to src/components/navigation/Logotype/main.css diff --git a/src/Navbar/animations.ts b/src/components/navigation/Navbar/animations.ts similarity index 100% rename from src/Navbar/animations.ts rename to src/components/navigation/Navbar/animations.ts diff --git a/src/Navbar/filter.svg b/src/components/navigation/Navbar/filter.svg similarity index 100% rename from src/Navbar/filter.svg rename to src/components/navigation/Navbar/filter.svg diff --git a/src/Navbar/handlers.ts b/src/components/navigation/Navbar/handlers.ts similarity index 96% rename from src/Navbar/handlers.ts rename to src/components/navigation/Navbar/handlers.ts index 5ee8e62..c0c7143 100644 --- a/src/Navbar/handlers.ts +++ b/src/components/navigation/Navbar/handlers.ts @@ -1,5 +1,5 @@ import { Dispatch, RefObject, SetStateAction } from 'react'; -import { IFilterQuery } from '../types'; +import { IFilterQuery } from '../../../types'; const handleFiltersButton = ( filtersCollapsed: boolean, diff --git a/src/Navbar/index.tsx b/src/components/navigation/Navbar/index.tsx similarity index 98% rename from src/Navbar/index.tsx rename to src/components/navigation/Navbar/index.tsx index fc0065e..0bca228 100644 --- a/src/Navbar/index.tsx +++ b/src/components/navigation/Navbar/index.tsx @@ -10,8 +10,8 @@ import { motion } from 'framer-motion'; import './main.css'; import FilterIcon from './filter.svg'; import SearchIcon from './search.svg'; -import { IFilterQuery } from '../types'; -import { useFocus } from '../utils'; +import { IFilterQuery } from '../../../types'; +import { useFocus } from '../../../utils'; import Logotype from '../Logotype'; import { filtersVariants, diff --git a/src/Navbar/main.css b/src/components/navigation/Navbar/main.css similarity index 100% rename from src/Navbar/main.css rename to src/components/navigation/Navbar/main.css diff --git a/src/Navbar/search.svg b/src/components/navigation/Navbar/search.svg similarity index 100% rename from src/Navbar/search.svg rename to src/components/navigation/Navbar/search.svg diff --git a/src/Navbar/utils.ts b/src/components/navigation/Navbar/utils.ts similarity index 91% rename from src/Navbar/utils.ts rename to src/components/navigation/Navbar/utils.ts index 6cec7b0..625b3dc 100644 --- a/src/Navbar/utils.ts +++ b/src/components/navigation/Navbar/utils.ts @@ -1,5 +1,5 @@ import { Dispatch, SetStateAction } from 'react'; -import { IFilterQuery } from '../types'; +import { IFilterQuery } from '../../../types'; const queryIsEmpty = (q: IFilterQuery): boolean => { for (const value of Object.values(q)) { diff --git a/src/components/uploadForm/Select/index.tsx b/src/components/uploadForm/Select/index.tsx new file mode 100644 index 0000000..7bd09b8 --- /dev/null +++ b/src/components/uploadForm/Select/index.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +type props = { + label: string; + name: string; + options: string[]; +}; + +const Select: React.FC = ({ label, name, options }) => { + return ( + <> + + + + ); +}; + +export default Select; diff --git a/src/components/uploadForm/Select/main.css b/src/components/uploadForm/Select/main.css new file mode 100644 index 0000000..e69de29 diff --git a/src/utils.ts b/src/utils.ts index 23c3f65..da3e8f0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,4 +8,27 @@ const useFocus = (focusRef: React.RefObject) => { return setFocus; }; -export { useFocus }; +const handleFormSubmit = ( + e: React.FormEvent, + uri: string, + callBack?: (res: Response) => void, + headers?: Headers | string[][] | Record | undefined +) => { + e.preventDefault(); + const data = new FormData(e.currentTarget); + + const options: RequestInit = { + method: 'POST', + body: data, + headers: headers + }; + + fetch('https://upml-bank.dmitriy.icu/' + uri, options) + .then((res) => { + if (!res.ok) throw res.statusText; + if (callBack) callBack(res); + }) + .catch((err) => console.log(err)); +}; + +export { useFocus, handleFormSubmit }; diff --git a/src/views/Admin/LogInForm/handlers.ts b/src/views/Admin/LogInForm/handlers.ts new file mode 100644 index 0000000..5d77d68 --- /dev/null +++ b/src/views/Admin/LogInForm/handlers.ts @@ -0,0 +1,13 @@ +import { Dispatch, SetStateAction } from 'react'; + +const handleSuccessfulLogin = ( + res: Response, + setToken: Dispatch> +) => { + res.json().then(({ token }) => { + localStorage.setItem('token', token); + setToken(token); + }); +}; + +export { handleSuccessfulLogin }; diff --git a/src/views/Admin/LogInForm/index.tsx b/src/views/Admin/LogInForm/index.tsx new file mode 100644 index 0000000..e9a7086 --- /dev/null +++ b/src/views/Admin/LogInForm/index.tsx @@ -0,0 +1,40 @@ +import React, { Dispatch, SetStateAction, useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; +import { ILoadingState } from '../../../types'; +import { handleFormSubmit } from '../../../utils'; +import { handleSuccessfulLogin } from './handlers'; + +type props = { + setLoading: Dispatch>; + token: string | null; + setToken: Dispatch>; +}; + +const LogInForm: React.FC = ({ setLoading, token, setToken }) => { + const { push: historyPush } = useHistory(); + + useEffect(() => { + setLoading({ fetching: false, error: '' }); + if (token) { + historyPush('/u'); + } + }, [setLoading, historyPush, token]); + + return ( +
+ handleFormSubmit(e, 'api/login', (res: Response) => handleSuccessfulLogin(res, setToken)) + } + > + + + + + + + +
+ ); +}; + +export default LogInForm; diff --git a/src/views/Admin/LogInForm/main.css b/src/views/Admin/LogInForm/main.css new file mode 100644 index 0000000..e69de29 diff --git a/src/views/Admin/UploadForm/index.tsx b/src/views/Admin/UploadForm/index.tsx new file mode 100644 index 0000000..7cfd11a --- /dev/null +++ b/src/views/Admin/UploadForm/index.tsx @@ -0,0 +1,78 @@ +import React, { Dispatch, SetStateAction, useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; + +import Select from '../../../components/uploadForm/Select'; +import { ILoadingState } from '../../../types'; +import { handleFormSubmit } from '../../../utils'; +import selectOptions from './selectOptions.json'; + +type props = { + setLoading: Dispatch>; + token: string | null; + setToken: Dispatch>; +}; + +const UploadForm: React.FC = ({ setLoading, token, setToken }) => { + const { push: historyPush } = useHistory(); + + useEffect(() => { + setLoading({ fetching: false, error: '' }); + if (!token) { + historyPush('/l'); + } + }, [setLoading, historyPush, token]); + + return ( + <> +
+ handleFormSubmit(e, 'api/card/create', undefined, { + Authorization: `Token ${localStorage.token}` + }) + } + > + + + + + + + + + + + +
+ + + ); +}; + +export default UploadForm; diff --git a/src/views/Admin/UploadForm/main.css b/src/views/Admin/UploadForm/main.css new file mode 100644 index 0000000..e69de29 diff --git a/src/views/Admin/UploadForm/selectOptions.json b/src/views/Admin/UploadForm/selectOptions.json new file mode 100644 index 0000000..fb8d864 --- /dev/null +++ b/src/views/Admin/UploadForm/selectOptions.json @@ -0,0 +1,20 @@ +{ + "teacher": [ + "Попов Д.А", + "Ильин А.Б", + "Пачин И.М", + "Николаева Л.Н", + "Ню В.В", + "Вишневская Е.А", + "Некрасов М.В", + "Попова Н.А", + "Пачин М.Ф", + "Керамов Н.Д", + "Новожилова В.И", + "Шпехт А.Ю", + "Конкина Н.В" + ], + "type_num": ["Семестровки", "Семинары", "Потоковые"], + "class_num": ["10", "11"], + "predmet_type": ["Математика", "Физика", "Информатика"] +} \ No newline at end of file diff --git a/src/views/Admin/index.tsx b/src/views/Admin/index.tsx new file mode 100644 index 0000000..e3351c4 --- /dev/null +++ b/src/views/Admin/index.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const Admin: React.FC = () => { + return
; +}; + +export default Admin; diff --git a/src/views/Admin/main.css b/src/views/Admin/main.css new file mode 100644 index 0000000..e69de29 diff --git a/src/Home/handlers.ts b/src/views/Home/handlers.ts similarity index 90% rename from src/Home/handlers.ts rename to src/views/Home/handlers.ts index 1dea41a..8164f37 100644 --- a/src/Home/handlers.ts +++ b/src/views/Home/handlers.ts @@ -1,5 +1,5 @@ import { Dispatch, SetStateAction } from 'react'; -import { IFilterQuery } from '../types'; +import { IFilterQuery } from '../../types'; const handleShowMore = ( predmet_type: string, diff --git a/src/Home/index.tsx b/src/views/Home/index.tsx similarity index 97% rename from src/Home/index.tsx rename to src/views/Home/index.tsx index eeb0854..8379354 100644 --- a/src/Home/index.tsx +++ b/src/views/Home/index.tsx @@ -1,9 +1,9 @@ import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; -import Card from '../Card'; +import Card from '../../components/lists/Card'; import NothingFound from '../NothingFound'; -import { IData, IFilterQuery, ILoadingState } from '../types'; +import { IData, IFilterQuery, ILoadingState } from '../../types'; import { handleShowMore } from './handlers'; import './main.css'; diff --git a/src/Home/main.css b/src/views/Home/main.css similarity index 100% rename from src/Home/main.css rename to src/views/Home/main.css diff --git a/src/NothingFound/icon.svg b/src/views/NothingFound/icon.svg similarity index 100% rename from src/NothingFound/icon.svg rename to src/views/NothingFound/icon.svg diff --git a/src/NothingFound/index.tsx b/src/views/NothingFound/index.tsx similarity index 92% rename from src/NothingFound/index.tsx rename to src/views/NothingFound/index.tsx index 8f50867..dcdbe71 100644 --- a/src/NothingFound/index.tsx +++ b/src/views/NothingFound/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, Dispatch, SetStateAction } from 'react'; import './main.css'; import icon from './icon.svg'; -import { ILoadingState } from '../types'; +import { ILoadingState } from '../../types'; type props = { setLoading?: Dispatch>; diff --git a/src/NothingFound/main.css b/src/views/NothingFound/main.css similarity index 100% rename from src/NothingFound/main.css rename to src/views/NothingFound/main.css diff --git a/src/SubjectList/index.tsx b/src/views/SubjectList/index.tsx similarity index 89% rename from src/SubjectList/index.tsx rename to src/views/SubjectList/index.tsx index 9a49fa2..90f1f58 100644 --- a/src/SubjectList/index.tsx +++ b/src/views/SubjectList/index.tsx @@ -1,9 +1,9 @@ import React, { useEffect, useState, Dispatch, SetStateAction } from 'react'; import { useHistory } from 'react-router-dom'; -import { IData, ILoadingState, IFilterQuery } from '../types'; -import { queryIsEmpty } from '../Navbar/utils'; -import Card from '../Card'; +import { IData, ILoadingState, IFilterQuery } from '../../types'; +import { queryIsEmpty } from '../../components/navigation/Navbar/utils'; +import Card from '../../components/lists/Card'; import './main.css'; import NothingFound from '../NothingFound'; diff --git a/src/SubjectList/main.css b/src/views/SubjectList/main.css similarity index 100% rename from src/SubjectList/main.css rename to src/views/SubjectList/main.css