master #7
							
								
								
									
										19
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								package.json
									
									
									
									
									
								
							@ -7,22 +7,32 @@
 | 
			
		||||
    "@babel/preset-typescript": "^7.10.1",
 | 
			
		||||
    "@date-io/moment": "^1.3.13",
 | 
			
		||||
    "@material-ui/core": "^4.10.1",
 | 
			
		||||
    "@material-ui/icons": "^4.9.1",
 | 
			
		||||
    "@material-ui/lab": "^4.0.0-alpha.55",
 | 
			
		||||
    "@material-ui/pickers": "^3.2.10",
 | 
			
		||||
    "@types/classnames": "^2.2.10",
 | 
			
		||||
    "@types/node": "^12.0.0",
 | 
			
		||||
    "@types/react": "^16.9.0",
 | 
			
		||||
    "@types/react-dom": "^16.9.0",
 | 
			
		||||
    "@types/react-redux": "^7.1.9",
 | 
			
		||||
    "@types/react-router-dom": "^5.1.5",
 | 
			
		||||
    "@types/redux": "^3.6.0",
 | 
			
		||||
    "@types/redux-persist": "^4.3.1",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^2.10.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^2.10.0",
 | 
			
		||||
    "babel-core": "^6.26.3",
 | 
			
		||||
    "babel-loader": "^8.1.0",
 | 
			
		||||
    "babel-plugin-import": "^1.13.0",
 | 
			
		||||
    "babel-preset-react-app": "^9.1.2",
 | 
			
		||||
    "classnames": "^2.2.6",
 | 
			
		||||
    "clean-webpack-plugin": "^3.0.0",
 | 
			
		||||
    "css-loader": "3.4.2",
 | 
			
		||||
    "date-holidays": "^1.5.3",
 | 
			
		||||
    "file-loader": "4.3.0",
 | 
			
		||||
    "html-webpack-plugin": "4.0.0-beta.11",
 | 
			
		||||
    "i18next": "^19.6.0",
 | 
			
		||||
    "i18next-browser-languagedetector": "^5.0.0",
 | 
			
		||||
    "material-ui-dropzone": "^3.3.0",
 | 
			
		||||
    "moment": "^2.26.0",
 | 
			
		||||
    "node-sass": "^4.14.1",
 | 
			
		||||
    "optimize-css-assets-webpack-plugin": "5.0.3",
 | 
			
		||||
@ -35,6 +45,12 @@
 | 
			
		||||
    "react-app-polyfill": "^1.0.6",
 | 
			
		||||
    "react-dev-utils": "^10.2.1",
 | 
			
		||||
    "react-dom": "^16.13.1",
 | 
			
		||||
    "react-i18next": "^11.7.0",
 | 
			
		||||
    "react-redux": "^7.2.0",
 | 
			
		||||
    "react-router-dom": "^5.2.0",
 | 
			
		||||
    "redux": "^4.0.5",
 | 
			
		||||
    "redux-devtools-extension": "^2.13.8",
 | 
			
		||||
    "redux-persist": "^6.0.0",
 | 
			
		||||
    "sass-loader": "8.0.2",
 | 
			
		||||
    "style-loader": "0.23.1",
 | 
			
		||||
    "ts-loader": "^7.0.5",
 | 
			
		||||
@ -43,7 +59,8 @@
 | 
			
		||||
    "webpack": "4.42.0",
 | 
			
		||||
    "webpack-cli": "^3.3.11",
 | 
			
		||||
    "webpack-dev-server": "3.10.3",
 | 
			
		||||
    "workbox-webpack-plugin": "4.3.1"
 | 
			
		||||
    "workbox-webpack-plugin": "4.3.1",
 | 
			
		||||
    "yaml-loader": "^0.6.0"
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "serve": "webpack-dev-server --mode development",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										98
									
								
								public/img/eti-logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								public/img/eti-logo.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,98 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:xlink="http://www.w3.org/1999/xlink"
 | 
			
		||||
   id="svg80"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   viewBox="0 0 79.63958 79.63958"
 | 
			
		||||
   height="79.63958mm"
 | 
			
		||||
   width="79.63958mm">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs74" />
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata77">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     style="display:none"
 | 
			
		||||
     id="layer1">
 | 
			
		||||
    <image
 | 
			
		||||
       id="image962"
 | 
			
		||||
       xlink:href="data:image/png;base64,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
 | 
			
		||||
0QKiiBYQ5R9/xZAqF7xrtwAAAABJRU5ErkJggg==
 | 
			
		||||
"
 | 
			
		||||
       style="image-rendering:optimizeSpeed"
 | 
			
		||||
       preserveAspectRatio="none"
 | 
			
		||||
       height="79.63958"
 | 
			
		||||
       width="79.63958"
 | 
			
		||||
       x="0"
 | 
			
		||||
       y="0" />
 | 
			
		||||
  </g>
 | 
			
		||||
  <g
 | 
			
		||||
     style="display:inline"
 | 
			
		||||
     id="layer3">
 | 
			
		||||
    <path
 | 
			
		||||
       transform="scale(0.26458333)"
 | 
			
		||||
       d="M 0,0 V 301 H 301 V 0 Z M 11,11 H 82 V 61 H 61 v 63 h 51 v 51 H 61 v 64 h 75 v 50 H 11 Z m 82,0 H 290 V 61 H 204 V 289 H 149 V 61 H 93 Z m 171,7 A 19.999999,18.5 0 0 0 244,36.5 19.999999,18.5 0 0 0 264,55 19.999999,18.5 0 0 0 284,36.5 19.999999,18.5 0 0 0 264,18 Z m -25,55 h 51 v 216 h -51 z"
 | 
			
		||||
       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.01347"
 | 
			
		||||
       id="rect1025" />
 | 
			
		||||
  </g>
 | 
			
		||||
  <g
 | 
			
		||||
     style="opacity:1"
 | 
			
		||||
     id="layer2" />
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										1
									
								
								public/img/pg-logotyp.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/img/pg-logotyp.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB  | 
@ -4,9 +4,9 @@
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
			
		||||
    <meta name="theme-color" content="#000000" />
 | 
			
		||||
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap&subset=latin,latin-ext" />
 | 
			
		||||
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
 | 
			
		||||
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap&subset=latin,latin-ext" />
 | 
			
		||||
    <title>Zgłoszenie praktyki studenckiej</title>
 | 
			
		||||
    <base href="/">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <noscript>You need to enable JavaScript to run this app.</noscript>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										121
									
								
								src/app.tsx
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								src/app.tsx
									
									
									
									
									
								
							@ -1,40 +1,103 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { Container, Typography } from "@material-ui/core";
 | 
			
		||||
import { MuiThemeProvider as ThemeProvider, StylesProvider } from "@material-ui/core/styles";
 | 
			
		||||
import { studentTheme } from "./ui/theme";
 | 
			
		||||
import { InternshipForm } from "@/forms/Internship";
 | 
			
		||||
import { MuiPickersUtilsProvider } from "@material-ui/pickers";
 | 
			
		||||
import MomentUtils from "@date-io/moment";
 | 
			
		||||
 | 
			
		||||
import "moment/locale/pl"
 | 
			
		||||
moment.locale("pl")
 | 
			
		||||
 | 
			
		||||
import React, { Dispatch, HTMLProps, useEffect } from 'react';
 | 
			
		||||
import { Link, Route, Switch } from "react-router-dom"
 | 
			
		||||
import moment from "moment";
 | 
			
		||||
import { route, routes } from "@/routing";
 | 
			
		||||
import { useDispatch, useSelector } from "react-redux";
 | 
			
		||||
import { AppState } from "@/state/reducer";
 | 
			
		||||
import { StudentAction, StudentActions } from "@/state/actions/student";
 | 
			
		||||
import { sampleStudent } from "@/provider/dummy/student";
 | 
			
		||||
import { Trans, useTranslation } from "react-i18next";
 | 
			
		||||
import { Student } from "@/data";
 | 
			
		||||
import '@/styles/overrides.scss'
 | 
			
		||||
import moment, { Moment } from "moment";
 | 
			
		||||
import '@/styles/header.scss'
 | 
			
		||||
import classNames from "classnames";
 | 
			
		||||
import { EditionAction, EditionActions } from "@/state/actions/edition";
 | 
			
		||||
import { sampleEdition } from "@/provider/dummy/edition";
 | 
			
		||||
import { Edition } from "@/data/edition";
 | 
			
		||||
 | 
			
		||||
class LocalizedMomentUtils extends MomentUtils {
 | 
			
