diff --git a/src/App.tsx b/src/App.tsx index c4b2626..87851cf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,41 +2,13 @@ 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 { ILoadingState, IFilterQuery } from './types'; - -const genName = (searchQuery: IFilterQuery, path: string): string => { - if (path === '/list' && searchQuery) { - let result = ''; - - if (searchQuery.class_num) { - result = result + searchQuery.class_num + ' класс'; - } - - if (searchQuery.predmet_type) { - result = result + ' ' + searchQuery.predmet_type; - } - - if (searchQuery.teacher) { - result = result + ' ' + searchQuery.teacher; - } - - if (searchQuery.search) { - result = result + ' поиск по "' + searchQuery.search + '"'; - } - - return result; - } - - if (path === '/') { - return 'Банк семинаров'; - } - - return ''; -}; +import NothingFound from './NothingFound'; const useDidUpdate: typeof useEffect = (func, dependencies) => { const didMountRef = useRef(false); @@ -76,10 +48,8 @@ const App = () => { }, [searchQuery]); return ( -
-
-

{genName(searchQuery, history.location.pathname)}

-
+ <> +
@@ -95,10 +65,10 @@ const App = () => { /> -

404

+
-
+ ); }; diff --git a/src/Header/index.tsx b/src/Header/index.tsx new file mode 100644 index 0000000..bf890b3 --- /dev/null +++ b/src/Header/index.tsx @@ -0,0 +1,103 @@ +import React, { Dispatch, SetStateAction, useEffect } from 'react'; +import { motion, Transition } from 'framer-motion'; +import { useHistory } from 'react-router-dom'; + +import { IFilterQuery, ILoadingState } from '../types'; +import './main.css'; +import Logotype from '../Logotype'; + +const genName = ( + searchQuery: IFilterQuery, + path: string, + error: string +): string => { + if (error) { + return error.toString(); + } + if (path === '/list' && searchQuery) { + let result = ''; + + if (searchQuery.class_num) { + result = result + searchQuery.class_num + ' класс'; + } + + if (searchQuery.predmet_type) { + result = result + ' ' + searchQuery.predmet_type; + } + + if (searchQuery.teacher) { + result = result + ' ' + searchQuery.teacher; + } + + if (searchQuery.search) { + result = result + ' поиск по "' + searchQuery.search + '"'; + } + + return result; + } + + if (path === '/') { + return 'Банк семинаров'; + } + + return ''; +}; + +const Header = ({ + query, + loading, + setSearchQuery +}: { + query: IFilterQuery; + loading: ILoadingState; + setSearchQuery: Dispatch>; +}) => { + /* + * Hooks definitions + */ + const history = useHistory(); + + useEffect(() => {}, [loading]); + + /* + * Animations + */ + const headerVariants = { + expanded: { + height: '100vh' + }, + collapsed: { + height: '10vh' + } + }; + + const transition: Transition = { + duration: 0.5, + ease: 'linear' + }; + + return ( + +

{genName(query, history.location.pathname, loading.error)}

+ {loading.fetching ? ( + + ) : ( + '' + )} +
+ ); +}; + +export default Header; diff --git a/src/Header/main.css b/src/Header/main.css new file mode 100644 index 0000000..5c65c6f --- /dev/null +++ b/src/Header/main.css @@ -0,0 +1,40 @@ +#name { + background-color: rgb(54, 54, 69); + padding: 2vh; + color: #ffffff; + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; + position: relative; + z-index: 10; + height: 10vh; + overflow: hidden; +} + +#name h1 { + text-align: center; + line-height: 6vh; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +#loadingLogo { + position: absolute; + width: 75vw; + height: 75vw; + left: 13.5vw; + top: calc((100vh - 75vw) / 2); + z-index: 1000; + background-color: white; + border-radius: 100%; + padding: 1vh; +} + +@media (orientation: landscape) { + #loadingLogo { + top: 25vh; + left: calc((100vw - 50vh) / 2); + width: 50vh; + height: 50vh; + } +} \ No newline at end of file diff --git a/src/Home/fakeData.json b/src/Home/fakeData.json deleted file mode 100644 index b48abf8..0000000 --- a/src/Home/fakeData.json +++ /dev/null @@ -1,111 +0,0 @@ -[{ - "title": "Семинар 10", - "type_num": "Семинары", - "class_num": "1", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 3 - }, - { - "title": "Семинар 10", - "type_num": "Семинары", - "class_num": "1", - "post_date": "2020-09-15", - "predmet_type": "Физика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 3 - }, - { - "title": "Семинар 10", - "type_num": "Семинары", - "class_num": "1", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 1 - }, - { - "title": "Very long text, too long to show it full", - "type_num": "Семинары", - "class_num": "2", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 2 - }, - { - "title": "Семинар 10", - "type_num": "Семинары", - "class_num": "2", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 3 - }, - { - "title": "Семинар 10", - "type_num": "Семинары", - "class_num": "3", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 1 - }, - { - "title": "Very long text, too long to show it full", - "type_num": "Семинары", - "class_num": "3", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 2 - }, - { - "title": "Семинар 10", - "type_num": "Семинары", - "class_num": "11", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 3 - }, - { - "title": "Семинар 10", - "type_num": "Семинары", - "class_num": "10", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 1 - }, - { - "title": "Very long text, too long to show it full", - "type_num": "Семинары", - "class_num": "11", - "post_date": "2020-09-15", - "predmet_type": "Математика", - "teacher": "Ню В.В", - "image": "/code/media/card_img/bxd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd0xb0xd1x80_10_xd0xa1xd0xb5xd0xbcxd0xb8xd0xbdxd_lN2D1k2.jpg", - "slug": "card-3-11-2020-09-15", - "card_id": 2 - } -] \ No newline at end of file diff --git a/src/Home/index.tsx b/src/Home/index.tsx index 0397e97..e4a51d1 100644 --- a/src/Home/index.tsx +++ b/src/Home/index.tsx @@ -2,6 +2,7 @@ import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import Card from '../Card'; +import NothingFound from '../NothingFound'; import { IData, IFilterQuery, ILoadingState } from '../types'; import './main.css'; @@ -38,60 +39,75 @@ const Home = ({ ]; const handleShowMore = (predmet_type: string, class_num: number) => { - setSearchQuery((prev): IFilterQuery => { - return { ...prev, predmet_type, class_num: class_num.toString() }; - }); + setSearchQuery( + (prev): IFilterQuery => { + return { + ...prev, + predmet_type, + class_num: class_num.toString() + }; + } + ); }; return (
- {classes.map((class_num, index) => ( -
-

{class_num} класс

- {subjects.map((subject, jndex) => - data.filter( - (el) => - parseInt(el.class_num) === class_num && - el.predmet_type === subject - ).length ? ( -
-

{subject}

-
-
- {data - .filter( - (el) => - parseInt(el.class_num) === - class_num && - el.predmet_type === subject - ) - .map((el, kndex) => ( - - ))} -
-
- - handleShowMore( - subject, - class_num + {classes.length ? ( + classes.map((class_num, index) => ( +
+

{class_num} класс

+ {subjects.map((subject, jndex) => + data.filter( + (el) => + parseInt(el.class_num) === class_num && + el.predmet_type === subject + ).length ? ( +
+

{subject}

+
+
+ {data + .filter( + (el) => + parseInt( + el.class_num + ) === class_num && + el.predmet_type === + subject ) - } - to={'/list'} - > - Больше → - + .map((el, kndex) => ( + + ))} +
+
+ + handleShowMore( + subject, + class_num + ) + } + to={'/list'} + > + Больше → + +
-
- ) : ( - '' - ) - )} + ) : ( + '' + ) + )} -
-
- ))} +
+
+ )) + ) : ( + + )}
); }; diff --git a/src/Home/main.css b/src/Home/main.css index c1b779d..4e3d607 100644 --- a/src/Home/main.css +++ b/src/Home/main.css @@ -7,6 +7,7 @@ padding-top: calc(20px + 2vh); margin-top: -20px; position: relative; + overflow: visible; } .subjectContainer { @@ -69,11 +70,11 @@ } .classContainer:nth-child(odd) .showMore { - background: linear-gradient(to right, rgba(244, 244, 244, 0) 25%, rgb(244, 244, 244) 70%); + background: linear-gradient( to right, rgba(244, 244, 244, 0) 25%, rgb(244, 244, 244) 70%); } .classContainer:nth-child(even) .showMore { - background: linear-gradient(to right, rgba(255, 255, 255, 0) 25%, rgb(255, 255, 255) 70%); + background: linear-gradient( to right, rgba(255, 255, 255, 0) 25%, rgb(255, 255, 255) 70%); } @@ -84,4 +85,14 @@ .showMore a { color: rgb(54, 54, 69); text-decoration: none; +} + +@media (orientation: landscape) { + .classContainer { + padding-left: 20vw; + padding-right: 20vw; + } + .classContainer .curve { + left: 2vh; + } } \ No newline at end of file diff --git a/src/Logotype/index.tsx b/src/Logotype/index.tsx new file mode 100644 index 0000000..18e7bfa --- /dev/null +++ b/src/Logotype/index.tsx @@ -0,0 +1,26 @@ +import React, { Dispatch, SetStateAction } from 'react'; +import { Link } from 'react-router-dom'; + +import { emptyQuery } from '../Navbar/utils'; +import { IFilterQuery } from '../types'; +import LogoImage from './logo.png'; +import './main.css' + +const Logotype = ({ + setSearchQuery +}: { + setSearchQuery: Dispatch>; +}) => { + return ( + { + emptyQuery(setSearchQuery); + }} + > + + + ); +}; + +export default Logotype; diff --git a/src/Navbar/logo.png b/src/Logotype/logo.png similarity index 100% rename from src/Navbar/logo.png rename to src/Logotype/logo.png diff --git a/src/Logotype/main.css b/src/Logotype/main.css new file mode 100644 index 0000000..ddd7c95 --- /dev/null +++ b/src/Logotype/main.css @@ -0,0 +1,21 @@ +#logo { + height: 6vh; + width: 6vh; + background-color: white; + border-radius: 100%; + padding: 1vh; + box-sizing: border-box; +} + +#loadingLogo #logo { + height: calc(75vw - 2vh); + width: calc(75vw - 2vh); + padding: 0; +} + +@media (orientation: landscape) { + #loadingLogo #logo { + width: 48vh; + height: 48vh; + } +} \ No newline at end of file diff --git a/src/Navbar/index.tsx b/src/Navbar/index.tsx index 7703e1f..4e44cc4 100644 --- a/src/Navbar/index.tsx +++ b/src/Navbar/index.tsx @@ -7,16 +7,13 @@ import React, { useState } from 'react'; import { motion } from 'framer-motion'; -import { Link } from 'react-router-dom'; import './main.css'; - -import LogoImage from './logo.png'; import FilterIcon from './filter.svg'; import SearchIcon from './search.svg'; import { IFilterQuery } from '../types'; -import { emptyQuery } from './utils'; import { useFocus } from '../utils'; +import Logotype from '../Logotype'; const Navbar = ({ setSearchQuery, @@ -42,7 +39,6 @@ const Navbar = ({ useEffect(() => { if (formRef.current) { for (const [key, value] of Object.entries(query)) { - console.log(key, value); if (formRef.current.elements.namedItem(key)) { (formRef.current.elements.namedItem( key @@ -143,14 +139,7 @@ const Navbar = ({ animate={filtersCollapsed ? 'closed' : 'open'} >