initial commit + added Navbar component
This commit is contained in:
parent
bed4b399e1
commit
9e7dc4554e
20
.prettierrc
Normal file
20
.prettierrc
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
65
package.json
65
package.json
@ -1,34 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "school_documents_front",
|
"name": "school_documents_front",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.3.2",
|
"@testing-library/react": "^9.3.2",
|
||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^7.1.2",
|
||||||
"react": "^16.13.1",
|
"framer-motion": "2.3.0",
|
||||||
"react-dom": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-scripts": "3.4.3"
|
"react-dom": "^16.13.1",
|
||||||
},
|
"react-scripts": "3.4.3"
|
||||||
"scripts": {
|
},
|
||||||
"start": "react-scripts start",
|
"scripts": {
|
||||||
"build": "react-scripts build",
|
"start": "react-scripts start",
|
||||||
"test": "react-scripts test",
|
"build": "react-scripts build",
|
||||||
"eject": "react-scripts eject"
|
"test": "react-scripts test",
|
||||||
},
|
"eject": "react-scripts eject"
|
||||||
"eslintConfig": {
|
},
|
||||||
"extends": "react-app"
|
"eslintConfig": {
|
||||||
},
|
"extends": "react-app"
|
||||||
"browserslist": {
|
},
|
||||||
"production": [
|
"browserslist": {
|
||||||
">0.2%",
|
"production": [
|
||||||
"not dead",
|
">0.2%",
|
||||||
"not op_mini all"
|
"not dead",
|
||||||
],
|
"not op_mini all"
|
||||||
"development": [
|
],
|
||||||
"last 1 chrome version",
|
"development": [
|
||||||
"last 1 firefox version",
|
"last 1 chrome version",
|
||||||
"last 1 safari version"
|
"last 1 firefox version",
|
||||||
]
|
"last 1 safari version"
|
||||||
}
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
42
src/App.css
42
src/App.css
@ -1,38 +1,4 @@
|
|||||||
.App {
|
body {
|
||||||
text-align: center;
|
min-height: 100vh;
|
||||||
}
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
.App-logo {
|
|
||||||
height: 40vmin;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
.App-logo {
|
|
||||||
animation: App-logo-spin infinite 20s linear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: #282c34;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: calc(10px + 2vmin);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-link {
|
|
||||||
color: #61dafb;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes App-logo-spin {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
26
src/App.js
26
src/App.js
@ -1,26 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import logo from './logo.svg';
|
|
||||||
import './App.css';
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
<header className="App-header">
|
|
||||||
<img src={logo} className="App-logo" alt="logo" />
|
|
||||||
<p>
|
|
||||||
Edit <code>src/App.js</code> and save to reload.
|
|
||||||
</p>
|
|
||||||
<a
|
|
||||||
className="App-link"
|
|
||||||
href="https://reactjs.org"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Learn React
|
|
||||||
</a>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
13
src/App.jsx
Normal file
13
src/App.jsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import React from "react";
|
||||||
|
import "./App.css";
|
||||||
|
import Navbar from "./Navbar";
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<div className="App">
|
||||||
|
<Navbar />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
@ -1,9 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { render } from '@testing-library/react';
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
|
||||||
const { getByText } = render(<App />);
|
|
||||||
const linkElement = getByText(/learn react/i);
|
|
||||||
expect(linkElement).toBeInTheDocument();
|
|
||||||
});
|
|
44
src/Navbar/filter.svg
Normal file
44
src/Navbar/filter.svg
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 477.875 477.875" style="enable-background:new 0 0 477.875 477.875;" xml:space="preserve">
|
||||||
|
<g fill="#363645">
|
||||||
|
<g>
|
||||||
|
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c0.001,4.836,2.054,9.445,5.649,12.681l165.018,148.514V460.8
|
||||||
|
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
||||||
|
V263.595l165.018-148.48c3.604-3.243,5.658-7.866,5.649-12.715V17.067C477.871,7.641,470.23,0,460.804,0z M443.737,94.805
|
||||||
|
L278.72,243.285c-3.604,3.243-5.657,7.866-5.649,12.715v143.053l-68.267,34.133V256c-0.001-4.836-2.054-9.445-5.649-12.68
|
||||||
|
L34.137,94.805V34.133h409.6V94.805z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
169
src/Navbar/index.jsx
Normal file
169
src/Navbar/index.jsx
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
|
||||||
|
import "./main.css";
|
||||||
|
|
||||||
|
import LogoImage from "./logo.png";
|
||||||
|
import FilterIcon from "./filter.svg";
|
||||||
|
import SearchIcon from "./search.svg";
|
||||||
|
|
||||||
|
const Navbar = (props) => {
|
||||||
|
const [searchCollapsed, setSearchCollapsed] = useState(true);
|
||||||
|
const [filtersCollapsed, setFiltersCollapsed] = useState(true);
|
||||||
|
|
||||||
|
const searchVariants = {
|
||||||
|
open: {
|
||||||
|
width: "calc(100vw - 5vh)",
|
||||||
|
display: "block",
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
width: "7vh",
|
||||||
|
transitionEnd: {
|
||||||
|
display: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const navVariants = {
|
||||||
|
open: {
|
||||||
|
height: "100vh",
|
||||||
|
borderTopLeftRadius: 0,
|
||||||
|
borderTopRightRadius: 0,
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
height: "12vh",
|
||||||
|
borderTopLeftRadius: "20px",
|
||||||
|
borderTopRightRadius: "20px",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const filtersVariants = {
|
||||||
|
open: {
|
||||||
|
height: "100vh",
|
||||||
|
padding: "2.5vh",
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
height: 0,
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const transition = {
|
||||||
|
ease: "easeIn",
|
||||||
|
duration: 0.5,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.header
|
||||||
|
id="navbar"
|
||||||
|
variants={navVariants}
|
||||||
|
transition={transition}
|
||||||
|
animate={filtersCollapsed ? "closed" : "open"}
|
||||||
|
>
|
||||||
|
<nav>
|
||||||
|
<a href="#">
|
||||||
|
<img id="logo" src={LogoImage} alt="Логотип ЮФМЛ" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div id="spacing"></div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="navButton"
|
||||||
|
id="filter"
|
||||||
|
onClick={() => setFiltersCollapsed((prev) => !prev)}
|
||||||
|
>
|
||||||
|
<img src={FilterIcon} alt="Фильтр" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="navButton"
|
||||||
|
id="search"
|
||||||
|
onClick={() => setSearchCollapsed((prev) => !prev)}
|
||||||
|
>
|
||||||
|
<img src={SearchIcon} alt="Поиск" />
|
||||||
|
</button>
|
||||||
|
<motion.input
|
||||||
|
type="search"
|
||||||
|
animate={searchCollapsed ? "closed" : "open"}
|
||||||
|
variants={searchVariants}
|
||||||
|
transition={transition}
|
||||||
|
aria-label="Поиск"
|
||||||
|
name="search"
|
||||||
|
id="searchInput"
|
||||||
|
/>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<motion.form
|
||||||
|
variants={filtersVariants}
|
||||||
|
transition={transition}
|
||||||
|
animate={filtersCollapsed ? "closed" : "open"}
|
||||||
|
id="filters"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="teacherFilter">
|
||||||
|
<h2>Преподаватель</h2>
|
||||||
|
</label>
|
||||||
|
<select name="teacher" id="teacherFilter">
|
||||||
|
<option defaultValue value="">
|
||||||
|
-
|
||||||
|
</option>
|
||||||
|
<option value="Попов Д.А">Попов Д.А</option>
|
||||||
|
<option value="Ильин А.Б">Ильин А.Б</option>
|
||||||
|
<option value="Пачин И.М">Пачин И.М</option>
|
||||||
|
<option value="Николаева Л.Н">Николаева Л.Н</option>
|
||||||
|
<option value="Ню В.В">Ню В.В</option>
|
||||||
|
<option value="Вишневская Е.А">Вишневская Е.А</option>
|
||||||
|
<option value="Некрасов М.В">Некрасов М.В</option>
|
||||||
|
<option value="Попова Н.А">Попова Н.А</option>
|
||||||
|
<option value="Пачин М.Ф">Пачин М.Ф</option>
|
||||||
|
<option value="Керамов Н.Д">Керамов Н.Д</option>
|
||||||
|
<option value="Новожилова В.И">Новожилова В.И</option>
|
||||||
|
<option value="Шпехт А.Ю">Шпехт А.Ю</option>
|
||||||
|
<option value="Конкина Н.В">Конкина Н.В</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="typeFilter">
|
||||||
|
<h2>Тип задания</h2>
|
||||||
|
</label>
|
||||||
|
<select name="type_num" id="typeFilter">
|
||||||
|
<option defaultValue value="">
|
||||||
|
-
|
||||||
|
</option>
|
||||||
|
<option value="Семестровки">Семестровки</option>
|
||||||
|
<option value="Семинары">Семинары</option>
|
||||||
|
<option value="Потоковые">Потоковые</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="predmetFilter">
|
||||||
|
<h2>Предмет</h2>
|
||||||
|
</label>
|
||||||
|
<select name="predmet_type" id="predmetFilter">
|
||||||
|
<option defaultValue value="">
|
||||||
|
-
|
||||||
|
</option>
|
||||||
|
<option value="Математика">Математика</option>
|
||||||
|
<option value="Физика">Физика</option>
|
||||||
|
<option value="Информатика">Информатика</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="classFilter">
|
||||||
|
<h2>Класс</h2>
|
||||||
|
</label>
|
||||||
|
<select name="class_num" id="classFilter">
|
||||||
|
<option defaultValue value="">
|
||||||
|
-
|
||||||
|
</option>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="11">11</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</motion.form>
|
||||||
|
</motion.header>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Navbar;
|
BIN
src/Navbar/logo.png
Normal file
BIN
src/Navbar/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
101
src/Navbar/main.css
Normal file
101
src/Navbar/main.css
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#navbar {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 12vh;
|
||||||
|
background-color: rgb(54, 54, 69);
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
padding: 2.5vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navbar nav {
|
||||||
|
background-color: rgb(54, 54, 69);
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5vh;
|
||||||
|
height: 7vh;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo {
|
||||||
|
height: 7vh;
|
||||||
|
width: 7vh;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 100%;
|
||||||
|
padding: 1vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spacing {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navButton {
|
||||||
|
background-color: rgb(255, 109, 109);
|
||||||
|
height: 7vh;
|
||||||
|
width: 7vh;
|
||||||
|
padding: 1.5vh;
|
||||||
|
border-radius: 100%;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search {
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navButton img {
|
||||||
|
height: 4vh;
|
||||||
|
width: 4vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchInput {
|
||||||
|
position: fixed;
|
||||||
|
width: 7vh;
|
||||||
|
bottom: 2.5vh;
|
||||||
|
right: 2.5vh;
|
||||||
|
height: 7vh;
|
||||||
|
border: none;
|
||||||
|
border-radius: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 2.5vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 5vh;
|
||||||
|
padding-top: -12vh;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters label h2 {
|
||||||
|
margin: 1.5vh 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters select {
|
||||||
|
background-color: rgb(255, 109, 109);
|
||||||
|
border: none;
|
||||||
|
appearance: none;
|
||||||
|
padding: 1.5vh;
|
||||||
|
height: 7vh;
|
||||||
|
border-radius: 100vh;
|
||||||
|
width: 75vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-bottom: 12vh;
|
||||||
|
}
|
43
src/Navbar/search.svg
Normal file
43
src/Navbar/search.svg
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 511.999 511.999" style="enable-background:new 0 0 511.999 511.999;" xml:space="preserve">
|
||||||
|
<g fill="#363645">
|
||||||
|
<g>
|
||||||
|
<path d="M508.874,478.708L360.142,329.976c28.21-34.827,45.191-79.103,45.191-127.309c0-111.75-90.917-202.667-202.667-202.667
|
||||||
|
S0,90.917,0,202.667s90.917,202.667,202.667,202.667c48.206,0,92.482-16.982,127.309-45.191l148.732,148.732
|
||||||
|
c4.167,4.165,10.919,4.165,15.086,0l15.081-15.082C513.04,489.627,513.04,482.873,508.874,478.708z M202.667,362.667
|
||||||
|
c-88.229,0-160-71.771-160-160s71.771-160,160-160s160,71.771,160,160S290.896,362.667,202.667,362.667z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
17
src/index.js
17
src/index.js
@ -1,17 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import './index.css';
|
|
||||||
import App from './App';
|
|
||||||
import * as serviceWorker from './serviceWorker';
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<React.StrictMode>
|
|
||||||
<App />
|
|
||||||
</React.StrictMode>,
|
|
||||||
document.getElementById('root')
|
|
||||||
);
|
|
||||||
|
|
||||||
// If you want your app to work offline and load faster, you can change
|
|
||||||
// unregister() to register() below. Note this comes with some pitfalls.
|
|
||||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
|
||||||
serviceWorker.unregister();
|
|
11
src/index.jsx
Normal file
11
src/index.jsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
import "./index.css";
|
||||||
|
import App from "./App";
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
document.getElementById("root")
|
||||||
|
);
|
@ -1,141 +0,0 @@
|
|||||||
// This optional code is used to register a service worker.
|
|
||||||
// register() is not called by default.
|
|
||||||
|
|
||||||
// This lets the app load faster on subsequent visits in production, and gives
|
|
||||||
// it offline capabilities. However, it also means that developers (and users)
|
|
||||||
// will only see deployed updates on subsequent visits to a page, after all the
|
|
||||||
// existing tabs open on the page have been closed, since previously cached
|
|
||||||
// resources are updated in the background.
|
|
||||||
|
|
||||||
// To learn more about the benefits of this model and instructions on how to
|
|
||||||
// opt-in, read https://bit.ly/CRA-PWA
|
|
||||||
|
|
||||||
const isLocalhost = Boolean(
|
|
||||||
window.location.hostname === 'localhost' ||
|
|
||||||
// [::1] is the IPv6 localhost address.
|
|
||||||
window.location.hostname === '[::1]' ||
|
|
||||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
|
||||||
window.location.hostname.match(
|
|
||||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
export function register(config) {
|
|
||||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
|
||||||
// The URL constructor is available in all browsers that support SW.
|
|
||||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
|
||||||
if (publicUrl.origin !== window.location.origin) {
|
|
||||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
|
||||||
// from what our page is served on. This might happen if a CDN is used to
|
|
||||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
|
||||||
|
|
||||||
if (isLocalhost) {
|
|
||||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
|
||||||
checkValidServiceWorker(swUrl, config);
|
|
||||||
|
|
||||||
// Add some additional logging to localhost, pointing developers to the
|
|
||||||
// service worker/PWA documentation.
|
|
||||||
navigator.serviceWorker.ready.then(() => {
|
|
||||||
console.log(
|
|
||||||
'This web app is being served cache-first by a service ' +
|
|
||||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Is not localhost. Just register service worker
|
|
||||||
registerValidSW(swUrl, config);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerValidSW(swUrl, config) {
|
|
||||||
navigator.serviceWorker
|
|
||||||
.register(swUrl)
|
|
||||||
.then(registration => {
|
|
||||||
registration.onupdatefound = () => {
|
|
||||||
const installingWorker = registration.installing;
|
|
||||||
if (installingWorker == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
installingWorker.onstatechange = () => {
|
|
||||||
if (installingWorker.state === 'installed') {
|
|
||||||
if (navigator.serviceWorker.controller) {
|
|
||||||
// At this point, the updated precached content has been fetched,
|
|
||||||
// but the previous service worker will still serve the older
|
|
||||||
// content until all client tabs are closed.
|
|
||||||
console.log(
|
|
||||||
'New content is available and will be used when all ' +
|
|
||||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
|
||||||
);
|
|
||||||
|
|
||||||
// Execute callback
|
|
||||||
if (config && config.onUpdate) {
|
|
||||||
config.onUpdate(registration);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// At this point, everything has been precached.
|
|
||||||
// It's the perfect time to display a
|
|
||||||
// "Content is cached for offline use." message.
|
|
||||||
console.log('Content is cached for offline use.');
|
|
||||||
|
|
||||||
// Execute callback
|
|
||||||
if (config && config.onSuccess) {
|
|
||||||
config.onSuccess(registration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error during service worker registration:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkValidServiceWorker(swUrl, config) {
|
|
||||||
// Check if the service worker can be found. If it can't reload the page.
|
|
||||||
fetch(swUrl, {
|
|
||||||
headers: { 'Service-Worker': 'script' },
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
// Ensure service worker exists, and that we really are getting a JS file.
|
|
||||||
const contentType = response.headers.get('content-type');
|
|
||||||
if (
|
|
||||||
response.status === 404 ||
|
|
||||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
|
||||||
) {
|
|
||||||
// No service worker found. Probably a different app. Reload the page.
|
|
||||||
navigator.serviceWorker.ready.then(registration => {
|
|
||||||
registration.unregister().then(() => {
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Service worker found. Proceed as normal.
|
|
||||||
registerValidSW(swUrl, config);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.log(
|
|
||||||
'No internet connection found. App is running in offline mode.'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function unregister() {
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
navigator.serviceWorker.ready
|
|
||||||
.then(registration => {
|
|
||||||
registration.unregister();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
|
||||||
// allows you to do things like:
|
|
||||||
// expect(element).toHaveTextContent(/react/i)
|
|
||||||
// learn more: https://github.com/testing-library/jest-dom
|
|
||||||
import '@testing-library/jest-dom/extend-expect';
|
|
75
yarn.lock
75
yarn.lock
@ -1095,6 +1095,18 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
|
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
|
||||||
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
|
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
|
||||||
|
|
||||||
|
"@emotion/is-prop-valid@^0.8.2":
|
||||||
|
version "0.8.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
|
||||||
|
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/memoize" "0.7.4"
|
||||||
|
|
||||||
|
"@emotion/memoize@0.7.4":
|
||||||
|
version "0.7.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
||||||
|
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
||||||
|
|
||||||
"@hapi/address@2.x.x":
|
"@hapi/address@2.x.x":
|
||||||
version "2.1.4"
|
version "2.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
|
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
|
||||||
@ -1309,6 +1321,22 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
||||||
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
|
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
|
||||||
|
|
||||||
|
"@popmotion/easing@^1.0.1", "@popmotion/easing@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@popmotion/easing/-/easing-1.0.2.tgz#17d925c45b4bf44189e5a38038d149df42d8c0b4"
|
||||||
|
integrity sha512-IkdW0TNmRnWTeWI7aGQIVDbKXPWHVEYdGgd5ZR4SH/Ty/61p63jCjrPxX1XrR7IGkl08bjhJROStD7j+RKgoIw==
|
||||||
|
|
||||||
|
"@popmotion/popcorn@^0.4.2":
|
||||||
|
version "0.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@popmotion/popcorn/-/popcorn-0.4.4.tgz#a5f906fccdff84526e3fcb892712d7d8a98d6adc"
|
||||||
|
integrity sha512-jYO/8319fKoNLMlY4ZJPiPu8Ea8occYwRZhxpaNn/kZsK4QG2E7XFlXZMJBsTWDw7I1i0uaqyC4zn1nwEezLzg==
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
framesync "^4.0.1"
|
||||||
|
hey-listen "^1.0.8"
|
||||||
|
style-value-types "^3.1.7"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
"@sheerun/mutationobserver-shim@^0.3.2":
|
"@sheerun/mutationobserver-shim@^0.3.2":
|
||||||
version "0.3.3"
|
version "0.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25"
|
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25"
|
||||||
@ -4685,6 +4713,28 @@ fragment-cache@^0.2.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
map-cache "^0.2.2"
|
map-cache "^0.2.2"
|
||||||
|
|
||||||
|
framer-motion@2.3.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-2.3.0.tgz#700c3d6a554c86bfa6a2d96e25f25829667cd0b4"
|
||||||
|
integrity sha512-zX6V5vz3joMzacqV7UpiHKUtqLMmU/YsVM6KpeRCi65KjUiymUX5O2jkpR3cCdlr1DkJ1yWUjBWY7xyiO834VA==
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.2"
|
||||||
|
"@popmotion/popcorn" "^0.4.2"
|
||||||
|
framesync "^4.0.4"
|
||||||
|
hey-listen "^1.0.8"
|
||||||
|
popmotion "9.0.0-beta-8"
|
||||||
|
style-value-types "^3.1.9"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
optionalDependencies:
|
||||||
|
"@emotion/is-prop-valid" "^0.8.2"
|
||||||
|
|
||||||
|
framesync@^4.0.1, framesync@^4.0.4:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/framesync/-/framesync-4.1.0.tgz#69a8db3ca432dc70d6a76ba882684a1497ef068a"
|
||||||
|
integrity sha512-MmgZ4wCoeVxNbx2xp5hN/zPDCbLSKiDt4BbbslK7j/pM2lg5S0vhTNv1v8BCVb99JPIo6hXBFdwzU7Q4qcAaoQ==
|
||||||
|
dependencies:
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
|
||||||
fresh@0.5.2:
|
fresh@0.5.2:
|
||||||
version "0.5.2"
|
version "0.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||||
@ -5015,6 +5065,11 @@ hex-color-regex@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
|
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
|
||||||
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
|
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
|
||||||
|
|
||||||
|
hey-listen@^1.0.5, hey-listen@^1.0.8:
|
||||||
|
version "1.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
|
||||||
|
integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
|
||||||
|
|
||||||
hmac-drbg@^1.0.0:
|
hmac-drbg@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||||
@ -7624,6 +7679,18 @@ pnp-webpack-plugin@1.6.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ts-pnp "^1.1.6"
|
ts-pnp "^1.1.6"
|
||||||
|
|
||||||
|
popmotion@9.0.0-beta-8:
|
||||||
|
version "9.0.0-beta-8"
|
||||||
|
resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-9.0.0-beta-8.tgz#f5a709f11737734e84f2a6b73f9bcf25ee30c388"
|
||||||
|
integrity sha512-6eQzqursPvnP7ePvdfPeY4wFHmS3OLzNP8rJRvmfFfEIfpFqrQgLsM50Gd9AOvGKJtYJOFknNG+dsnzCpgIdAA==
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
"@popmotion/popcorn" "^0.4.2"
|
||||||
|
framesync "^4.0.4"
|
||||||
|
hey-listen "^1.0.8"
|
||||||
|
style-value-types "^3.1.6"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
portfinder@^1.0.26:
|
portfinder@^1.0.26:
|
||||||
version "1.0.28"
|
version "1.0.28"
|
||||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
|
||||||
@ -9812,6 +9879,14 @@ style-loader@0.23.1:
|
|||||||
loader-utils "^1.1.0"
|
loader-utils "^1.1.0"
|
||||||
schema-utils "^1.0.0"
|
schema-utils "^1.0.0"
|
||||||
|
|
||||||
|
style-value-types@^3.1.6, style-value-types@^3.1.7, style-value-types@^3.1.9:
|
||||||
|
version "3.1.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.1.9.tgz#faf7da660d3f284ed695cff61ea197d85b9122cc"
|
||||||
|
integrity sha512-050uqgB7WdvtgacoQKm+4EgKzJExVq0sieKBQQtJiU3Muh6MYcCp4T3M8+dfl6VOF2LR0NNwXBP1QYEed8DfIw==
|
||||||
|
dependencies:
|
||||||
|
hey-listen "^1.0.8"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
stylehacks@^4.0.0:
|
stylehacks@^4.0.0:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
|
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user