Refactored components code
This commit is contained in:
parent
64340c4ef0
commit
c50ad9f2b9
@ -3,7 +3,11 @@ import { IData } from '../types';
|
|||||||
|
|
||||||
import './main.css';
|
import './main.css';
|
||||||
|
|
||||||
const Card = ({ data }: { data: IData }) => (
|
type props = {
|
||||||
|
data: IData;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Card: React.FC<props> = ({ data }) => (
|
||||||
<a
|
<a
|
||||||
className="card"
|
className="card"
|
||||||
href={'/' + data.image.slice(data.image.indexOf('media'))}
|
href={'/' + data.image.slice(data.image.indexOf('media'))}
|
||||||
|
23
src/Header/animations.ts
Normal file
23
src/Header/animations.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { Transition, Variants } from 'framer-motion';
|
||||||
|
|
||||||
|
const headerVariants: Variants = {
|
||||||
|
expanded: {
|
||||||
|
height: '100vh'
|
||||||
|
},
|
||||||
|
collapsed: {
|
||||||
|
height: '10vh'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerTransition: Transition = {
|
||||||
|
duration: 0.5,
|
||||||
|
ease: 'linear'
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadingLogoTransition: Transition = {
|
||||||
|
loop: Infinity,
|
||||||
|
ease: 'linear',
|
||||||
|
duration: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
export { headerVariants, headerTransition, loadingLogoTransition };
|
@ -1,95 +1,43 @@
|
|||||||
import React, { Dispatch, SetStateAction, useEffect } from 'react';
|
import React, { Dispatch, SetStateAction } from 'react';
|
||||||
import { motion, Transition } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
import { IFilterQuery, ILoadingState } from '../types';
|
import { IFilterQuery, ILoadingState } from '../types';
|
||||||
import './main.css';
|
import './main.css';
|
||||||
import Logotype from '../Logotype';
|
import Logotype from '../Logotype';
|
||||||
|
import { genName } from './utils';
|
||||||
|
import {
|
||||||
|
headerTransition,
|
||||||
|
headerVariants,
|
||||||
|
loadingLogoTransition
|
||||||
|
} from './animations';
|
||||||
|
|
||||||
const genName = (
|
type props = {
|
||||||
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;
|
query: IFilterQuery;
|
||||||
loading: ILoadingState;
|
loading: ILoadingState;
|
||||||
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
const Header: React.FC<props> = ({ query, loading, setSearchQuery }) => {
|
||||||
/*
|
/*
|
||||||
* Hooks definitions
|
* Hooks definitions
|
||||||
*/
|
*/
|
||||||
const history = useHistory();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
useEffect(() => {}, [loading]);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Animations
|
|
||||||
*/
|
|
||||||
const headerVariants = {
|
|
||||||
expanded: {
|
|
||||||
height: '100vh'
|
|
||||||
},
|
|
||||||
collapsed: {
|
|
||||||
height: '10vh'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const transition: Transition = {
|
|
||||||
duration: 0.5,
|
|
||||||
ease: 'linear'
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.header
|
<motion.header
|
||||||
id="name"
|
id="name"
|
||||||
variants={headerVariants}
|
variants={headerVariants}
|
||||||
transition={transition}
|
transition={headerTransition}
|
||||||
animate={loading.fetching ? 'expanded' : 'collapsed'}
|
animate={loading.fetching ? 'expanded' : 'collapsed'}
|
||||||
initial="expanded"
|
initial="expanded"
|
||||||
>
|
>
|
||||||
<h1>{genName(query, history.location.pathname, loading.error)}</h1>
|
<h1>{genName(query, pathname, loading.error)}</h1>
|
||||||
{loading.fetching ? (
|
{loading.fetching ? (
|
||||||
<motion.div
|
<motion.div
|
||||||
id="loadingLogo"
|
id="loadingLogo"
|
||||||
animate={{ rotate: 360 }}
|
animate={{ rotate: 360 }}
|
||||||
transition={{ loop: Infinity, ease: 'linear', duration: 3 }}
|
transition={loadingLogoTransition}
|
||||||
>
|
>
|
||||||
<Logotype setSearchQuery={setSearchQuery} />
|
<Logotype setSearchQuery={setSearchQuery} />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
40
src/Header/utils.ts
Normal file
40
src/Header/utils.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { IFilterQuery } from '../types';
|
||||||
|
|
||||||
|
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 '';
|
||||||
|
};
|
||||||
|
|
||||||
|
export { genName };
|
20
src/Home/handlers.ts
Normal file
20
src/Home/handlers.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Dispatch, SetStateAction } from 'react';
|
||||||
|
import { IFilterQuery } from '../types';
|
||||||
|
|
||||||
|
const handleShowMore = (
|
||||||
|
predmet_type: string,
|
||||||
|
class_num: number,
|
||||||
|
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>
|
||||||
|
) => {
|
||||||
|
setSearchQuery(
|
||||||
|
(prev): IFilterQuery => {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
predmet_type,
|
||||||
|
class_num: class_num.toString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { handleShowMore };
|
@ -4,15 +4,15 @@ import { Link } from 'react-router-dom';
|
|||||||
import Card from '../Card';
|
import Card from '../Card';
|
||||||
import NothingFound from '../NothingFound';
|
import NothingFound from '../NothingFound';
|
||||||
import { IData, IFilterQuery, ILoadingState } from '../types';
|
import { IData, IFilterQuery, ILoadingState } from '../types';
|
||||||
|
import { handleShowMore } from './handlers';
|
||||||
import './main.css';
|
import './main.css';
|
||||||
|
|
||||||
const Home = ({
|
type props = {
|
||||||
setLoading,
|
|
||||||
setSearchQuery
|
|
||||||
}: {
|
|
||||||
setLoading: Dispatch<SetStateAction<ILoadingState>>;
|
setLoading: Dispatch<SetStateAction<ILoadingState>>;
|
||||||
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
const Home: React.FC<props> = ({ setLoading, setSearchQuery }) => {
|
||||||
const [data, setData] = useState<IData[]>([]);
|
const [data, setData] = useState<IData[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -38,18 +38,6 @@ const Home = ({
|
|||||||
...Array.from(new Set(data.map((el) => el.predmet_type).sort()))
|
...Array.from(new Set(data.map((el) => el.predmet_type).sort()))
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleShowMore = (predmet_type: string, class_num: number) => {
|
|
||||||
setSearchQuery(
|
|
||||||
(prev): IFilterQuery => {
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
predmet_type,
|
|
||||||
class_num: class_num.toString()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="homeContainer">
|
<main className="homeContainer">
|
||||||
{classes.length ? (
|
{classes.length ? (
|
||||||
@ -87,7 +75,8 @@ const Home = ({
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleShowMore(
|
handleShowMore(
|
||||||
subject,
|
subject,
|
||||||
class_num
|
class_num,
|
||||||
|
setSearchQuery
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
to={'/list'}
|
to={'/list'}
|
||||||
|
@ -4,13 +4,13 @@ import { Link } from 'react-router-dom';
|
|||||||
import { emptyQuery } from '../Navbar/utils';
|
import { emptyQuery } from '../Navbar/utils';
|
||||||
import { IFilterQuery } from '../types';
|
import { IFilterQuery } from '../types';
|
||||||
import LogoImage from './logo.png';
|
import LogoImage from './logo.png';
|
||||||
import './main.css'
|
import './main.css';
|
||||||
|
|
||||||
const Logotype = ({
|
type props = {
|
||||||
setSearchQuery
|
|
||||||
}: {
|
|
||||||
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
const Logotype: React.FC<props> = ({ setSearchQuery }) => {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to="/"
|
to="/"
|
||||||
|
45
src/Navbar/animations.ts
Normal file
45
src/Navbar/animations.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { Transition, Variants } from 'framer-motion'
|
||||||
|
|
||||||
|
const searchVariants: Variants = {
|
||||||
|
open: {
|
||||||
|
width: 'calc(100vw - 4vh)',
|
||||||
|
display: 'block'
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
width: '6vh',
|
||||||
|
transitionEnd: {
|
||||||
|
display: 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const navVariants: Variants = {
|
||||||
|
open: {
|
||||||
|
height: '100vh',
|
||||||
|
borderTopLeftRadius: 0,
|
||||||
|
borderTopRightRadius: 0
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
height: '10vh',
|
||||||
|
borderTopLeftRadius: '20px',
|
||||||
|
borderTopRightRadius: '20px'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const filtersVariants: Variants = {
|
||||||
|
open: {
|
||||||
|
height: '100vh',
|
||||||
|
padding: '2vh'
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
height: 0,
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const transition: Transition = {
|
||||||
|
ease: 'easeIn',
|
||||||
|
duration: 0.5
|
||||||
|
};
|
||||||
|
|
||||||
|
export { filtersVariants, navVariants, searchVariants, transition };
|
49
src/Navbar/handlers.ts
Normal file
49
src/Navbar/handlers.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { Dispatch, RefObject, SetStateAction } from 'react';
|
||||||
|
import { IFilterQuery } from '../types';
|
||||||
|
|
||||||
|
const handleFiltersButton = (
|
||||||
|
filtersCollapsed: boolean,
|
||||||
|
localFilters: Partial<IFilterQuery>,
|
||||||
|
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>,
|
||||||
|
setFiltersCollapsed: Dispatch<SetStateAction<boolean>>
|
||||||
|
) => {
|
||||||
|
if (!filtersCollapsed) {
|
||||||
|
setSearchQuery((prev) => {
|
||||||
|
return { ...prev, ...localFilters };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setFiltersCollapsed((prev) => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectChange = (
|
||||||
|
element: HTMLSelectElement,
|
||||||
|
setLocalFilters: Dispatch<SetStateAction<Partial<IFilterQuery>>>
|
||||||
|
) => {
|
||||||
|
setLocalFilters((prev) => {
|
||||||
|
return { ...prev, [element.name]: element.value };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchButton = (
|
||||||
|
searchCollapsed: boolean,
|
||||||
|
setSearchCollapsed: Dispatch<SetStateAction<boolean>>,
|
||||||
|
setInputFocus: () => void,
|
||||||
|
searchInputRef: RefObject<HTMLInputElement>,
|
||||||
|
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>
|
||||||
|
) => {
|
||||||
|
if (searchCollapsed) {
|
||||||
|
setSearchCollapsed(false);
|
||||||
|
setInputFocus();
|
||||||
|
} else if (searchInputRef && searchInputRef.current) {
|
||||||
|
const value = searchInputRef.current.value;
|
||||||
|
|
||||||
|
setSearchQuery((prev) => {
|
||||||
|
return { ...prev, search: value };
|
||||||
|
});
|
||||||
|
setSearchCollapsed(true);
|
||||||
|
|
||||||
|
searchInputRef.current.value = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { handleFiltersButton, handleSelectChange, handleSearchButton };
|
@ -1,5 +1,4 @@
|
|||||||
import React, {
|
import React, {
|
||||||
ChangeEvent,
|
|
||||||
Dispatch,
|
Dispatch,
|
||||||
SetStateAction,
|
SetStateAction,
|
||||||
useEffect,
|
useEffect,
|
||||||
@ -14,25 +13,31 @@ import SearchIcon from './search.svg';
|
|||||||
import { IFilterQuery } from '../types';
|
import { IFilterQuery } from '../types';
|
||||||
import { useFocus } from '../utils';
|
import { useFocus } from '../utils';
|
||||||
import Logotype from '../Logotype';
|
import Logotype from '../Logotype';
|
||||||
|
import {
|
||||||
|
filtersVariants,
|
||||||
|
navVariants,
|
||||||
|
searchVariants,
|
||||||
|
transition
|
||||||
|
} from './animations';
|
||||||
|
import {
|
||||||
|
handleFiltersButton,
|
||||||
|
handleSearchButton,
|
||||||
|
handleSelectChange
|
||||||
|
} from './handlers';
|
||||||
|
|
||||||
const Navbar = ({
|
type props = {
|
||||||
setSearchQuery,
|
|
||||||
query
|
|
||||||
}: {
|
|
||||||
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
setSearchQuery: Dispatch<SetStateAction<IFilterQuery>>;
|
||||||
query: IFilterQuery;
|
query: IFilterQuery;
|
||||||
}) => {
|
};
|
||||||
/*
|
|
||||||
* Hooks
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
const Navbar: React.FC<props> = ({ setSearchQuery, query }) => {
|
||||||
const [searchCollapsed, setSearchCollapsed] = useState(true);
|
const [searchCollapsed, setSearchCollapsed] = useState(true);
|
||||||
const [filtersCollapsed, setFiltersCollapsed] = useState(true);
|
const [filtersCollapsed, setFiltersCollapsed] = useState(true);
|
||||||
const [localFilters, setLocalFilters] = useState<Partial<IFilterQuery>>();
|
const [localFilters, setLocalFilters] = useState<Partial<IFilterQuery>>({});
|
||||||
|
|
||||||
const searchInput = useRef<HTMLInputElement>(null);
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const setInputFocus = useFocus(searchInput);
|
const setInputFocus = useFocus(searchInputRef);
|
||||||
|
|
||||||
const formRef = useRef<HTMLFormElement>(null);
|
const formRef = useRef<HTMLFormElement>(null);
|
||||||
|
|
||||||
@ -48,89 +53,6 @@ const Navbar = ({
|
|||||||
}
|
}
|
||||||
}, [query]);
|
}, [query]);
|
||||||
|
|
||||||
/*
|
|
||||||
* Animations
|
|
||||||
*/
|
|
||||||
|
|
||||||
const searchVariants = {
|
|
||||||
open: {
|
|
||||||
width: 'calc(100vw - 4vh)',
|
|
||||||
display: 'block'
|
|
||||||
},
|
|
||||||
closed: {
|
|
||||||
width: '6vh',
|
|
||||||
transitionEnd: {
|
|
||||||
display: 'none'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const navVariants = {
|
|
||||||
open: {
|
|
||||||
height: '100vh',
|
|
||||||
borderTopLeftRadius: 0,
|
|
||||||
borderTopRightRadius: 0
|
|
||||||
},
|
|
||||||
closed: {
|
|
||||||
height: '10vh',
|
|
||||||
borderTopLeftRadius: '20px',
|
|
||||||
borderTopRightRadius: '20px'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const filtersVariants = {
|
|
||||||
open: {
|
|
||||||
height: '100vh',
|
|
||||||
padding: '2vh'
|
|
||||||
},
|
|
||||||
closed: {
|
|
||||||
height: 0,
|
|
||||||
padding: 0
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const transition = {
|
|
||||||
ease: 'easeIn',
|
|
||||||
duration: 0.5
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Input handlers
|
|
||||||
*/
|
|
||||||
|
|
||||||
const handleFiltersButton = () => {
|
|
||||||
if (!filtersCollapsed) {
|
|
||||||
setSearchQuery((prev) => {
|
|
||||||
return { ...prev, ...localFilters };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setFiltersCollapsed((prev) => !prev);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSelectChange = ({
|
|
||||||
target: element
|
|
||||||
}: ChangeEvent<HTMLSelectElement>) => {
|
|
||||||
setLocalFilters((prev) => {
|
|
||||||
return { ...prev, [element.name]: element.value };
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSearchButton = () => {
|
|
||||||
if (searchCollapsed) {
|
|
||||||
setSearchCollapsed(false);
|
|
||||||
setInputFocus();
|
|
||||||
} else if (searchInput && searchInput.current) {
|
|
||||||
const value = searchInput.current.value;
|
|
||||||
|
|
||||||
setSearchQuery((prev) => {
|
|
||||||
return { ...prev, search: value };
|
|
||||||
});
|
|
||||||
setSearchCollapsed(true);
|
|
||||||
|
|
||||||
searchInput.current.value = '';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.header
|
<motion.header
|
||||||
id="navbar"
|
id="navbar"
|
||||||
@ -146,7 +68,14 @@ const Navbar = ({
|
|||||||
<button
|
<button
|
||||||
className="navButton"
|
className="navButton"
|
||||||
id="filter"
|
id="filter"
|
||||||
onClick={handleFiltersButton}
|
onClick={() =>
|
||||||
|
handleFiltersButton(
|
||||||
|
filtersCollapsed,
|
||||||
|
localFilters,
|
||||||
|
setSearchQuery,
|
||||||
|
setFiltersCollapsed
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<img src={FilterIcon} alt="Фильтр" />
|
<img src={FilterIcon} alt="Фильтр" />
|
||||||
</button>
|
</button>
|
||||||
@ -154,7 +83,15 @@ const Navbar = ({
|
|||||||
<button
|
<button
|
||||||
className="navButton"
|
className="navButton"
|
||||||
id="search"
|
id="search"
|
||||||
onClick={handleSearchButton}
|
onClick={() =>
|
||||||
|
handleSearchButton(
|
||||||
|
searchCollapsed,
|
||||||
|
setSearchCollapsed,
|
||||||
|
setInputFocus,
|
||||||
|
searchInputRef,
|
||||||
|
setSearchQuery
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<img src={SearchIcon} alt="Поиск" />
|
<img src={SearchIcon} alt="Поиск" />
|
||||||
</button>
|
</button>
|
||||||
@ -163,10 +100,16 @@ const Navbar = ({
|
|||||||
variants={searchVariants}
|
variants={searchVariants}
|
||||||
transition={transition}
|
transition={transition}
|
||||||
aria-label="Поиск"
|
aria-label="Поиск"
|
||||||
ref={searchInput}
|
ref={searchInputRef}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
handleSearchButton();
|
handleSearchButton(
|
||||||
|
searchCollapsed,
|
||||||
|
setSearchCollapsed,
|
||||||
|
setInputFocus,
|
||||||
|
searchInputRef,
|
||||||
|
setSearchQuery
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
type="search"
|
type="search"
|
||||||
@ -188,7 +131,9 @@ const Navbar = ({
|
|||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
name="teacher"
|
name="teacher"
|
||||||
onChange={handleSelectChange}
|
onChange={(e) =>
|
||||||
|
handleSelectChange(e.target, setLocalFilters)
|
||||||
|
}
|
||||||
id="teacherFilter"
|
id="teacherFilter"
|
||||||
>
|
>
|
||||||
<option value="">-</option>
|
<option value="">-</option>
|
||||||
@ -213,7 +158,9 @@ const Navbar = ({
|
|||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
name="type_num"
|
name="type_num"
|
||||||
onChange={handleSelectChange}
|
onChange={(e) =>
|
||||||
|
handleSelectChange(e.target, setLocalFilters)
|
||||||
|
}
|
||||||
id="typeFilter"
|
id="typeFilter"
|
||||||
>
|
>
|
||||||
<option value="">-</option>
|
<option value="">-</option>
|
||||||
@ -228,7 +175,9 @@ const Navbar = ({
|
|||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
name="predmet_type"
|
name="predmet_type"
|
||||||
onChange={handleSelectChange}
|
onChange={(e) =>
|
||||||
|
handleSelectChange(e.target, setLocalFilters)
|
||||||
|
}
|
||||||
id="predmetFilter"
|
id="predmetFilter"
|
||||||
>
|
>
|
||||||
<option value="">-</option>
|
<option value="">-</option>
|
||||||
@ -243,7 +192,9 @@ const Navbar = ({
|
|||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
name="class_num"
|
name="class_num"
|
||||||
onChange={handleSelectChange}
|
onChange={(e) =>
|
||||||
|
handleSelectChange(e.target, setLocalFilters)
|
||||||
|
}
|
||||||
id="classFilter"
|
id="classFilter"
|
||||||
>
|
>
|
||||||
<option value="">-</option>
|
<option value="">-</option>
|
||||||
|
@ -4,11 +4,11 @@ import './main.css';
|
|||||||
import icon from './icon.svg';
|
import icon from './icon.svg';
|
||||||
import { ILoadingState } from '../types';
|
import { ILoadingState } from '../types';
|
||||||
|
|
||||||
const NothingFound = ({
|
type props = {
|
||||||
setLoading
|
|
||||||
}: {
|
|
||||||
setLoading?: Dispatch<SetStateAction<ILoadingState>>;
|
setLoading?: Dispatch<SetStateAction<ILoadingState>>;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
const NothingFound: React.FC<props> = ({ setLoading }) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!setLoading) return;
|
if (!setLoading) return;
|
||||||
|
|
||||||
|
@ -7,13 +7,12 @@ import Card from '../Card';
|
|||||||
import './main.css';
|
import './main.css';
|
||||||
import NothingFound from '../NothingFound';
|
import NothingFound from '../NothingFound';
|
||||||
|
|
||||||
const SubjectList = ({
|
type props = {
|
||||||
setLoading,
|
|
||||||
searchQuery
|
|
||||||
}: {
|
|
||||||
setLoading: Dispatch<SetStateAction<ILoadingState>>;
|
setLoading: Dispatch<SetStateAction<ILoadingState>>;
|
||||||
searchQuery: IFilterQuery;
|
searchQuery: IFilterQuery;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
const SubjectList: React.FC<props> = ({ setLoading, searchQuery }) => {
|
||||||
const [data, setData] = useState<IData[]>([]);
|
const [data, setData] = useState<IData[]>([]);
|
||||||
|
|
||||||
const { push: historyPush } = useHistory();
|
const { push: historyPush } = useHistory();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user