		||||
    getDatePickerHeaderText(date: Moment): string {
 | 
			
		||||
        return this.format(date, "d MMM yyyy");
 | 
			
		||||
const UserMenu = (props: HTMLProps<HTMLUListElement>) => {
 | 
			
		||||
    const student = useSelector<AppState, Student>(state => state.student as Student);
 | 
			
		||||
    const dispatch = useDispatch<Dispatch<StudentAction>>();
 | 
			
		||||
    const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
    const handleUserLogin = () => {
 | 
			
		||||
        dispatch({
 | 
			
		||||
            type: StudentActions.Login,
 | 
			
		||||
            student: sampleStudent,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const handleUserLogout = () => {
 | 
			
		||||
        dispatch({ type: StudentActions.Logout })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return <ul { ...props }>
 | 
			
		||||
        {
 | 
			
		||||
            student ? <>
 | 
			
		||||
                <Trans t={ t } i18nKey="logged-in-as">logged in as <strong>{ { name: `${ student.name } ${ student.surname }` } }</strong></Trans>
 | 
			
		||||
                { ' ' }
 | 
			
		||||
                (<Link to={ '#' } onClick={ handleUserLogout }>{ t('logout') }</Link>)
 | 
			
		||||
            </> : <>
 | 
			
		||||
                <Link to={ '#' } onClick={ handleUserLogin }>{ t('login') }</Link>
 | 
			
		||||
            </>
 | 
			
		||||
        }
 | 
			
		||||
    </ul>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const LanguageSwitcher = ({ className, ...props }: HTMLProps<HTMLUListElement>) => {
 | 
			
		||||
    const { i18n } = useTranslation();
 | 
			
		||||
 | 
			
		||||
    const handleLanguageChange = (language: string) => () => {
 | 
			
		||||
        i18n.changeLanguage(language);
 | 
			
		||||
        document.documentElement.lang = language;
 | 
			
		||||
        moment.locale(language)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const isActive = (language: string) => language.toLowerCase() === i18n.language.toLowerCase();
 | 
			
		||||
 | 
			
		||||
    return <ul className={ classNames(className, "language-switcher") } { ...props }>
 | 
			
		||||
        { ['pl', 'en'].map(language => <li key={ language }>
 | 
			
		||||
            <Link to="#" onClick={ handleLanguageChange(language) }
 | 
			
		||||
                  className={ classNames("language-switcher__language", isActive(language) && "language-switcher__language--active") }>
 | 
			
		||||
                { language }
 | 
			
		||||
            </Link>
 | 
			
		||||
        </li>) }
 | 
			
		||||
    </ul>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function App() {
 | 
			
		||||
  return (
 | 
			
		||||
      <StylesProvider injectFirst>
 | 
			
		||||
          <MuiPickersUtilsProvider utils={ LocalizedMomentUtils } libInstance={ moment }>
 | 
			
		||||
              <ThemeProvider theme={ studentTheme }>
 | 
			
		||||
                  <div className="app">
 | 
			
		||||
                      <Container maxWidth={"md"}>
 | 
			
		||||
                          <Typography variant="h3">Zgłoszenie Praktyki</Typography>
 | 
			
		||||
                          <Typography variant="subtitle1">UX Demo</Typography>
 | 
			
		||||
    const dispatch = useDispatch<Dispatch<EditionAction>>();
 | 
			
		||||
    const edition = useSelector<AppState, Edition | null>(state => state.edition);
 | 
			
		||||
 | 
			
		||||
                          <InternshipForm />
 | 
			
		||||
                      </Container>
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (!edition) {
 | 
			
		||||
            dispatch({ type: EditionActions.Set, edition: sampleEdition });
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const isReady = !!edition;
 | 
			
		||||
 | 
			
		||||
    return <>
 | 
			
		||||
        <header className="header">
 | 
			
		||||
            <div id="logo" className="header__logo">
 | 
			
		||||
                <Link to={ route('home') }>
 | 
			
		||||
                    <img src="img/pg-logotyp.svg"/>
 | 
			
		||||
                </Link>
 | 
			
		||||
            </div>
 | 
			
		||||
              </ThemeProvider>
 | 
			
		||||
          </MuiPickersUtilsProvider>
 | 
			
		||||
      </StylesProvider>
 | 
			
		||||
  );
 | 
			
		||||
            <div className="header__nav">
 | 
			
		||||
                <nav className="header__top">
 | 
			
		||||
                    <ul className="header__menu"></ul>
 | 
			
		||||
                    <UserMenu className="header__user"/>
 | 
			
		||||
                    <div className="header__divider"/>
 | 
			
		||||
                    <LanguageSwitcher className="header__language-switcher"/>
 | 
			
		||||
                </nav>
 | 
			
		||||
                <nav className="header__bottom">
 | 
			
		||||
                    <ul className="header__menu header__menu--main"></ul>
 | 
			
		||||
                </nav>
 | 
			
		||||
            </div>
 | 
			
		||||
        </header>
 | 
			
		||||
        { isReady && <Switch>{ routes.map(({ name, content, ...route }) => <Route { ...route } key={ name }>{ content() }</Route>) }</Switch> }
 | 
			
		||||
    </>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default App;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								src/components/actions.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/components/actions.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
import React, { HTMLProps } from "react";
 | 
			
		||||
import { makeStyles } from "@material-ui/core/styles";
 | 
			
		||||
 | 
			
		||||
export const Actions = (props: HTMLProps<HTMLDivElement>) => {
 | 
			
		||||
    const classes = makeStyles(theme => ({
 | 
			
		||||
        root: {
 | 
			
		||||
            "& > *": {
 | 
			
		||||
                marginRight: theme.spacing(1)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }))();
 | 
			
		||||
 | 
			
		||||
    return <div className={ classes.root } { ...props }/>
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								src/data/edition.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/data/edition.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
import { Moment } from "moment";
 | 
			
		||||
 | 
			
		||||
export type Edition = {
 | 
			
		||||
    startDate: Moment;
 | 
			
		||||
    endDate: Moment;
 | 
			
		||||
    proposalDeadline: Moment;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type Deadlines = {
 | 
			
		||||
    personalData?: Moment;
 | 
			
		||||
    proposal?: Moment;
 | 
			
		||||
    personalPlan?: Moment;
 | 
			
		||||
    report?: Moment;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getEditionDeadlines(edition: Edition): Deadlines {
 | 
			
		||||
    return {
 | 
			
		||||
        proposal: edition.proposalDeadline,
 | 
			
		||||
        personalPlan: edition.proposalDeadline,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { Moment } from "moment";
 | 
			
		||||
import { Identifiable } from "./common";
 | 
			
		||||
import { countWorkingWeeksInRange } from "@/utils/date";
 | 
			
		||||
import { Student } from "@/data/student";
 | 
			
		||||
import { Company } from "@/data/company";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,3 +11,18 @@ export interface Student extends Identifiable {
 | 
			
		||||
    semester: Semester;
 | 
			
		||||
    course: Course;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function isStudentDataComplete(student: Student): boolean {
 | 
			
		||||
    return getMissingStudentData(student).length === 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getMissingStudentData(student: Student): (keyof Student)[] {
 | 
			
		||||
    return [
 | 
			
		||||
        !!student.name || "name",
 | 
			
		||||
        !!student.surname || "surname",
 | 
			
		||||
        !!student.email || "email",
 | 
			
		||||
        !!student.albumNumber || "albumNumber",
 | 
			
		||||
        !!student.semester || "semester",
 | 
			
		||||
        !!student.course || "course",
 | 
			
		||||
    ].filter(x => x !== true) as (keyof Student)[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -144,13 +144,13 @@ export const InternshipForm: React.FunctionComponent<InternshipFormProps> = prop
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="internship-form">
 | 
			
		||||
            <Typography variant="h5" className="section-header">Dane osoby odbywającej praktykę</Typography>
 | 
			
		||||
            <Typography variant="h3" className="section-header">Dane osoby odbywającej praktykę</Typography>
 | 
			
		||||
            <StudentForm student={ sampleStudent }/>
 | 
			
		||||
            <Typography variant="h5" className="section-header">Rodzaj i program praktyki</Typography>
 | 
			
		||||
            <Typography variant="h3" className="section-header">Rodzaj i program praktyki</Typography>
 | 
			
		||||
            <InternshipProgramForm internship={ internship } onChange={ setInternship }/>
 | 
			
		||||
            <Typography variant="h5" className="section-header">Czas trwania praktyki</Typography>
 | 
			
		||||
            <Typography variant="h3" className="section-header">Czas trwania praktyki</Typography>
 | 
			
		||||
            <InternshipDurationForm internship={ internship } onChange={ setInternship }/>
 | 
			
		||||
            <Typography variant="h5" className="section-header">Miejsce odbywania praktyki</Typography>
 | 
			
		||||
            <Typography variant="h3" className="section-header">Miejsce odbywania praktyki</Typography>
 | 
			
		||||
            <CompanyForm internship={ internship } onChange={ setInternship }/>
 | 
			
		||||
            <Button variant="contained" color="primary">Wyślij</Button>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								src/i18n.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/i18n.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
import i18n from "i18next";
 | 
			
		||||
import { initReactI18next } from "react-i18next";
 | 
			
		||||
import I18nextBrowserLanguageDetector from "i18next-browser-languagedetector";
 | 
			
		||||
 | 
			
		||||
import moment from "moment";
 | 
			
		||||
 | 
			
		||||
import "moment/locale/pl"
 | 
			
		||||
import "moment/locale/en-gb"
 | 
			
		||||
 | 
			
		||||
const resources = {
 | 
			
		||||
    en: {
 | 
			
		||||
        translation: require('../translations/en.yaml'),
 | 
			
		||||
    },
 | 
			
		||||
    pl: {
 | 
			
		||||
        translation: require('../translations/pl.yaml'),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
i18n
 | 
			
		||||
    .use(I18nextBrowserLanguageDetector)
 | 
			
		||||
    .use(initReactI18next)
 | 
			
		||||
    .init({
 | 
			
		||||
        resources,
 | 
			
		||||
        fallbackLng: "en",
 | 
			
		||||
        interpolation: {
 | 
			
		||||
            escapeValue: false
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
document.documentElement.lang = i18n.language;
 | 
			
		||||
moment.locale(i18n.language)
 | 
			
		||||
 | 
			
		||||
export default i18n;
 | 
			
		||||
@ -1,10 +1,38 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import ReactDOM from 'react-dom';
 | 
			
		||||
import "./i18n"
 | 
			
		||||
import App from './app';
 | 
			
		||||
import { Provider } from "react-redux";
 | 
			
		||||
import store, { persistor } from "@/state/store";
 | 
			
		||||
import { PersistGate } from "redux-persist/integration/react";
 | 
			
		||||
import { MuiThemeProvider as ThemeProvider, StylesProvider } from "@material-ui/core/styles";
 | 
			
		||||
import { MuiPickersUtilsProvider } from "@material-ui/pickers";
 | 
			
		||||
import moment, { Moment } from "moment";
 | 
			
		||||
import { studentTheme } from "@/ui/theme";
 | 
			
		||||
import { BrowserRouter } from "react-router-dom";
 | 
			
		||||
import MomentUtils from "@date-io/moment";
 | 
			
		||||
 | 
			
		||||
class LocalizedMomentUtils extends MomentUtils {
 | 
			
		||||
    getDatePickerHeaderText(date: Moment): string {
 | 
			
		||||
        return this.format(date, "d MMM yyyy");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReactDOM.render(
 | 
			
		||||
  <React.StrictMode>
 | 
			
		||||
      <Provider store={ store }>
 | 
			
		||||
          <PersistGate loading={ null } persistor={ persistor }>
 | 
			
		||||
              <StylesProvider injectFirst>
 | 
			
		||||
                  <MuiPickersUtilsProvider utils={ LocalizedMomentUtils } libInstance={ moment }>
 | 
			
		||||
                      <ThemeProvider theme={ studentTheme }>
 | 
			
		||||
                          <BrowserRouter>
 | 
			
		||||
                              <App />
 | 
			
		||||
                          </BrowserRouter>
 | 
			
		||||
                      </ThemeProvider>
 | 
			
		||||
                  </MuiPickersUtilsProvider>
 | 
			
		||||
              </StylesProvider>
 | 
			
		||||
          </PersistGate>
 | 
			
		||||
      </Provider>
 | 
			
		||||
  </React.StrictMode>,
 | 
			
		||||
  document.getElementById('root')
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								src/pages/base.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/pages/base.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
import React, { HTMLProps, useEffect } from "react";
 | 
			
		||||
import classNames from "classnames"
 | 
			
		||||
import { Box, BoxProps, Breadcrumbs, BreadcrumbsProps, Container, Typography } from "@material-ui/core";
 | 
			
		||||
import "@/styles/page.scss"
 | 
			
		||||
 | 
			
		||||
export type PageProps = {
 | 
			
		||||
    title?: string;
 | 
			
		||||
} & BoxProps;
 | 
			
		||||
 | 
			
		||||
export type PageHeaderProps = {
 | 
			
		||||
    maxWidth?: "sm" | "md" | "lg" | false
 | 
			
		||||
} & HTMLProps<HTMLDivElement>
 | 
			
		||||
 | 
			
		||||
export const Page = ({ title, children, ...props }: PageProps) => {
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        document.title = title ? title + " | Praktyka Studencka" : "Praktyka Studencka";
 | 
			
		||||
    }, [ title ])
 | 
			
		||||
 | 
			
		||||
    return <Box {...props} className={ classNames("page", props.className) } component="main">
 | 
			
		||||
        { children }
 | 
			
		||||
    </Box>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Page.Header = ({ children, maxWidth = false, ...props }: PageHeaderProps) =>
 | 
			
		||||
    <section {...props} className={classNames("page__header", props.className)}>
 | 
			
		||||
        <Container maxWidth={ maxWidth }>
 | 
			
		||||
            { children }
 | 
			
		||||
        </Container>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
Page.Title = ({ children }: HTMLProps<any>) => <Typography variant="h2" className="page__title">{ children }</Typography>
 | 
			
		||||
 | 
			
		||||
Page.Breadcrumbs = ({ children, ...props }: BreadcrumbsProps) => <Breadcrumbs { ...props}>{ children }</Breadcrumbs>
 | 
			
		||||
							
								
								
									
										22
									
								
								src/pages/errors/not-found.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/pages/errors/not-found.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
import { Page } from "@/pages/base";
 | 
			
		||||
import { Box, Button, Container, Divider, Typography } from "@material-ui/core";
 | 
			
		||||
import { route } from "@/routing";
 | 
			
		||||
import { Link as RouterLink } from "react-router-dom";
 | 
			
		||||
import React from "react";
 | 
			
		||||
 | 
			
		||||
export const NotFoundPage = () => {
 | 
			
		||||
    return <Page title="Strona nie została znaleziona">
 | 
			
		||||
        <Container>
 | 
			
		||||
            <Typography variant="h1">404</Typography>
 | 
			
		||||
            <Typography variant="h2">Strona nie została znaleziona</Typography>
 | 
			
		||||
 | 
			
		||||
            <Box my={ 4 }>
 | 
			
		||||
                <Divider variant="fullWidth"/>
 | 
			
		||||
            </Box>
 | 
			
		||||
 | 
			
		||||
            <Button to={ route("home") } color="primary" component={ RouterLink }>strona główna</Button>
 | 
			
		||||
        </Container>
 | 
			
		||||
    </Page>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default NotFoundPage;
 | 
			
		||||
							
								
								
									
										4
									
								
								src/pages/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/pages/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
export * from "./internship/proposal";
 | 
			
		||||
export * from "./errors/not-found"
 | 
			
		||||
export * from "./main"
 | 
			
		||||
export { Actions } from "@/components/actions";
 | 
			
		||||
							
								
								
									
										52
									
								
								src/pages/internship/plan.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/pages/internship/plan.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
import { Page } from "@/pages/base";
 | 
			
		||||
import { Button, Container, FormHelperText, Grid, Link, Typography } from "@material-ui/core";
 | 
			
		||||
import { Link as RouterLink } from "react-router-dom";
 | 
			
		||||
import { route } from "@/routing";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { useTranslation } from "react-i18next";
 | 
			
		||||
import { DropzoneArea } from "material-ui-dropzone";
 | 
			
		||||
import { Description as DescriptionIcon } from "@material-ui/icons";
 | 
			
		||||
import { Actions } from "@/components/actions";
 | 
			
		||||
 | 
			
		||||
export const SubmitPlanPage = () => {
 | 
			
		||||
    const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
    return <Page title={ t("steps.plan.submit") }>
 | 
			
		||||
        <Page.Header maxWidth="md">
 | 
			
		||||
            <Page.Breadcrumbs>
 | 
			
		||||
                <Link component={ RouterLink } to={ route("home") }>{ t('sections.my-internship.header') }</Link>
 | 
			
		||||
                <Typography color="textPrimary">{ t("steps.plan.submit") }</Typography>
 | 
			
		||||
            </Page.Breadcrumbs>
 | 
			
		||||
            <Page.Title>{ t("steps.plan.submit") }</Page.Title>
 | 
			
		||||
        </Page.Header>
 | 
			
		||||
        <Container maxWidth={ "md" }>
 | 
			
		||||
            <Grid container>
 | 
			
		||||
                <Grid item>
 | 
			
		||||
                    <Typography variant="body1" component="p">{ t('forms.plan.instructions') }</Typography>
 | 
			
		||||
                </Grid>
 | 
			
		||||
                <Grid item>
 | 
			
		||||
                    <Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon /> }>
 | 
			
		||||
                        { t('steps.plan.template') }
 | 
			
		||||
                    </Button>
 | 
			
		||||
                </Grid>
 | 
			
		||||
                <Grid item>
 | 
			
		||||
                    <DropzoneArea acceptedFiles={["image/*", "application/x-pdf"]} filesLimit={ 1 } dropzoneText={ t("dropzone") }/>
 | 
			
		||||
                    <FormHelperText>{ t('forms.plan.dropzone-help') }</FormHelperText>
 | 
			
		||||
                </Grid>
 | 
			
		||||
                <Grid item>
 | 
			
		||||
                    <Actions>
 | 
			
		||||
                        <Button variant="contained" color="primary">
 | 
			
		||||
                            { t('confirm') }
 | 
			
		||||
                        </Button>
 | 
			
		||||
 | 
			
		||||
                        <Button component={ RouterLink } to={ route("home") }>
 | 
			
		||||
                            { t('go-back') }
 | 
			
		||||
                        </Button>
 | 
			
		||||
                    </Actions>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </Container>
 | 
			
		||||
    </Page>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default SubmitPlanPage;
 | 
			
		||||
							
								
								
									
										23
									
								
								src/pages/internship/proposal.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/pages/internship/proposal.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
import { Page } from "@/pages/base";
 | 
			
		||||
import { Container, Link, Typography } from "@material-ui/core";
 | 
			
		||||
import { Link as RouterLink } from "react-router-dom";
 | 
			
		||||
import { route } from "@/routing";
 | 
			
		||||
import { InternshipForm } from "@/forms/Internship";
 | 
			
		||||
import React from "react";
 | 
			
		||||
 | 
			
		||||
export const InternshipProposalPage = () => {
 | 
			
		||||
    return <Page title="Zgłoszenie praktyki">
 | 
			
		||||
        <Page.Header maxWidth="md">
 | 
			
		||||
            <Page.Breadcrumbs>
 | 
			
		||||
                <Link component={ RouterLink } to={ route("home") }>Moja praktyka</Link>
 | 
			
		||||
                <Typography color="textPrimary">Zgłoszenie praktyki</Typography>
 | 
			
		||||
            </Page.Breadcrumbs>
 | 
			
		||||
            <Page.Title>Zgłoszenie praktyki</Page.Title>
 | 
			
		||||
        </Page.Header>
 | 
			
		||||
        <Container maxWidth={ "md" }>
 | 
			
		||||
            <InternshipForm/>
 | 
			
		||||
        </Container>
 | 
			
		||||
    </Page>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default InternshipProposalPage;
 | 
			
		||||
							
								
								
									
										95
									
								
								src/pages/main.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/pages/main.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,95 @@
 | 
			
		||||
import React, { useMemo } from "react";
 | 
			
		||||
import { Page } from "@/pages/base";
 | 
			
		||||
import { Box, Button, Container, Step as StepperStep, StepContent, StepLabel, Stepper, StepProps as StepperStepProps, Typography } from "@material-ui/core";
 | 
			
		||||
import { Link as RouterLink } from "react-router-dom";
 | 
			
		||||
import { route } from "@/routing";
 | 
			
		||||
import { useTranslation } from "react-i18next";
 | 
			
		||||
import moment, { Moment } from "moment";
 | 
			
		||||
import { useSelector } from "react-redux";
 | 
			
		||||
import { AppState } from "@/state/reducer";
 | 
			
		||||
import { getMissingStudentData, Student } from "@/data";
 | 
			
		||||
import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
 | 
			
		||||
import { Description as DescriptionIcon } from "@material-ui/icons"
 | 
			
		||||
import { Actions } from "@/components/actions";
 | 
			
		||||
 | 
			
		||||
type StepProps = StepperStepProps & {
 | 
			
		||||
    until?: Moment;
 | 
			
		||||
    completedOn?: Moment;
 | 
			
		||||
    label: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const now = moment();
 | 
			
		||||
 | 
			
		||||
const Step = ({ until, label, completedOn, children, completed, ...props }: StepProps) => {
 | 
			
		||||
    const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
    const isLate = useMemo(() => until?.isBefore(completedOn || now), [completedOn, until]);
 | 
			
		||||
    const left = useMemo(() => moment.duration(now.diff(until)), [until]);
 | 
			
		||||
 | 
			
		||||
    return <StepperStep { ...props } completed={ completed || !!completedOn }>
 | 
			
		||||
        <StepLabel>
 | 
			
		||||
            { label }
 | 
			
		||||
            { until && <Box>
 | 
			
		||||
                <Typography variant="subtitle2" color="textSecondary">
 | 
			
		||||
                    { t('until', { date: until.format("DD MMMM YYYY") }) }
 | 
			
		||||
                    { isLate && <Typography color="error" display="inline"
 | 
			
		||||
                                            variant="body2"> - { t('late', { by: moment.duration(now.diff(until)).humanize() }) }</Typography> }
 | 
			
		||||
                    { !isLate && !completed && <Typography display="inline" variant="body2"> - { t('left', { left: left.humanize() }) }</Typography> }
 | 
			
		||||
                </Typography>
 | 
			
		||||
            </Box> }
 | 
			
		||||
        </StepLabel>
 | 
			
		||||
        { children && <StepContent>{ children }</StepContent> }
 | 
			
		||||
    </StepperStep>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const MainPage = () => {
 | 
			
		||||
    const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
    const student = useSelector<AppState, Student | null>(state => state.student);
 | 
			
		||||
    const deadlines = useSelector<AppState, Deadlines>(state => getEditionDeadlines(state.edition as Edition)); // edition cannot be null at this point
 | 
			
		||||
 | 
			
		||||
    const missingStudentData = useMemo(() => student ? getMissingStudentData(student) : [], [student]);
 | 
			
		||||
 | 
			
		||||
    return <Page my={ 6 }>
 | 
			
		||||
        <Container>
 | 
			
		||||
            <Typography variant="h2">{ t("sections.my-internship.header") }</Typography>
 | 
			
		||||
            <Stepper orientation="vertical" nonLinear>
 | 
			
		||||
                <Step label={ t('steps.personal-data.header') } completed={ missingStudentData.length === 0 } until={ deadlines.personalData }>
 | 
			
		||||
                    { missingStudentData.length > 0 && <>
 | 
			
		||||
                        <p>{ t('steps.personal-data.info') }</p>
 | 
			
		||||
 | 
			
		||||
                        <ul>
 | 
			
		||||
                            { missingStudentData.map(field => <li key={ field }>{ t(`student.${ field }`) }</li>) }
 | 
			
		||||
                        </ul>
 | 
			
		||||
 | 
			
		||||
                        <Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }>
 | 
			
		||||
                            { t('steps.personal-data.form') }
 | 
			
		||||
                        </Button>
 | 
			
		||||
                    </> }
 | 
			
		||||
                </Step>
 | 
			
		||||
                <Step label={ t('steps.internship-proposal.header') } active={ missingStudentData.length === 0 } until={ deadlines.proposal }>
 | 
			
		||||
                    <p>{ t('steps.internship-proposal.info') }</p>
 | 
			
		||||
 | 
			
		||||
                    <Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }>
 | 
			
		||||
                        { t('steps.internship-proposal.form') }
 | 
			
		||||
                    </Button>
 | 
			
		||||
                </Step>
 | 
			
		||||
                <Step label={ t('steps.plan.header') } active={ missingStudentData.length === 0 } until={ deadlines.proposal }>
 | 
			
		||||
                    <p>{ t('steps.plan.info') }</p>
 | 
			
		||||
 | 
			
		||||
                    <Actions>
 | 
			
		||||
                        <Button to={ route("internship_plan") } variant="contained" color="primary" component={ RouterLink }>
 | 
			
		||||
                            { t('steps.plan.submit') }
 | 
			
		||||
                        </Button>
 | 
			
		||||
                        <Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon /> }>
 | 
			
		||||
                            { t('steps.plan.template') }
 | 
			
		||||
                        </Button>
 | 
			
		||||
                    </Actions>
 | 
			
		||||
                </Step>
 | 
			
		||||
                <Step label={ t('steps.insurance.header') }/>
 | 
			
		||||
                <Step label={ t('steps.report.header') } until={ deadlines.report }/>
 | 
			
		||||
                <Step label={ t('steps.grade.header') }/>
 | 
			
		||||
            </Stepper>
 | 
			
		||||
        </Container>
 | 
			
		||||
    </Page>
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								src/provider/dummy/edition.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/provider/dummy/edition.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
import { Edition } from "@/data/edition";
 | 
			
		||||
import moment from "moment";
 | 
			
		||||
 | 
			
		||||
export const sampleEdition: Edition = {
 | 
			
		||||
    startDate: moment("2020-07-01"),
 | 
			
		||||
    endDate: moment("2020-09-30"),
 | 
			
		||||
    proposalDeadline: moment("2020-07-31")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								src/routing.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/routing.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
import React, { ReactComponentElement } from "react";
 | 
			
		||||
import { MainPage } from "@/pages/main";
 | 
			
		||||
import { RouteProps } from "react-router-dom";
 | 
			
		||||
import { InternshipProposalPage } from "@/pages/internship/proposal";
 | 
			
		||||
import { NotFoundPage } from "@/pages/errors/not-found";
 | 
			
		||||
import SubmitPlanPage from "@/pages/internship/plan";
 | 
			
		||||
 | 
			
		||||
type Route = {
 | 
			
		||||
    name?: string;
 | 
			
		||||
    content: () => ReactComponentElement<any>,
 | 
			
		||||
} & RouteProps;
 | 
			
		||||
 | 
			
		||||
export const routes: Route[] = [
 | 
			
		||||
    { name: "home", path: "/", exact: true, content: () => <MainPage/> },
 | 
			
		||||
 | 
			
		||||
    { name: "internship_proposal", path: "/internship/proposal", exact: true, content: () => <InternshipProposalPage/> },
 | 
			
		||||
    { name: "internship_plan", path: "/internship/plan", exact: true, content: () => <SubmitPlanPage/> },
 | 
			
		||||
 | 
			
		||||
    // fallback route for 404 pages
 | 
			
		||||
    { name: "fallback", path: "*", content: () => <NotFoundPage/> }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const routeNameMap = new Map(routes.filter(({ name }) => !!name).map(({ name, path }) => [name, path instanceof Array ? path[0] : path])) as Map<string, string>
 | 
			
		||||
 | 
			
		||||
export function route(name: string, params: { [param: string]: string } = {}) {
 | 
			
		||||
    const url = routeNameMap.get(name) || "";
 | 
			
		||||
 | 
			
		||||
    return Object.entries(params).reduce((url, [name, value]) => url.replace(`:${ name }`, value), url);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								src/state/actions/base.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/state/actions/base.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
export interface Action<TType extends string> {
 | 
			
		||||
    readonly type: TType;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								src/state/actions/edition.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/state/actions/edition.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
import { Action } from "@/state/actions/base";
 | 
			
		||||
import { Edition } from "@/data/edition";
 | 
			
		||||
 | 
			
		||||
export enum EditionActions {
 | 
			
		||||
    Set = 'SET',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface SetAction extends Action<EditionActions.Set> {
 | 
			
		||||
    edition: Edition,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type EditionAction = SetAction;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								src/state/actions/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/state/actions/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										16
									
								
								src/state/actions/student.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/state/actions/student.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
import { Action } from "@/state/actions/base";
 | 
			
		||||
import { Student } from "@/data";
 | 
			
		||||
 | 
			
		||||
export enum StudentActions {
 | 
			
		||||
    Login = 'LOGIN',
 | 
			
		||||
    Logout = 'LOGOUT'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface LoginAction extends Action<StudentActions.Login> {
 | 
			
		||||
    student: Student
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type LogoutAction = Action<StudentActions.Logout>;
 | 
			
		||||
 | 
			
		||||
export type StudentAction = LoginAction | LogoutAction;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								src/state/reducer/edition.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/state/reducer/edition.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
import { Edition } from "@/data/edition";
 | 
			
		||||
import { EditionAction, EditionActions } from "@/state/actions/edition";
 | 
			
		||||
 | 
			
		||||
export type EditionState = Edition | null;
 | 
			
		||||
 | 
			
		||||
const initialEditionState: EditionState = null;
 | 
			
		||||
 | 
			
		||||
const editionReducer = (state: EditionState = initialEditionState, action: EditionAction): EditionState => {
 | 
			
		||||
    switch (action.type) {
 | 
			
		||||
        case EditionActions.Set:
 | 
			
		||||
            return action.edition;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default editionReducer;
 | 
			
		||||
							
								
								
									
										13
									
								
								src/state/reducer/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/state/reducer/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
import { combineReducers } from "redux";
 | 
			
		||||
 | 
			
		||||
import studentReducer from "./student"
 | 
			
		||||
import editionReducer from "@/state/reducer/edition";
 | 
			
		||||
 | 
			
		||||
const rootReducer = combineReducers({
 | 
			
		||||
    student: studentReducer,
 | 
			
		||||
    edition: editionReducer,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export type AppState = ReturnType<typeof rootReducer>;
 | 
			
		||||
 | 
			
		||||
export default rootReducer;
 | 
			
		||||
							
								
								
									
										20
									
								
								src/state/reducer/student.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/state/reducer/student.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
import { Student } from "@/data";
 | 
			
		||||
import { StudentAction, StudentActions } from "@/state/actions/student";
 | 
			
		||||
 | 
			
		||||
export type StudentState = Student | null;
 | 
			
		||||
 | 
			
		||||
const initialStudentState: StudentState = null;
 | 
			
		||||
 | 
			
		||||
const studentReducer = (state: StudentState = initialStudentState, action: StudentAction): StudentState => {
 | 
			
		||||
    switch (action.type) {
 | 
			
		||||
        case StudentActions.Login:
 | 
			
		||||
            return action.student;
 | 
			
		||||
 | 
			
		||||
        case StudentActions.Logout:
 | 
			
		||||
            return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default studentReducer;
 | 
			
		||||
							
								
								
									
										21
									
								
								src/state/store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/state/store.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
import { createStore } from "redux";
 | 
			
		||||
import rootReducer from "@/state/reducer";
 | 
			
		||||
import { devToolsEnhancer } from "redux-devtools-extension";
 | 
			
		||||
import { persistReducer, persistStore } from "redux-persist"
 | 
			
		||||
import sessionStorage from "redux-persist/lib/storage/session"
 | 
			
		||||
 | 
			
		||||
const store = createStore(
 | 
			
		||||
    persistReducer(
 | 
			
		||||
        {
 | 
			
		||||
            key: 'state',
 | 
			
		||||
            storage: sessionStorage,
 | 
			
		||||
            blacklist: ['edition']
 | 
			
		||||
        },
 | 
			
		||||
        rootReducer
 | 
			
		||||
    ),
 | 
			
		||||
    devToolsEnhancer({})
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const persistor = persistStore(store)
 | 
			
		||||
 | 
			
		||||
export default store;
 | 
			
		||||
							
								
								
									
										5
									
								
								src/styles/_variables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/styles/_variables.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
$brand: #043865;
 | 
			
		||||
 | 
			
		||||
$main: #052f52;
 | 
			
		||||
$main-dark: #072138;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								src/styles/header.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/styles/header.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
@import "variables";
 | 
			
		||||
 | 
			
		||||
.header {
 | 
			
		||||
  height: 110px;
 | 
			
		||||
  background: $main;
 | 
			
		||||
  display: flex;
 | 
			
		||||
 | 
			
		||||
  color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.header__logo {
 | 
			
		||||
  width: 152px;
 | 
			
		||||
  background: $brand;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
 | 
			
		||||
  img {
 | 
			
		||||
    max-width: 100px;
 | 
			
		||||
    max-height: 72px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.header__top {
 | 
			
		||||
  background-color: $main-dark;
 | 
			
		||||
  height: 38px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  font-size: 0.75rem;
 | 
			
		||||
  color: #e4f1fe;
 | 
			
		||||
  padding: 0 1rem;
 | 
			
		||||
 | 
			
		||||
  a {
 | 
			
		||||
    color: #e4f1fe
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .header__divider {
 | 
			
		||||
    margin: 0 1rem;
 | 
			
		||||
    background: #274057;
 | 
			
		||||
    width: 1px;
 | 
			
		||||
    height: 60%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.header__nav {
 | 
			
		||||
  flex: 1 1 auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.header__top .header__menu {
 | 
			
		||||
  margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.header__language-switcher {
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  text-transform: uppercase;
 | 
			
		||||
 | 
			
		||||
  li {
 | 
			
		||||
    list-style: none;
 | 
			
		||||
 | 
			
		||||
    &:not(:last-child) {
 | 
			
		||||
      margin-right: .5rem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    a {
 | 
			
		||||
      padding: 7px;
 | 
			
		||||
      display: block;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.language-switcher__language--active {
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  cursor: default;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
@ -11,6 +11,13 @@
 | 
			
		||||
  margin-top: 1.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#root {
 | 
			
		||||
  margin: 100px 0;
 | 
			
		||||
html, body {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
 | 
			
		||||
  font-family: "Roboto", "Helvetica", "Arial", sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
* {
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								src/styles/page.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/styles/page.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
@import "variables";
 | 
			
		||||
 | 
			
		||||
.page__header {
 | 
			
		||||
  background-color: #e9f0f5;
 | 
			
		||||
  padding: 20px 0;
 | 
			
		||||
  margin-bottom: 2rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.page__title {
 | 
			
		||||
  color: $brand;
 | 
			
		||||
  font-size: 3rem;
 | 
			
		||||
  font-weight: 400;
 | 
			
		||||
  line-height: 1.5;
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +1,34 @@
 | 
			
		||||
import { createMuiTheme } from "@material-ui/core/styles";
 | 
			
		||||
import { createMuiTheme, responsiveFontSizes } from "@material-ui/core/styles";
 | 
			
		||||
 | 
			
		||||
export const studentTheme = createMuiTheme({
 | 
			
		||||
export const studentTheme = responsiveFontSizes(createMuiTheme({
 | 
			
		||||
    props: {
 | 
			
		||||
        MuiGrid: {
 | 
			
		||||
            spacing: 3,
 | 
			
		||||
            xs: 12,
 | 
			
		||||
        },
 | 
			
		||||
        MuiContainer: {
 | 
			
		||||
            maxWidth: "md"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    palette: {
 | 
			
		||||
        primary: {
 | 
			
		||||
            main: "#043865",
 | 
			
		||||
            dark: "#072138"
 | 
			
		||||
        }
 | 
			
		||||
})
 | 
			
		||||
    },
 | 
			
		||||
    typography: {
 | 
			
		||||
        h2: {
 | 
			
		||||
            fontSize: "3rem",
 | 
			
		||||
            fontWeight: 400,
 | 
			
		||||
            color: "#043865",
 | 
			
		||||
        },
 | 
			
		||||
        h3: {
 | 
			
		||||
            fontSize: "2.25rem",
 | 
			
		||||
            lineHeight: "1.2",
 | 
			
		||||
        },
 | 
			
		||||
        h4: {
 | 
			
		||||
            fontSize: "1.75rem"
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    spacing: 8
 | 
			
		||||
}))
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										44
									
								
								translations/en.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								translations/en.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
---
 | 
			
		||||
login: login
 | 
			
		||||
logout: logout
 | 
			
		||||
logged-in-as: logged in as <1>{{ name }}</1>
 | 
			
		||||
 | 
			
		||||
until: until {{ date }}
 | 
			
		||||
late: late by {{ by }}
 | 
			
		||||
left: '{{ left }} left'
 | 
			
		||||
 | 
			
		||||
dropzone: "Drag and drop a file here or click to choose"
 | 
			
		||||
 | 
			
		||||
student:
 | 
			
		||||
  name: first name
 | 
			
		||||
  surname: last name
 | 
			
		||||
  course: course
 | 
			
		||||
  semester: semester
 | 
			
		||||
  email: e-mail
 | 
			
		||||
  albumNumber: album number
 | 
			
		||||
 | 
			
		||||
sections:
 | 
			
		||||
  my-internship:
 | 
			
		||||
    header: "My internship"
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
  personal-data:
 | 
			
		||||
    header: "Fill personal data"
 | 
			
		||||
    info: >
 | 
			
		||||
      Your profile is incomplete. In order to continue your internship you have to supply information given below. In
 | 
			
		||||
      case of problem with providing those information - please contact with your internship coordinator of your course.
 | 
			
		||||
  internship-proposal:
 | 
			
		||||
    header: "Internship proposal"
 | 
			
		||||
    form: "Internship proposal form"
 | 
			
		||||
    info: ""
 | 
			
		||||
  plan:
 | 
			
		||||
    header: "Individual Internship Plan"
 | 
			
		||||
    info: ""
 | 
			
		||||
    template: "Download template"
 | 
			
		||||
    submit: "Submit Individual Internship Plan"
 | 
			
		||||
  insurance:
 | 
			
		||||
    header: "Insurance"
 | 
			
		||||
  report:
 | 
			
		||||
    header: "Internship report"
 | 
			
		||||
  grade:
 | 
			
		||||
    header: "Your grade"
 | 
			
		||||
							
								
								
									
										57
									
								
								translations/pl.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								translations/pl.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
---
 | 
			
		||||
login: zaloguj się
 | 
			
		||||
logout: wyloguj się
 | 
			
		||||
logged-in-as: zalogowany jako <1>{{ name }}</1>
 | 
			
		||||
 | 
			
		||||
until: do {{ date }}
 | 
			
		||||
late: '{{ by }} spóźnienia'
 | 
			
		||||
left: jeszcze {{ left }}
 | 
			
		||||
 | 
			
		||||
confirm: zatwierdź
 | 
			
		||||
go-back: wstecz
 | 
			
		||||
 | 
			
		||||
dropzone: "Przeciągnij i upuść plik bądź kliknij, aby wybrać"
 | 
			
		||||
 | 
			
		||||
sections:
 | 
			
		||||
  my-internship:
 | 
			
		||||
    header: "Moja praktyka"
 | 
			
		||||
 | 
			
		||||
forms:
 | 
			
		||||
  plan:
 | 
			
		||||
    instructions: >
 | 
			
		||||
      Wypełnij i zeskanuj Indywidualny Plan Praktyk a następnie wyślij go z pomocą tego formularza. <więcej informacji>
 | 
			
		||||
    dropzone-help: Skan dokumentu w formacie PDF
 | 
			
		||||
 | 
			
		||||
student:
 | 
			
		||||
  name: imię
 | 
			
		||||
  surname: mazwisko
 | 
			
		||||
  course: kierunek
 | 
			
		||||
  semester: semestr
 | 
			
		||||
  email: adres e-mail
 | 
			
		||||
  albumNumber: numer albumu
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
  personal-data:
 | 
			
		||||
    header: "Uzupełnienie informacji"
 | 
			
		||||
    info: >
 | 
			
		||||
      Twój profil jest niekompletny. W celu kontynuacji praktyki musisz uzupełnić informacje podane poniżej. Jeżeli masz
 | 
			
		||||
      problem z uzupełnieniem tych informacji - skontaktuj się z koordynatorem praktyk dla Twojego kierunku.
 | 
			
		||||
    form: "Uzupełnij dane"
 | 
			
		||||
  internship-proposal:
 | 
			
		||||
    header: "Zgłoszenie praktyki"
 | 
			
		||||
    info: >
 | 
			
		||||
      Przed podjęciem praktyki należy ją zgłosić.
 | 
			
		||||
    form: "Formularz zgłaszania praktyki"
 | 
			
		||||
  plan:
 | 
			
		||||
    header: "Indywidualny Program Praktyki"
 | 
			
		||||
    info: ""
 | 
			
		||||
    template: "Pobierz szablon"
 | 
			
		||||
    submit: "Wyślij Indywidualny Plan Praktyki"
 | 
			
		||||
  report:
 | 
			
		||||
    header: "Raport z praktyki"
 | 
			
		||||
  grade:
 | 
			
		||||
    header: "Ocena z praktyki"
 | 
			
		||||
  insurance:
 | 
			
		||||
    header: "Ubezpieczenie NNW"
 | 
			
		||||
 | 
			
		||||
contact-coordinator: "Skontaktuj się z koordynatorem"
 | 
			
		||||
@ -34,6 +34,10 @@ const config = {
 | 
			
		||||
        }, {
 | 
			
		||||
            test: /\.(woff|woff2|eot|ttf|otf)$/,
 | 
			
		||||
            use: 'file-loader'
 | 
			
		||||
        }, {
 | 
			
		||||
            test: /\.ya?ml$/,
 | 
			
		||||
            type: 'json',
 | 
			
		||||
            use: 'yaml-loader'
 | 
			
		||||
        }]
 | 
			
		||||
    },
 | 
			
		||||
    plugins: [
 | 
			
		||||
@ -48,6 +52,7 @@ const config = {
 | 
			
		||||
        port: 3000,
 | 
			
		||||
        host: 'system-praktyk-front.localhost',
 | 
			
		||||
        disableHostCheck: true,
 | 
			
		||||
        historyApiFallback: true,
 | 
			
		||||
    },
 | 
			
		||||
    optimization: {
 | 
			
		||||
        usedExports: true
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										272
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								yarn.lock
									
									
									
									
									
								
							@ -919,13 +919,20 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.13.4"
 | 
			
		||||
 | 
			
		||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
 | 
			
		||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
 | 
			
		||||
  version "7.10.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839"
 | 
			
		||||
  integrity sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.13.4"
 | 
			
		||||
 | 
			
		||||
"@babel/runtime@^7.10.1":
 | 
			
		||||
  version "7.10.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99"
 | 
			
		||||
  integrity sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    regenerator-runtime "^0.13.4"
 | 
			
		||||
 | 
			
		||||
"@babel/template@^7.10.1", "@babel/template@^7.8.6":
 | 
			
		||||
  version "7.10.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811"
 | 
			
		||||
@ -1036,6 +1043,13 @@
 | 
			
		||||
    react-is "^16.8.0"
 | 
			
		||||
    react-transition-group "^4.4.0"
 | 
			
		||||
 | 
			
		||||
"@material-ui/icons@^4.9.1":
 | 
			
		||||
  version "4.9.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.9.1.tgz#fdeadf8cb3d89208945b33dbc50c7c616d0bd665"
 | 
			
		||||
  integrity sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.4.4"
 | 
			
		||||
 | 
			
		||||
"@material-ui/lab@^4.0.0-alpha.55":
 | 
			
		||||
  version "4.0.0-alpha.55"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.55.tgz#82a850dc59654e04ee3a31be1b34eb3bf64d5585"
 | 
			
		||||
@ -1123,6 +1137,11 @@
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
 | 
			
		||||
  integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==
 | 
			
		||||
 | 
			
		||||
"@types/classnames@^2.2.10":
 | 
			
		||||
  version "2.2.10"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999"
 | 
			
		||||
  integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==
 | 
			
		||||
 | 
			
		||||
"@types/eslint-visitor-keys@^1.0.0":
 | 
			
		||||
  version "1.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
 | 
			
		||||
@ -1136,6 +1155,19 @@
 | 
			
		||||
    "@types/minimatch" "*"
 | 
			
		||||
    "@types/node" "*"
 | 
			
		||||
 | 
			
		||||
"@types/history@*":
 | 
			
		||||
  version "4.7.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.6.tgz#ed8fc802c45b8e8f54419c2d054e55c9ea344356"
 | 
			
		||||
  integrity sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w==
 | 
			
		||||
 | 
			
		||||
"@types/hoist-non-react-statics@^3.3.0":
 | 
			
		||||
  version "3.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
 | 
			
		||||
  integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
    hoist-non-react-statics "^3.3.0"
 | 
			
		||||
 | 
			
		||||
"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
 | 
			
		||||
  version "7.0.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
 | 
			
		||||
@ -1178,6 +1210,33 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
 | 
			
		||||
"@types/react-redux@^7.1.9":
 | 
			
		||||
  version "7.1.9"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.9.tgz#280c13565c9f13ceb727ec21e767abe0e9b4aec3"
 | 
			
		||||
  integrity sha512-mpC0jqxhP4mhmOl3P4ipRsgTgbNofMRXJb08Ms6gekViLj61v1hOZEKWDCyWsdONr6EjEA6ZHXC446wdywDe0w==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/hoist-non-react-statics" "^3.3.0"
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
    hoist-non-react-statics "^3.3.0"
 | 
			
		||||
    redux "^4.0.0"
 | 
			
		||||
 | 
			
		||||
"@types/react-router-dom@^5.1.5":
 | 
			
		||||
  version "5.1.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.5.tgz#7c334a2ea785dbad2b2dcdd83d2cf3d9973da090"
 | 
			
		||||
  integrity sha512-ArBM4B1g3BWLGbaGvwBGO75GNFbLDUthrDojV2vHLih/Tq8M+tgvY1DSwkuNrPSwdp/GUL93WSEpTZs8nVyJLw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/history" "*"
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
    "@types/react-router" "*"
 | 
			
		||||
 | 
			
		||||
"@types/react-router@*":
 | 
			
		||||
  version "5.1.8"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.8.tgz#4614e5ba7559657438e17766bb95ef6ed6acc3fa"
 | 
			
		||||
  integrity sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/history" "*"
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
 | 
			
		||||
"@types/react-transition-group@^4.2.0":
 | 
			
		||||
  version "4.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d"
 | 
			
		||||
@ -1193,6 +1252,20 @@
 | 
			
		||||
    "@types/prop-types" "*"
 | 
			
		||||
    csstype "^2.2.0"
 | 
			
		||||
 | 
			
		||||
"@types/redux-persist@^4.3.1":
 | 
			
		||||
  version "4.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/redux-persist/-/redux-persist-4.3.1.tgz#aa4c876859e0bea5155e5f7980e5b8c4699dc2e6"
 | 
			
		||||
  integrity sha1-qkyHaFngvqUVXl95gOW4xGmdwuY=
 | 
			
		||||
  dependencies:
 | 
			
		||||
    redux-persist "*"
 | 
			
		||||
 | 
			
		||||
"@types/redux@^3.6.0":
 | 
			
		||||
  version "3.6.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/redux/-/redux-3.6.0.tgz#f1ebe1e5411518072e4fdfca5c76e16e74c1399a"
 | 
			
		||||
  integrity sha1-8evh5UEVGAcuT9/KXHbhbnTBOZo=
 | 
			
		||||
  dependencies:
 | 
			
		||||
    redux "*"
 | 
			
		||||
 | 
			
		||||
"@types/source-list-map@*":
 | 
			
		||||
  version "0.1.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
 | 
			
		||||
@ -1703,6 +1776,11 @@ atob@^2.1.2:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
 | 
			
		||||
  integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
 | 
			
		||||
 | 
			
		||||
attr-accept@^2.0.0:
 | 
			
		||||
  version "2.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.1.0.tgz#a231a854385d36ff7a99647bb77b33c8a5175aee"
 | 
			
		||||
  integrity sha512-sLzVM3zCCmmDtDNhI0i96k6PUztkotSOXqE4kDGQt/6iDi5M+H0srjeF+QC6jN581l4X/Zq3Zu/tgcErEssavg==
 | 
			
		||||
 | 
			
		||||
autoprefixer@^9.6.1:
 | 
			
		||||
  version "9.8.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.0.tgz#68e2d2bef7ba4c3a65436f662d0a56a741e56511"
 | 
			
		||||
@ -2407,6 +2485,11 @@ class-utils@^0.3.5:
 | 
			
		||||
    isobject "^3.0.0"
 | 
			
		||||
    static-extend "^0.1.1"
 | 
			
		||||
 | 
			
		||||
classnames@^2.2.6:
 | 
			
		||||
  version "2.2.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
 | 
			
		||||
  integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
 | 
			
		||||
 | 
			
		||||
clean-css@^4.2.3:
 | 
			
		||||
  version "4.2.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
 | 
			
		||||
@ -3722,6 +3805,13 @@ file-loader@4.3.0:
 | 
			
		||||
    loader-utils "^1.2.3"
 | 
			
		||||
    schema-utils "^2.5.0"
 | 
			
		||||
 | 
			
		||||
file-selector@^0.1.12:
 | 
			
		||||
  version "0.1.12"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.1.12.tgz#fe726547be219a787a9dcc640575a04a032b1fd0"
 | 
			
		||||
  integrity sha512-Kx7RTzxyQipHuiqyZGf+Nz4vY9R1XGxuQl/hLoJwq+J4avk/9wxxgZyHKtbyIPJmbD4A66DWGYfyykWNpcYutQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    tslib "^1.9.0"
 | 
			
		||||
 | 
			
		||||
file-uri-to-path@1.0.0:
 | 
			
		||||
  version "1.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
 | 
			
		||||
@ -4240,6 +4330,18 @@ hex-color-regex@^1.1.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
 | 
			
		||||
  integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
 | 
			
		||||
 | 
			
		||||
history@^4.9.0:
 | 
			
		||||
  version "4.10.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
 | 
			
		||||
  integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.1.2"
 | 
			
		||||
    loose-envify "^1.2.0"
 | 
			
		||||
    resolve-pathname "^3.0.0"
 | 
			
		||||
    tiny-invariant "^1.0.2"
 | 
			
		||||
    tiny-warning "^1.0.0"
 | 
			
		||||
    value-equal "^1.0.1"
 | 
			
		||||
 | 
			
		||||
hmac-drbg@^1.0.0:
 | 
			
		||||
  version "1.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
 | 
			
		||||
@ -4249,7 +4351,7 @@ hmac-drbg@^1.0.0:
 | 
			
		||||
    minimalistic-assert "^1.0.0"
 | 
			
		||||
    minimalistic-crypto-utils "^1.0.1"
 | 
			
		||||
 | 
			
		||||
hoist-non-react-statics@^3.3.2:
 | 
			
		||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
 | 
			
		||||
  version "3.3.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
 | 
			
		||||
  integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
 | 
			
		||||
@ -4319,6 +4421,13 @@ html-minifier-terser@^5.0.1:
 | 
			
		||||
    relateurl "^0.2.7"
 | 
			
		||||
    terser "^4.6.3"
 | 
			
		||||
 | 
			
		||||
html-parse-stringify2@2.0.1:
 | 
			
		||||
  version "2.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
 | 
			
		||||
  integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
 | 
			
		||||
  dependencies:
 | 
			
		||||
    void-elements "^2.0.1"
 | 
			
		||||
 | 
			
		||||
html-webpack-plugin@4.0.0-beta.11:
 | 
			
		||||
  version "4.0.0-beta.11"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz#3059a69144b5aecef97708196ca32f9e68677715"
 | 
			
		||||
@ -4423,6 +4532,20 @@ hyphenate-style-name@^1.0.3:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48"
 | 
			
		||||
  integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==
 | 
			
		||||
 | 
			
		||||
i18next-browser-languagedetector@^5.0.0:
 | 
			
		||||
  version "5.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-5.0.0.tgz#9e946ed2ea5514a636913fe020a32455e82946e3"
 | 
			
		||||
  integrity sha512-ekeKbRvTOsSOABSEPHFqyb6Q37JagZXjkISgQKHP84t/VZRW/B3FMVz+tBNQDVdZLsEaOe8fuJpeZsw2TvWeVQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.5.5"
 | 
			
		||||
 | 
			
		||||
i18next@^19.6.0:
 | 
			
		||||
  version "19.6.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/i18next/-/i18next-19.6.0.tgz#3881b8e476e494dcdadcc8983e594080417fd82e"
 | 
			
		||||
  integrity sha512-t+pA7iN2WtwS1UQc4PFKHDIO4HYZIl2Wo8UC8gqt70Q1qY50FflAF5vV4IbQEqy4DuK3I9wv3BL1PMvkk238WA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.10.1"
 | 
			
		||||
 | 
			
		||||
iconv-lite@0.4.24, iconv-lite@^0.4.24:
 | 
			
		||||
  version "0.4.24"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
 | 
			
		||||
@ -4905,6 +5028,11 @@ is-wsl@^2.1.1:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    is-docker "^2.0.0"
 | 
			
		||||
 | 
			
		||||
isarray@0.0.1:
 | 
			
		||||
  version "0.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
 | 
			
		||||
  integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
 | 
			
		||||
 | 
			
		||||
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
 | 
			
		||||
  version "1.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
 | 
			
		||||
@ -5301,7 +5429,7 @@ loglevel@^1.6.6:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171"
 | 
			
		||||
  integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==
 | 
			
		||||
 | 
			
		||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
 | 
			
		||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
 | 
			
		||||
  version "1.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
 | 
			
		||||
  integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
 | 
			
		||||
@ -5375,6 +5503,15 @@ map-visit@^1.0.0:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    object-visit "^1.0.0"
 | 
			
		||||
 | 
			
		||||
material-ui-dropzone@^3.3.0:
 | 
			
		||||
  version "3.3.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/material-ui-dropzone/-/material-ui-dropzone-3.3.0.tgz#5adb64e7ad71953eb29c7d0616b0b693904eb412"
 | 
			
		||||
  integrity sha512-PBOj5IiGbLxEgNybO28xo381/qe0tMF55U715xGs8XLoyfjOFIoC29u4UL3+SWPYsaP/JIFwR4JW+h32xHugIg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.4.4"
 | 
			
		||||
    clsx "^1.0.2"
 | 
			
		||||
    react-dropzone "^10.2.1"
 | 
			
		||||
 | 
			
		||||
md5.js@^1.3.4:
 | 
			
		||||
  version "1.3.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
 | 
			
		||||
@ -5522,6 +5659,14 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
 | 
			
		||||
  integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
 | 
			
		||||
 | 
			
		||||
mini-create-react-context@^0.4.0:
 | 
			
		||||
  version "0.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz#df60501c83151db69e28eac0ef08b4002efab040"
 | 
			
		||||
  integrity sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.5.5"
 | 
			
		||||
    tiny-warning "^1.0.3"
 | 
			
		||||
 | 
			
		||||
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
 | 
			
		||||
  version "1.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
 | 
			
		||||
@ -6220,6 +6365,13 @@ path-to-regexp@0.1.7:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
 | 
			
		||||
  integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
 | 
			
		||||
 | 
			
		||||
path-to-regexp@^1.7.0:
 | 
			
		||||
  version "1.8.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
 | 
			
		||||
  integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    isarray "0.0.1"
 | 
			
		||||
 | 
			
		||||
path-type@^1.0.0:
 | 
			
		||||
  version "1.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
 | 
			
		||||
@ -7229,16 +7381,73 @@ react-dom@^16.13.1:
 | 
			
		||||
    prop-types "^15.6.2"
 | 
			
		||||
    scheduler "^0.19.1"
 | 
			
		||||
 | 
			
		||||
react-dropzone@^10.2.1:
 | 
			
		||||
  version "10.2.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-10.2.2.tgz#67b4db7459589a42c3b891a82eaf9ade7650b815"
 | 
			
		||||
  integrity sha512-U5EKckXVt6IrEyhMMsgmHQiWTGLudhajPPG77KFSvgsMqNEHSyGpqWvOMc5+DhEah/vH4E1n+J5weBNLd5VtyA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    attr-accept "^2.0.0"
 | 
			
		||||
    file-selector "^0.1.12"
 | 
			
		||||
    prop-types "^15.7.2"
 | 
			
		||||
 | 
			
		||||
react-error-overlay@^6.0.7:
 | 
			
		||||
  version "6.0.7"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
 | 
			
		||||
  integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==
 | 
			
		||||
 | 
			
		||||
react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1:
 | 
			
		||||
react-i18next@^11.7.0:
 | 
			
		||||
  version "11.7.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.7.0.tgz#f27c4c237a274e007a48ac1210db83e33719908b"
 | 
			
		||||
  integrity sha512-8tvVkpuxQlubcszZON+jmoCgiA9gCZ74OAYli9KChPhETtq8pJsANBTe9KRLRLmX3ubumgvidURWr0VvKz1tww==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.3.1"
 | 
			
		||||
    html-parse-stringify2 "2.0.1"
 | 
			
		||||
 | 
			
		||||
react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.9.0:
 | 
			
		||||
  version "16.13.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
 | 
			
		||||
  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
 | 
			
		||||
 | 
			
		||||
react-redux@^7.2.0:
 | 
			
		||||
  version "7.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d"
 | 
			
		||||
  integrity sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.5.5"
 | 
			
		||||
    hoist-non-react-statics "^3.3.0"
 | 
			
		||||
    loose-envify "^1.4.0"
 | 
			
		||||
    prop-types "^15.7.2"
 | 
			
		||||
    react-is "^16.9.0"
 | 
			
		||||
 | 
			
		||||
react-router-dom@^5.2.0:
 | 
			
		||||
  version "5.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
 | 
			
		||||
  integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.1.2"
 | 
			
		||||
    history "^4.9.0"
 | 
			
		||||
    loose-envify "^1.3.1"
 | 
			
		||||
    prop-types "^15.6.2"
 | 
			
		||||
    react-router "5.2.0"
 | 
			
		||||
    tiny-invariant "^1.0.2"
 | 
			
		||||
    tiny-warning "^1.0.0"
 | 
			
		||||
 | 
			
		||||
react-router@5.2.0:
 | 
			
		||||
  version "5.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293"
 | 
			
		||||
  integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/runtime" "^7.1.2"
 | 
			
		||||
    history "^4.9.0"
 | 
			
		||||
    hoist-non-react-statics "^3.1.0"
 | 
			
		||||
    loose-envify "^1.3.1"
 | 
			
		||||
    mini-create-react-context "^0.4.0"
 | 
			
		||||
    path-to-regexp "^1.7.0"
 | 
			
		||||
    prop-types "^15.6.2"
 | 
			
		||||
    react-is "^16.6.0"
 | 
			
		||||
    tiny-invariant "^1.0.2"
 | 
			
		||||
    tiny-warning "^1.0.0"
 | 
			
		||||
 | 
			
		||||
react-transition-group@^4.0.0, react-transition-group@^4.4.0:
 | 
			
		||||
  version "4.4.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
 | 
			
		||||
@ -7328,6 +7537,24 @@ redent@^1.0.0:
 | 
			
		||||
    indent-string "^2.1.0"
 | 
			
		||||
    strip-indent "^1.0.1"
 | 
			
		||||
 | 
			
		||||
redux-devtools-extension@^2.13.8:
 | 
			
		||||
  version "2.13.8"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz#37b982688626e5e4993ff87220c9bbb7cd2d96e1"
 | 
			
		||||
  integrity sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg==
 | 
			
		||||
 | 
			
		||||
redux-persist@*, redux-persist@^6.0.0:
 | 
			
		||||
  version "6.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
 | 
			
		||||
  integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==
 | 
			
		||||
 | 
			
		||||
redux@*, redux@^4.0.0, redux@^4.0.5:
 | 
			
		||||
  version "4.0.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
 | 
			
		||||
  integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    loose-envify "^1.4.0"
 | 
			
		||||
    symbol-observable "^1.2.0"
 | 
			
		||||
 | 
			
		||||
regenerate-unicode-properties@^8.2.0:
 | 
			
		||||
  version "8.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
 | 
			
		||||
@ -7512,6 +7739,11 @@ resolve-from@^4.0.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
 | 
			
		||||
  integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
 | 
			
		||||
 | 
			
		||||
resolve-pathname@^3.0.0:
 | 
			
		||||
  version "3.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
 | 
			
		||||
  integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
 | 
			
		||||
 | 
			
		||||
resolve-url@^0.2.1:
 | 
			
		||||
  version "0.2.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
 | 
			
		||||
@ -8307,6 +8539,11 @@ svgo@^1.0.0:
 | 
			
		||||
    unquote "~1.1.1"
 | 
			
		||||
    util.promisify "~1.0.0"
 | 
			
		||||
 | 
			
		||||
symbol-observable@^1.2.0:
 | 
			
		||||
  version "1.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
 | 
			
		||||
  integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
 | 
			
		||||
 | 
			
		||||
tapable@^1.0.0, tapable@^1.1.3:
 | 
			
		||||
  version "1.1.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
 | 
			
		||||
@ -8380,7 +8617,12 @@ timsort@^0.3.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
 | 
			
		||||
  integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
 | 
			
		||||
 | 
			
		||||
tiny-warning@^1.0.2:
 | 
			
		||||
tiny-invariant@^1.0.2:
 | 
			
		||||
  version "1.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
 | 
			
		||||
  integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
 | 
			
		||||
 | 
			
		||||
tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3:
 | 
			
		||||
  version "1.0.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
 | 
			
		||||
  integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
 | 
			
		||||
@ -8724,6 +8966,11 @@ validate-npm-package-license@^3.0.1:
 | 
			
		||||
    spdx-correct "^3.0.0"
 | 
			
		||||
    spdx-expression-parse "^3.0.0"
 | 
			
		||||
 | 
			
		||||
value-equal@^1.0.1:
 | 
			
		||||
  version "1.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
 | 
			
		||||
  integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
 | 
			
		||||
 | 
			
		||||
vary@~1.1.2:
 | 
			
		||||
  version "1.1.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
 | 
			
		||||
@ -8748,6 +8995,11 @@ vm-browserify@^1.0.1:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
 | 
			
		||||
  integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
 | 
			
		||||
 | 
			
		||||
void-elements@^2.0.1:
 | 
			
		||||
  version "2.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
 | 
			
		||||
  integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
 | 
			
		||||
 | 
			
		||||
watchpack-chokidar2@^2.0.0:
 | 
			
		||||
  version "2.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
 | 
			
		||||
@ -9128,7 +9380,15 @@ yallist@^3.0.2:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
 | 
			
		||||
  integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
 | 
			
		||||
 | 
			
		||||
yaml@^1.7.2:
 | 
			
		||||
yaml-loader@^0.6.0:
 | 
			
		||||
  version "0.6.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/yaml-loader/-/yaml-loader-0.6.0.tgz#fe1c48b9f4803dace55a59a1474e790ba6ab1b48"
 | 
			
		||||
  integrity sha512-1bNiLelumURyj+zvVHOv8Y3dpCri0F2S+DCcmps0pA1zWRLjS+FhZQg4o3aUUDYESh73+pKZNI18bj7stpReow==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    loader-utils "^1.4.0"
 | 
			
		||||
    yaml "^1.8.3"
 | 
			
		||||
 | 
			
		||||
yaml@^1.7.2, yaml@^1.8.3:
 | 
			
		||||
  version "1.10.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"
 | 
			
		||||
  integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user