Skip to content

Commit

Permalink
fix:added a loader for the header and navigation, handled the error
Browse files Browse the repository at this point in the history
  • Loading branch information
Runar committed Sep 2, 2022
1 parent 5d76b79 commit f3b5e5b
Show file tree
Hide file tree
Showing 20 changed files with 286 additions and 164 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@types/react-router-dom": "5.3.3",
"classnames": "2.3.1",
"react": "^18.2.0",
"react-content-loader": "^6.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "7.34.0",
"react-loader-spinner": "^5.1.7-beta.1",
Expand Down
17 changes: 17 additions & 0 deletions src/Spinner/preloader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

import ContentLoader from 'react-content-loader'

export const MyLoader = () => (
<ContentLoader
width={725}
height={45}
viewBox="0 0 725 45"
backgroundColor="#d9d9d9"
foregroundColor="#ecebeb">
<rect x="155" y="20" rx="3" ry="3" width="85" height="6" />
<rect x="320" y="20" rx="3" ry="3" width="85" height="6" />
<rect x="480" y="20" rx="3" ry="3" width="85" height="6" />
<rect x="640" y="20" rx="3" ry="3" width="85" height="6" />
<rect x="0" y="20" rx="3" ry="3" width="85" height="6" />
</ContentLoader>
);
2 changes: 1 addition & 1 deletion src/components/Cards/TiledCards/TiledCards.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
justify-content: center;
align-items: center;
overflow: hidden;
border-radius: 10px;
border-radius: 12px;
background: #e4e2e2;

& > img {
Expand Down
20 changes: 8 additions & 12 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import { FC, useState, useEffect } from "react"

import { FC } from "react"
import { DropdownList } from "./DropdownList/DropdownList";
import { IList } from "./DropdownList/DropdownList";
import classes from "./Dropdown.module.scss"

export const Dropdown: FC = () => {
import { IList } from "./DropdownList/DropdownList";

const [menu, setMenu] = useState<IList[]>([])
import classes from "./Dropdown.module.scss"

useEffect(() => {
fetch("/api/menu")
.then(response => response.json())
.then(data => setMenu(data))
}, [])
interface IPropsDropdown {
data: IList[]
}
export const Dropdown: FC<IPropsDropdown> = ({ data }) => {

return (
<div className={classes.flex}>
{menu.map((menu) => {
{data.map((menu) => {
return (
<DropdownList
key={menu.title}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Header/Header.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,6 @@
line-height: 17px;
border-bottom: 3px solid #f8f8f8;
}
.error {
color: red;
}
42 changes: 37 additions & 5 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,51 @@
import { FC } from 'react'
import { FC, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'

import { Navigation } from '../Navigation/Navigation'
import { HeaderMenu } from './HeaderMenu/HeaderMenu'
import { IconSvg } from '../IconSvg/IconSvg'

import classes from './Header.module.scss'

import { MyLoader } from '../../Spinner/preloader'
type Data = {
id: number
item: string,
path: string,
isIcon?: boolean,
}[]
export const Header: FC = () => {
const [data, setData] = useState<Data>([])
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useEffect(() => {
const requestHandler = async () => {
try {
const request = await fetch('/api/navigation');
const response = await request.json();
setLoading(false);
setData(response);
} catch (error) {
console.log(error)
setError(true);
setLoading(false);
}
};
requestHandler();
}, []);

return (
<header className={classes.header}>
<div className={classes.container}>
<Navigation
className={[classes.navList, classes.navListItem]}
/>
{loading && <MyLoader />}

{error ? <span className={classes.error}>Ошибка сервера, попробуйте обновить страницу</span>
:
<Navigation
data={data}
className={[classes.navList, classes.navListItem]}
/>
}

<div className={classes.buttons}>
<Link to={"/bookmarks"} className={classes.bookmark} >
Закладки
Expand Down
3 changes: 3 additions & 0 deletions src/components/Header/HeaderMenu/HeaderMenu.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@
background: linear-gradient(90deg, #9d94ff 0%, #6b50e9 94.5%);
border-radius: 19px;
}
.error {
color: red;
}
32 changes: 29 additions & 3 deletions src/components/Header/HeaderMenu/HeaderMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
import { FC } from 'react'
import { FC, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { Logo } from '../../Logo/Logo'
import { Dropdown } from '../../Dropdown/Dropdown'

import classes from './HeaderMenu.module.scss'

import { IList } from '../../Dropdown/DropdownList/DropdownList'
import { MyLoader } from '../../../Spinner/preloader'

export const HeaderMenu: FC = () => {

const [data, setData] = useState<IList[]>([])
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useEffect(() => {
const requestHandler = async () => {
try {
const request = await fetch('/api/menu');
const response = await request.json();
setLoading(false);
setData(response);
} catch (error) {
console.log(error)
setError(true);
setLoading(false);
}
};
requestHandler();
}, []);

return (
<div className={classes.wrapper}>
<div className={classes.container}>
<Logo />
<Dropdown />
{loading && <MyLoader />}
{error ?
<span className={classes.error}>Ошибка сервера, попробуйте обновить страницу</span>
:
<Dropdown data={data} />
}
<Link
to={"/404"}
className={classes.link}
Expand Down
43 changes: 23 additions & 20 deletions src/components/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useEffect, useState } from "react";
import { FC } from "react";

import { NavLink } from "react-router-dom";
import { IconSvg } from "../IconSvg/IconSvg"
Expand All @@ -12,34 +12,37 @@ type Data = {
isIcon?: boolean,
}[]

interface IPropsNav {
interface IPropsNavigation {
className: string[]
noHomePage?: boolean
data?: Data
}

export const Navigation: FC<IPropsNav> = ({ noHomePage, className: [navList, navListItem] }) => {
const [data, setData] = useState<Data>([])
const slice = noHomePage ? data.slice(1) : data
useEffect(() => {
fetch("/api/navigation")
.then(response => response.json())
.then(data => setData(data))
}, [])
export const Navigation: FC<IPropsNavigation> = ({ noHomePage, data, className: [navList, navListItem] }) => {

const slice = noHomePage ? data?.slice(1) : data

const setActive = ({ isActive }: { isActive: boolean }) => (isActive ? classes.active : "");
return (
<nav>
<ul className={navList}>
{slice.map(({ id, item, path, isIcon }) =>
<li key={id} className={navListItem} >
<NavLink
to={path}
className={setActive}
>
{isIcon && <IconSvg id={"#mark"} className={classes.icon} />}
{item}
</NavLink>
</li>)}
{
slice?.map(({ id, item, path, isIcon }) =>
<li key={id} className={navListItem} >
<NavLink
to={path}
className={setActive}
>
{isIcon && <IconSvg id={"#mark"} className={classes.icon} />}
{item}
</NavLink>
</li>
)
}




</ul>
</nav>
)
Expand Down
Loading

1 comment on commit f3b5e5b

@vercel
Copy link

@vercel vercel bot commented on f3b5e5b Sep 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.