Added some typescript, global loading state

This commit is contained in:
Dm1tr1y147 2020-09-18 16:21:35 +05:00
parent 4ed055dcb6
commit a83e667dae
10 changed files with 264 additions and 268 deletions

View File

@ -1,20 +1,7 @@
{
"arrowParens": "always",
"bracketSpacing": true,
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxBracketSameLine": false,
"jsxSingleQuote": false,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": true,
"singleQuote": false,
"tabWidth": 4,
"trailingComma": "es5",
"useTabs": false,
"vueIndentScriptAndStyle": false,
"parser": "babel"
"trailingComma": "none",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 4
}

View File

@ -1,10 +1,11 @@
import React from "react";
import React, { useState } from "react";
import { Switch, Route, useLocation } from "react-router-dom";
import "./App.css";
import Home from "./Home";
import Navbar from "./Navbar";
import SubjectList from "./SubjectList";
import {ILoadingState} from './types'
const genName = (path: string, search?: string): string => {
if (path === "/list" && search) {
@ -42,6 +43,8 @@ const genName = (path: string, search?: string): string => {
function App() {
const location = useLocation();
const [loading, setLoading] = useState<ILoadingState>({ fetching: true, error: "" });
return (
<div>
<header id="name">
@ -50,10 +53,10 @@ function App() {
<Navbar />
<Switch>
<Route exact path="/">
<Home />
<Home setLoading={setLoading} />
</Route>
<Route path="/list">
<SubjectList />
<SubjectList setLoading={setLoading} />
</Route>
<Route path="*">
<h1>404</h1>

111
src/Home/fakeData.json Normal file
View File

@ -0,0 +1,111 @@
[{
"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
}
]

View File

@ -1,187 +0,0 @@
import React from "react";
import { Link } from "react-router-dom";
import Card from "../Card";
import "./main.css";
const data = [
{
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,
},
];
const Home = () => {
const classes = [
...new Set(data.map((el) => parseInt(el.class_num)).sort()),
];
const subjects = [...new Set(data.map((el) => el.predmet_type).sort())];
return (
<main>
{classes.map((class_num, index) => (
<div key={index} className="classContainer">
<h1>{class_num} класс</h1>
{subjects.map((subject, jndex) =>
data.filter(
(el) =>
parseInt(el.class_num) === class_num &&
el.predmet_type === subject
).length ? (
<div key={jndex} className="subjectContainer">
<h2>{subject}</h2>
<div className="carousel">
<div className="carouselInner">
{data
.filter(
(el) =>
parseInt(el.class_num) ===
class_num &&
el.predmet_type === subject
)
.map((el, kndex) => (
<Card key={kndex} data={el} />
))}
</div>
<div className="showMore">
<Link
to={
"/list?subject=" +
subject +
"?clas=" +
class_num
}
>
Больше &rarr;
</Link>
</div>
</div>
</div>
) : (
""
)
)}
<div className="curve"></div>
</div>
))}
</main>
);
};
export default Home;

89
src/Home/index.tsx Normal file
View File

@ -0,0 +1,89 @@
import React, { Dispatch, useEffect, useState } from "react";
import { Link } from "react-router-dom";
import Card from "../Card";
import { IData, ILoadingState } from "../types";
import "./main.css";
const Home = ({ setLoading }: {setLoading: Dispatch<ILoadingState>}) => {
const [data, setData] = useState<IData[]>([]);
useEffect(() => {
setLoading({ fetching: true, error: "" });
console.log("Loading data");
const requestURL =
"https://cors-anywhere.herokuapp.com/upml-bank.dmitriy.icu/api/cards";
fetch(requestURL)
.then((res) => res.json())
.then((data) => {
console.log("Fetched data");
console.log(data);
setData(data);
setLoading({ fetching: false, error: "" });
})
.catch((err) => {
setLoading({ fetching: false, error: err });
console.error(err);
});
}, [setLoading]);
const classes: number[] = [
...Array.from(new Set(data.map((el) => parseInt(el.class_num)).sort())),
];
const subjects: string[] = [...Array.from(new Set(data.map((el) => el.predmet_type).sort()))];
return (
<main className="homeContainer">
{classes.map((class_num, index) => (
<div key={index} className="classContainer">
<h1>{class_num} класс</h1>
{subjects.map((subject, jndex) =>
data.filter(
(el) =>
parseInt(el.class_num) === class_num &&
el.predmet_type === subject
).length ? (
<div key={jndex} className="subjectContainer">
<h2>{subject}</h2>
<div className="carousel">
<div className="carouselInner">
{data
.filter(
(el) =>
parseInt(el.class_num) ===
class_num &&
el.predmet_type === subject
)
.map((el, kndex) => (
<Card key={kndex} data={el} />
))}
</div>
<div className="showMore">
<Link
to={
"/list?subject=" +
subject +
"?clas=" +
class_num
}
>
Больше &rarr;
</Link>
</div>
</div>
</div>
) : (
""
)
)}
<div className="curve"></div>
</div>
))}
</main>
);
};
export default Home;

View File

@ -1,3 +1,7 @@
.homeContainer {
min-height: calc(79.5vh + 20px);
}
.classContainer {
padding: 2vh;
padding-top: calc(20px + 2vh);

View File

@ -8,7 +8,7 @@ import LogoImage from "./logo.png";
import FilterIcon from "./filter.svg";
import SearchIcon from "./search.svg";
const Navbar = (props) => {
const Navbar = () => {
const [searchCollapsed, setSearchCollapsed] = useState(true);
const [filtersCollapsed, setFiltersCollapsed] = useState(true);
@ -105,7 +105,7 @@ const Navbar = (props) => {
<h2>Преподаватель</h2>
</label>
<select name="teacher" id="teacherFilter">
<option defaultValue value="">
<option value="">
-
</option>
<option value="Попов Д.А">Попов Д.А</option>
@ -128,7 +128,7 @@ const Navbar = (props) => {
<h2>Тип задания</h2>
</label>
<select name="type_num" id="typeFilter">
<option defaultValue value="">
<option value="">
-
</option>
<option value="Семестровки">Семестровки</option>
@ -141,7 +141,7 @@ const Navbar = (props) => {
<h2>Предмет</h2>
</label>
<select name="predmet_type" id="predmetFilter">
<option defaultValue value="">
<option value="">
-
</option>
<option value="Математика">Математика</option>
@ -154,7 +154,7 @@ const Navbar = (props) => {
<h2>Класс</h2>
</label>
<select name="class_num" id="classFilter">
<option defaultValue value="">
<option value="">
-
</option>
<option value="10">10</option>

View File

@ -96,6 +96,7 @@
height: 6vh;
border-radius: 20px;
width: 75vw;
font-size: 2.5vh;
}
body {

View File

@ -1,61 +1,31 @@
import React from "react";
import { useLocation } from "react-router-dom";
import Card from "../Card";
import "./main.css";
import React, { useEffect, useState, Dispatch } from 'react';
import { useLocation } from 'react-router-dom';
const data = [
{
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,
},
];
import { IData, ILoadingState } from '../types';
import Card from '../Card';
import './main.css';
const SubjectList = () => {
const location = useLocation();
const SubjectList = ({
setLoading
}: {
setLoading: Dispatch<ILoadingState>;
}) => {
const [data, setData] = useState<IData[]>([]);
useEffect(() => {
setLoading({ fetching: true, error: '' });
const fetchURL = 'https://upml-bank.dmitriy.icu/api/cards?' + new URLSearchParams({class_num: '11'}).toString()
fetch(fetchURL)
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading({ fetching: false, error: '' });
})
.catch((err) => {
console.error(err);
setLoading({ fetching: false, error: err });
});
}, [setLoading]);
return (
<main className="subjectList">

18
src/types.ts Normal file
View File

@ -0,0 +1,18 @@
interface ILoadingState {
fetching: boolean;
error: string;
}
interface IData {
title: string;
type_num: string;
class_num: string;
post_date: string;
predmet_type: string;
teacher: string;
image: string;
slug: string;
card_id: number;
}
export type { ILoadingState, IData };