2021-09-24 02:35:58 +09:00
|
|
|
import React from 'react';
|
2021-09-01 20:16:26 +09:00
|
|
|
import { BrowserRouter, Link, Route, Switch, useLocation } from 'react-router-dom';
|
2021-09-04 22:19:35 +09:00
|
|
|
import { Provider } from 'react-redux';
|
2021-09-14 14:28:40 +09:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2021-09-24 02:27:46 +09:00
|
|
|
import i18n from 'i18next';
|
|
|
|
import { initReactI18next } from 'react-i18next';
|
2021-09-01 20:06:33 +09:00
|
|
|
|
|
|
|
import { IndexPage } from './pages';
|
|
|
|
import { RankingPage } from './pages/ranking';
|
|
|
|
import { Header } from './components/Header';
|
2021-09-04 18:24:11 +09:00
|
|
|
import { TermPage } from './pages/term';
|
2021-09-24 02:35:58 +09:00
|
|
|
import { store } from './store';
|
2021-09-14 04:11:43 +09:00
|
|
|
import { ModalComponent } from './Modal';
|
2021-09-24 02:35:58 +09:00
|
|
|
import { useTheme } from './misc/theme';
|
2021-09-24 02:27:46 +09:00
|
|
|
import { getBrowserLanguage, resources } from './langs';
|
|
|
|
import { LOCALSTORAGE_KEY_LANG } from './const';
|
2021-09-01 20:06:33 +09:00
|
|
|
|
|
|
|
import 'xeltica-ui/dist/css/xeltica-ui.min.css';
|
|
|
|
import './style.scss';
|
|
|
|
|
2021-09-24 02:27:46 +09:00
|
|
|
document.body.classList.add('dark');
|
|
|
|
|
|
|
|
if (!localStorage[LOCALSTORAGE_KEY_LANG]) {
|
|
|
|
localStorage[LOCALSTORAGE_KEY_LANG] = getBrowserLanguage();
|
|
|
|
}
|
|
|
|
|
|
|
|
i18n
|
|
|
|
.use(initReactI18next)
|
|
|
|
.init({
|
|
|
|
resources,
|
|
|
|
lng: localStorage[LOCALSTORAGE_KEY_LANG],
|
|
|
|
interpolation: {
|
|
|
|
escapeValue: false // react already safes from xss
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-09-01 20:06:33 +09:00
|
|
|
const AppInner : React.VFC = () => {
|
|
|
|
const $location = useLocation();
|
2021-09-04 22:19:35 +09:00
|
|
|
|
2021-09-24 02:35:58 +09:00
|
|
|
useTheme();
|
2021-09-14 04:11:43 +09:00
|
|
|
|
2021-09-14 14:28:40 +09:00
|
|
|
const {t} = useTranslation();
|
|
|
|
|
2021-09-24 02:18:31 +09:00
|
|
|
const error = (window as any).__misshaialert?.error;
|
|
|
|
|
|
|
|
return error ? (
|
|
|
|
<div className="container">
|
|
|
|
<Header hasTopLink />
|
|
|
|
<div className="xarticle">
|
|
|
|
<h1>{t('error')}</h1>
|
|
|
|
<p>{t('_error.sorry')}</p>
|
|
|
|
<p>
|
|
|
|
{t('_error.additionalInfo')}
|
|
|
|
{t(`_error.${error}`)}
|
|
|
|
</p>
|
|
|
|
<Link to="/" onClick={() => (window as any).__misshaialert.error = null}>{t('retry')}</Link>
|
2021-09-01 20:06:33 +09:00
|
|
|
</div>
|
2021-09-24 02:18:31 +09:00
|
|
|
</div>
|
|
|
|
) : (
|
|
|
|
<div className="container">
|
|
|
|
{$location.pathname !== '/' && <Header hasTopLink />}
|
|
|
|
<Switch>
|
|
|
|
<Route exact path="/" component={IndexPage} />
|
|
|
|
<Route exact path="/ranking" component={RankingPage} />
|
|
|
|
<Route exact path="/term" component={TermPage} />
|
|
|
|
</Switch>
|
|
|
|
<footer className="text-center pa-5">
|
|
|
|
<p>(C)2020-2021 Xeltica</p>
|
|
|
|
<p><Link to="/term">{t('termsOfService')}</Link></p>
|
|
|
|
</footer>
|
|
|
|
<ModalComponent />
|
|
|
|
</div>
|
2021-09-01 20:06:33 +09:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const App: React.VFC = () => (
|
2021-09-04 22:19:35 +09:00
|
|
|
<Provider store={store}>
|
|
|
|
<BrowserRouter>
|
|
|
|
<AppInner />
|
|
|
|
</BrowserRouter>
|
|
|
|
</Provider>
|
2021-09-01 20:06:33 +09:00
|
|
|
);
|