updated react-router

This commit is contained in:
Daniel 2021-12-21 17:39:15 -05:00
parent 9dea03a02d
commit d9b3e8213e
16 changed files with 1814 additions and 2039 deletions

3499
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,11 +16,10 @@
"author": "Danude Sandstorm",
"license": "MIT",
"dependencies": {
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@loadable/component": "^5.15.0",
"@mui/icons-material": "^5.0.5",
"@mui/material": "^5.0.6",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@mui/icons-material": "^5.2.5",
"@mui/material": "^5.2.5",
"lokijs": "^1.5.12",
"mobx": "^5.15.7",
"mobx-react": "^6.3.1",
@ -31,36 +30,35 @@
"react-dom": "^16.14.0",
"react-interactive": "^1.1.2",
"react-loadable": "^5.5.0",
"react-onclickoutside": "^6.12.0",
"react-onclickoutside": "^6.12.1",
"react-process-string": "^1.2.0",
"react-router": "^5.2.1",
"react-router-dom": "^5.3.0",
"react-router": "^6.2.1",
"react-router-dom": "^6.2.1",
"tone": "^14.7.77",
"universal-cookie": "^4.0.4",
"whatwg-fetch": "^3.6.2"
},
"devDependencies": {
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.0",
"@babel/node": "^7.16.0",
"@babel/plugin-proposal-class-properties": "^7.16.0",
"@babel/plugin-proposal-decorators": "^7.16.0",
"@babel/plugin-proposal-dynamic-import": "^7.16.0",
"@babel/plugin-proposal-object-rest-spread": "^7.16.0",
"@babel/core": "^7.16.5",
"@babel/node": "^7.16.5",
"@babel/plugin-proposal-class-properties": "^7.16.5",
"@babel/plugin-proposal-decorators": "^7.16.5",
"@babel/plugin-proposal-dynamic-import": "^7.16.5",
"@babel/plugin-proposal-object-rest-spread": "^7.16.5",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-computed-properties": "^7.16.0",
"@babel/plugin-transform-runtime": "^7.16.0",
"@babel/plugin-transform-computed-properties": "^7.16.5",
"@babel/plugin-transform-runtime": "^7.16.5",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.16.0",
"@babel/preset-react": "^7.16.0",
"@babel/preset-typescript": "^7.16.0",
"@babel/register": "^7.16.0",
"@babel/runtime": "^7.16.0",
"@types/chai": "^4.2.22",
"@types/mocha": "^8.2.3",
"@types/react": "^16.14.20",
"@babel/preset-env": "^7.16.5",
"@babel/preset-react": "^7.16.5",
"@babel/preset-typescript": "^7.16.5",
"@babel/register": "^7.16.5",
"@babel/runtime": "^7.16.5",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"@types/react": "^16.14.21",
"@types/react-dom": "^16.9.14",
"@types/react-router-dom": "^5.3.2",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"babel-eslint": "^10.1.0",
@ -69,29 +67,29 @@
"clean-webpack-plugin": "^4.0.0",
"cross-env": "^7.0.3",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.1.1",
"css-minimizer-webpack-plugin": "^3.3.0",
"eslint": "^7.32.0",
"eslint-plugin-babel": "^5.3.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"fsevents": "^2.3.2",
"ignore-styles": "^5.0.1",
"jsdom": "^17.0.0",
"jsdom-global": "^3.0.2",
"mini-css-extract-plugin": "^2.4.4",
"mocha": "^8.4.0",
"postcss": "^8.3.11",
"sass": "^1.43.4",
"sass-loader": "^12.3.0",
"mini-css-extract-plugin": "^2.4.5",
"mocha": "^9.1.3",
"postcss": "^8.4.5",
"sass": "^1.45.0",
"sass-loader": "^12.4.0",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.2.4",
"terser-webpack-plugin": "^5.3.0",
"ts-node": "^10.4.0",
"typescript": "^4.4.4",
"webpack": "^5.61.0",
"typescript": "^4.5.4",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^3.11.2"
"webpack-dev-server": "^3.11.3"
},
"browser": {
"fs": false

View File

@ -1,9 +1,9 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Outlet, Link } from 'react-router-dom';
import API from './SpreadsheetData';
import { Donate } from './Snippets';
export default function Base({ children }) {
export default function Base() {
// Configuration for the language and background
// Images managed in css file
const language = "ENG";
@ -64,7 +64,7 @@ export default function Base({ children }) {
<div className="content-area-right-repeat-y">
<div className="content-area-inner-space">
<div id="player">
{children}
<Outlet />
</div>
</div>
</div>

View File

@ -0,0 +1,12 @@
import React from "react";
import {useLocation, useNavigate} from 'react-router-dom';
const RouteElement = ({ component: RouteComponent, ...props }) => {
const location = useLocation();
const navigate = useNavigate();
return (
<RouteComponent location={location} navigate={navigate} {...props} />
);
};
export default RouteElement;

View File

@ -1,35 +1,36 @@
import React from 'react';
import { useLocation } from 'react-router';
import s from '../../styles/app.style';
export * from './_icons';
export * from './_text';
export function UnderConstruction(props) {
export function UnderConstruction() {
return (
<p style={s.p}>This page is currently under construction</p>
);
}
export function PageNotFound(props) {
export function PageNotFound() {
const { pathname } = useLocation();
return (
<p style={s.p}>
404 route not found - {s.code(props.location.pathname)}
404 route not found - {s.code(pathname)}
</p>
);
}
export function Loading(props) {
export function Loading() {
return (<span>Loading...</span>);
}
export function Splash(props) {
const { image } = props;
export function Splash({ image }) {
return (
<div style={{ position: 'absolute', top: '0', left: '0', right: '0', bottom: '0', backgroundImage: 'url(\'' + image + '\') no-repeat center', backgroundSize: 'cover' }} />
);
}
export function Donate(props) {
export function Donate() {
return (
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick" />
@ -40,7 +41,7 @@ export function Donate(props) {
);
}
export function SearchButton(props) {
export function SearchButton() {
return (<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="magnifying-glass"><g fillRule="evenodd"><path d="M21.747 20.524l-4.872-4.871a.864.864 0 1 0-1.222 1.222l4.871 4.872a.864.864 0 1 0 1.223-1.223z"></path><path d="M3.848 10.763a6.915 6.915 0 0 1 6.915-6.915 6.915 6.915 0 0 1 6.915 6.915 6.915 6.915 0 0 1-6.915 6.915 6.915 6.915 0 0 1-6.915-6.915zm-1.729 0a8.643 8.643 0 0 0 8.644 8.644 8.643 8.643 0 0 0 8.644-8.644 8.643 8.643 0 0 0-8.644-8.644 8.643 8.643 0 0 0-8.644 8.644z"></path></g>
</svg>);
}

View File

@ -7,7 +7,7 @@ import {
Typography, useMediaQuery, useTheme, Zoom
} from '@mui/material';
import React, { FormEvent, useEffect, useMemo, useReducer, useRef, useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { useNavigate, useLocation } from 'react-router-dom';
import search_api from '../../collection/search/search';
import { ElementIcon, TribeIcon } from '../../Snippets';
import API, { sets } from '../../SpreadsheetData/API';
@ -71,9 +71,9 @@ const expandReducer = (state: typeof initExpand, newState: Partial<typeof initEx
function Search ({ setContent, setInfo }) {
const theme = useTheme();
const history = useHistory();
const navigate = useNavigate();
const location = useLocation();
const prevLocation = useRef<any>(location);
const prevSearch = useRef(location.search);
const [input, dispatchInput] = useReducer(inputReducer, initInput, (input) => parseQuery(input, location));
const [expand, dispatchExpand] = useReducer(expandReducer, initExpand, parseExpand);
const [loaded, setLoaded] = useState(false);
@ -92,12 +92,11 @@ function Search ({ setContent, setInfo }) {
}, []);
useEffect(() => {
if (location != prevLocation.current) {
prevLocation.current = location;
if (location.search != prevSearch.current) {
prevSearch.current = location.search;
dispatchInput(parseQuery(initInput, location));
}
}, [input, location]);
}, [location.search]);
const cleanInput = () => {
dispatchInput({ ...initInput });
@ -107,7 +106,10 @@ function Search ({ setContent, setInfo }) {
if (event) {
event.preventDefault();
event.stopPropagation();
updateQuery(input, history);
const queryString = updateQuery(input);
prevSearch.current = `?${queryString}`;
navigate(`/collection/?${queryString}`);
setOpen(false);
}
@ -138,7 +140,7 @@ function Search ({ setContent, setInfo }) {
const handleClose = () => {setOpen(false)};
const generate = (type: string, row: boolean, label: (item: string) => React.ReactNode) => {
const generate = (type: string, row: boolean, label: (item: string) => string | number | React.ReactElement) => {
return Object.keys(input[type]).map((item, i) => (
<FormControlLabel style={{ display: "inline" }} key={i} control={
<Checkbox checked={input[type][item]} onChange={handleChange(item, type)} />
@ -398,7 +400,7 @@ const parseQuery = (init: typeof initInput, location) => {
return input;
};
const updateQuery = (input, history) => {
const updateQuery = (input) => {
let queryString = "";
queryList.forEach(query => {
@ -437,8 +439,7 @@ const updateQuery = (input, history) => {
// Strip trailing &
queryString = queryString.replace(/\&$/, '');
// Push to URL
history.push(`/collection/?${queryString}`);
return queryString;
};
const parseExpand = (init: typeof initExpand) => {

View File

@ -1,35 +1,25 @@
import React, { useEffect } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import loadable from '@loadable/component';
import React, { useEffect, lazy, Suspense } from 'react';
import { Route, Routes, Navigate, useLocation } from 'react-router-dom';
import RouteElement from './RouteElement';
import useCheckMobileScreen from './_hooks/useCheckMobileScreen';
import { PageNotFound, UnderConstruction, Loading } from './Snippets';
import Create from './create';
import Home from './home';
import Base from './BaseStylesWrapper';
const EnterTheCode = loadable(
() => import('./entercode'),
{ fallback: <Loading /> }
);
const Home = loadable(
() => import('./home'),
{ fallback: <Loading /> }
);
const Portal = loadable(
() => import('./portal'),
{ fallback: <Loading /> }
);
const Collection = loadable(
() => import('./collection'),
{ fallback: <Loading /> }
);
const EnterTheCode = lazy(() => import('./entercode'));
const MobileCollection = loadable(
() => import('./_mobile/collection')
);
const Portal = lazy(() => import('./portal'));
const Collection = lazy(() => import('./collection'));
const MobileCollection = lazy(() => import('./_mobile/collection'));
const RedirectBeta = () => {
const { pathname } = useLocation();
return <Navigate to={pathname.replace("/beta", "")} replace />;
};
export default function App() {
const isMobile = useCheckMobileScreen();
@ -43,23 +33,31 @@ export default function App() {
}, [isMobile]);
return (
<Switch>
<Route path="/beta/collection" component={Collection} />
<Route path="/beta">
{({ location }) => <Redirect to={location.pathname.replace("/beta", "")} /> }
</Route>
{isMobile && <Route path="/collection" component={MobileCollection} />}
<Routes>
<Route path="/beta/collection" element={
<Suspense fallback={<Loading />}><Collection /></Suspense>
} />
<Route path="/beta/*" element={<RedirectBeta />} />
{isMobile && <Route path="/collection" element={
<Suspense fallback={<Loading />}><MobileCollection /></Suspense>
} />}
{/* Normal Routes */}
<Base>
<Route exact path="/" component={Home} />
<Route path="/PageNotFound" component={PageNotFound} />
<Route path="/UnderConstruction" component={UnderConstruction} />
<Route path="/EnterTheCode" component={EnterTheCode} />
<Route path="/create" component={Create} />
<Route path="/collection" component={Collection} />
<Route path="/portal" component={Portal} />
</Base>
</Switch>
<Route path="/" element={<Base />} >
<Route index element={<Home />} />
<Route path="PageNotFound" element={<PageNotFound />} />
<Route path="UnderConstruction" element={<UnderConstruction />} />
<Route path="EnterTheCode/*" element={
<Suspense fallback={<Loading />}><EnterTheCode /></Suspense>
} />
<Route path="create/*" element={<Create />} />
<Route path="collection/*" element={
<Suspense fallback={<Loading />}><RouteElement component={Collection} /></Suspense>
} />
<Route path="portal/*" element={
<Suspense fallback={<Loading />}><Portal /></Suspense>
} />
</Route>
</Routes>
);
}

View File

@ -158,7 +158,7 @@ export default class SearchCollection extends React.Component {
queryString = queryString.replace(/\&$/, '');
// Push to URL
this.props.history.push('/collection/?'+(queryString));
this.props.navigate('/collection/?'+(queryString));
}
reset = (event) => {

View File

@ -8,7 +8,7 @@ import MugicPlay from '../../mugicplayer/playbutton.tsx';
export default class Mugic extends React.Component {
render() {
const { card, history } = this.props;
const { card } = this.props;
const mugicCounters = [];
if (card.gsx$cost == 0) {

View File

@ -1,13 +1,9 @@
import React from 'react';
import { observer, inject } from 'mobx-react';
@inject((stores, props, context) => props) @observer
export default class Create extends React.Component {
render() {
return (<div><span>This page is not yet available</span>
</div>);
}
export default function Create () {
return (
<div>
<span>This page is not yet available</span>
</div>
);
}

View File

@ -1,24 +1,14 @@
import React from 'react';
import { observer, inject } from 'mobx-react';
import { Route, Switch } from 'react-router-dom';
import { Route, Routes } from 'react-router-dom';
import EnterTheCode from './EnterTheCode';
import PackSimulator from './PackSimulator';
import './packs.scss';
@inject((stores, props, context) => props) @observer
export default class Base extends React.Component {
render() {
const { match } = this.props;
return (
<div>
<Switch>
<Route exact path={match.url} component={EnterTheCode} />
<Route path={`${match.url}/PackSimulator`} component={PackSimulator} />
</Switch>
</div>
);
}
export default function Base () {
return (
<Routes>
<Route path="/" element={<EnterTheCode />} />
<Route path="PackSimulator" element={<PackSimulator />} />
</Routes>
);
}

View File

@ -2,7 +2,6 @@ import React from 'react';
import { Link } from 'react-router-dom';
import { Donate } from '../Snippets';
import "./home.scss";
import { observable } from 'mobx';
const GithubLink = () => (
<a

View File

@ -2,7 +2,7 @@ import loki from 'lokijs';
import { observable } from 'mobx';
import { inject, observer } from 'mobx-react';
import React from 'react';
import { Route, Link } from 'react-router-dom';
import { Routes, Route, Link } from 'react-router-dom';
import { Loading } from '../../Snippets';
import API from '../../SpreadsheetData';
@ -82,8 +82,10 @@ export default class Tribes extends React.Component {
return (<div className="entry tribe">
<div className="entry_content">
<Route path={`${this.props.match.url}/Creatures/:card`} component={Creature} />
<Route path={`${this.props.match.url}/Mugic/:card`} component={Mugic} />
<Routes>
<Route path={`Creatures/:card`} element={<Creature {...this.props} />} />
<Route path={`Mugic/:card`} element={<Mugic {...this.props} />} />
</Routes>
</div>
<div className="cat_title"><Link to={`/portal/${tribe}`}>{tribe}</Link></div>
<div className="entry_nav">{bottom_nav}</div>

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Link, Route } from 'react-router-dom';
import { Link, Route, Routes } from 'react-router-dom';
import { observable } from 'mobx';
import { observer, inject } from 'mobx-react';
@ -54,13 +54,13 @@ export default class Category extends React.Component {
if (tribe) {
if (path.length > 4) {
base_path = false;
top_content = <Route path={`${this.props.match.url}/${tribe}/:card`} component={this.props.component} />;
top_content = <Route path={`${tribe}/:card`} element={React.cloneElement(this.props.component, this.props)} />;
}
}
else {
if (path.length > 3) {
base_path = false;
top_content = <Route path={`${this.props.match.url}/:card`} component={this.props.component} />;
top_content = <Route path={`:card`} element={React.cloneElement(this.props.component, this.props)} />;
}
}
@ -88,7 +88,7 @@ export default class Category extends React.Component {
else {
if (path.length > 3) {
base_path = false;
top_content = (<Route path={`${this.props.match.url}/:card`} component={this.props.component} />);
top_content = (<Route path={`:card`} element={React.cloneElement(this.props.component, this.props)} />);
}
cat_title = this.props.type;
@ -109,7 +109,7 @@ export default class Category extends React.Component {
return (
<div className={`entry ${type}`}>
<div className="entry_content">{top_content}</div>
<div className="entry_content"><Routes>{top_content}</Routes></div>
<div className="cat_title"><Link to={`/portal/${this.props.type}`}>{cat_title}</Link></div>
<div className="entry_nav">{bottom_nav}</div>
</div>

View File

@ -32,7 +32,7 @@ export default class SearchPortal extends React.Component {
event.preventDefault();
event.stopPropagation();
this.props.history.push('/portal/Search/?'+encodeURIComponent(this.query));
this.props.navigate('/portal/Search/?'+encodeURIComponent(this.query));
this.input = this.query;
}
}

View File

@ -1,9 +1,8 @@
import React from 'react';
import { observable } from "mobx";
import { observer, inject } from 'mobx-react';
import { Route, Switch } from 'react-router-dom';
import React, { useEffect } from 'react';
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import API from '../SpreadsheetData';
import RouteElement from '../RouteElement';
import Header from './Header';
import Home from './Home';
@ -19,36 +18,52 @@ import Mugic from './Single/Mugic';
import './portal.scss';
@inject((stores, props, context) => props) @observer
export default class Base extends React.Component {
export default function Base () {
const location = useLocation();
const navigate = useNavigate();
componentDidUpdate() {
useEffect(() => {
window.scrollTo({
top: 220,
left: 0,
behavior: 'smooth'
});
}
}, [location.pathname]);
render() {
const { url } = this.props.match;
const tribes = API.tribes.map((tribe) => (
<Route key={tribe} path={`${tribe}/*`} element={
<RouteElement component={Tribes} />
} />
));
return (
<div className="portal">
<Header />
<Routes>
<Route path="/" element={
<RouteElement component={Home} />
}/>
<Route path="Search" element={
<RouteElement component={Search} />
}/>
<Route path="Attacks/*" element={
<Category type="Attacks" component={<Attack />} {...({ location, navigate })} />
} />
<Route path="Battlegear/*" element={
<Category type="Battlegear" component={<Battlegear />} {...({ location, navigate })} />
}/>
<Route path="Creatures/*" element={
<Category type="Creatures" component={<Creature />} {...({ location, navigate })} />
}/>
<Route path="Locations/*" element={
<Category type="Locations" component={<Location />} {...({ location, navigate })} />
}/>
<Route path="Mugic/*" element={
<Category type="Mugic" component={<Mugic />} {...({ location, navigate })} />
}/>
{tribes}
</Routes>
</div>
);
const tribes = API.tribes.map((tribe, i) => (<Route key={i} path={`${url}/${tribe}`} component={Tribes} />));
return (
<div className="portal">
<Header />
<Switch>
<Route exact path={url} component={Home} />
<Route path={`${url}/Search`} component={Search} />
<Route path={`${url}/Attacks`} render={(props) => <Category {...props} type="Attacks" component={Attack} />} />
<Route path={`${url}/Battlegear`} render={(props) => <Category {...props} type="Battlegear" component={Battlegear} />} />
<Route path={`${url}/Creatures`} render={(props) => <Category {...props} type="Creatures" component={Creature} />} />
<Route path={`${url}/Locations`} render={(props) => <Category {...props} type="Locations" component={Location} />} />
<Route path={`${url}/Mugic`} render={(props) => <Category {...props} type="Mugic" component={Mugic} />} />
{tribes}
</Switch>
</div>
);
}
}