125 lines
4.5 KiB
TypeScript
125 lines
4.5 KiB
TypeScript
import React, { HTMLProps, useEffect } from 'react';
|
|
import { Link, Route, Switch } from "react-router-dom"
|
|
import { route, routes } from "@/routing";
|
|
import { useSelector } from "react-redux";
|
|
import { AppState, isReady } from "@/state/reducer";
|
|
import { 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 '@/styles/header.scss'
|
|
import '@/styles/footer.scss'
|
|
import classNames from "classnames";
|
|
import { EditionActions } from "@/state/actions/edition";
|
|
import { sampleEdition } from "@/provider/dummy/edition";
|
|
import { Edition } from "@/data/edition";
|
|
import { SettingActions } from "@/state/actions/settings";
|
|
import { useDispatch } from "@/state/actions";
|
|
import { getLocale, Locale } from "@/state/reducer/settings";
|
|
import i18n from "@/i18n";
|
|
import moment from "moment";
|
|
import { Container } from "@material-ui/core";
|
|
|
|
const UserMenu = (props: HTMLProps<HTMLUListElement>) => {
|
|
const student = useSelector<AppState, Student>(state => state.student as Student);
|
|
const dispatch = useDispatch();
|
|
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 dispatch = useDispatch();
|
|
|
|
const handleLanguageChange = (language: Locale) => () => {
|
|
dispatch({ type: SettingActions.SetLocale, 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 as Locale) }
|
|
className={ classNames("language-switcher__language", isActive(language) && "language-switcher__language--active") }>
|
|
{ language }
|
|
</Link>
|
|
</li>) }
|
|
</ul>
|
|
}
|
|
|
|
function App() {
|
|
const dispatch = useDispatch();
|
|
const edition = useSelector<AppState, Edition | null>(state => state.edition);
|
|
const { t } = useTranslation();
|
|
const locale = useSelector<AppState, Locale>(state => getLocale(state.settings));
|
|
|
|
useEffect(() => {
|
|
if (!edition) {
|
|
dispatch({ type: EditionActions.Set, edition: sampleEdition });
|
|
}
|
|
})
|
|
|
|
useEffect(() => {
|
|
i18n.changeLanguage(locale);
|
|
document.documentElement.lang = locale;
|
|
moment.locale(locale)
|
|
}, [ locale ])
|
|
|
|
const ready = useSelector(isReady);
|
|
|
|
return <>
|
|
<header className="header">
|
|
<div id="logo" className="header__logo">
|
|
<Link to={ route('home') }>
|
|
<img src="img/pg-logotyp.svg"/>
|
|
</Link>
|
|
</div>
|
|
<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>
|
|
<main id="content">
|
|
{ ready && <Switch>{ routes.map(({ name, content, ...route }) => <Route { ...route } key={ name }>{ content() }</Route>) }</Switch> }
|
|
</main>
|
|
<footer className="footer">
|
|
<Container>
|
|
<div className="footer__copyright">{ t('copyright', { date: moment() }) }</div>
|
|
</Container>
|
|
</footer>
|
|
</>;
|
|
}
|
|
|
|
export default App;
|