fix: Transition the drawer to redux
This commit is contained in:
parent
2cadcec370
commit
2f7e468285
37
package-lock.json
generated
37
package-lock.json
generated
@ -7880,8 +7880,12 @@
|
||||
"lodash": {
|
||||
"version": "4.17.10",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||
},
|
||||
"lodash-es": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz",
|
||||
"integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q=="
|
||||
},
|
||||
"lodash.clone": {
|
||||
"version": "4.5.0",
|
||||
@ -10521,6 +10525,19 @@
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "5.0.7",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz",
|
||||
"integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^2.5.0",
|
||||
"invariant": "^2.0.0",
|
||||
"lodash": "^4.17.5",
|
||||
"lodash-es": "^4.17.5",
|
||||
"loose-envify": "^1.1.0",
|
||||
"prop-types": "^15.6.0"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
|
||||
@ -10691,6 +10708,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"redux": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.0.tgz",
|
||||
"integrity": "sha512-NnnHF0h0WVE/hXyrB6OlX67LYRuaf/rJcbWvnHHEPCF/Xa/AZpwhs/20WyqzQae5x4SD2F9nPObgBh2rxAgLiA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"symbol-observable": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
|
||||
|
@ -14,7 +14,9 @@
|
||||
"@material-ui/icons": "^2.0.3",
|
||||
"react": "^16.4.2",
|
||||
"react-dom": "^16.4.2",
|
||||
"react-router-dom": "^4.3.1"
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"redux": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^23.3.2",
|
||||
|
15
src/actions/index.ts
Normal file
15
src/actions/index.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export const SET_DRAWER = "SET_DRAWER";
|
||||
export function setDrawer(state: boolean) {
|
||||
return {
|
||||
type: SET_DRAWER,
|
||||
show: state,
|
||||
};
|
||||
};
|
||||
|
||||
export const SET_DRAWER_BUTTON = "SET_DRAWER_BUTTON";
|
||||
export function setDrawerButton(state: boolean) {
|
||||
return {
|
||||
type: SET_DRAWER_BUTTON,
|
||||
show: state,
|
||||
};
|
||||
};
|
146
src/components/Drawer.tsx
Normal file
146
src/components/Drawer.tsx
Normal file
@ -0,0 +1,146 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import AppBar from "@material-ui/core/AppBar";
|
||||
import Toolbar from "@material-ui/core/Toolbar";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import SwipeableDrawer from "@material-ui/core/SwipeableDrawer";
|
||||
import List from "@material-ui/core/List";
|
||||
import ListItem from "@material-ui/core/ListItem";
|
||||
import ListItemIcon from "@material-ui/core/ListItemIcon";
|
||||
import ListItemText from "@material-ui/core/ListItemText";
|
||||
import Divider from "@material-ui/core/Divider";
|
||||
import Avatar from "@material-ui/core/Avatar";
|
||||
import MenuIcon from "@material-ui/icons/Menu";
|
||||
import SettingsIcon from "@material-ui/icons/Settings";
|
||||
import PersonIcon from "@material-ui/icons/Person";
|
||||
import InfoIcon from "@material-ui/icons/Info";
|
||||
import HomeIcon from "@material-ui/icons/Home";
|
||||
import BookIcon from "@material-ui/icons/Book";
|
||||
import ViewWeekIcon from "@material-ui/icons/ViewWeek";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
showButton: boolean;
|
||||
authenticated: boolean;
|
||||
setDrawer: (state: boolean) => void;
|
||||
};
|
||||
|
||||
export default class Drawer extends React.Component<IProps> {
|
||||
openDrawer = () => {
|
||||
this.props.setDrawer(true);
|
||||
}
|
||||
closeDrawer = () => {
|
||||
this.props.setDrawer(false);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<AppBar position="static">
|
||||
<Toolbar>
|
||||
{
|
||||
(this.props.authenticated && this.props.showButton) ? (
|
||||
<IconButton
|
||||
color="inherit"
|
||||
onClick={this.openDrawer}>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
) : undefined
|
||||
}
|
||||
<Typography className="flex" variant="title" color="inherit">
|
||||
Lateinicus
|
||||
</Typography>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<SwipeableDrawer
|
||||
anchor="left"
|
||||
open={this.props.open}
|
||||
onClose={this.closeDrawer}
|
||||
onOpen={this.openDrawer}>
|
||||
<List component="nav">
|
||||
<ListItem>
|
||||
<Avatar alt="{Username}" style={{ width: 80, height: 80 }} src="https://avatarfiles.alphacoders.com/105/105250.jpg" />
|
||||
<ListItemText primary={"{{ PLACEHOLDER }}"} />
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem button>
|
||||
<ListItemIcon>
|
||||
<PersonIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Profil" />
|
||||
</ListItem>
|
||||
<ListItem button>
|
||||
<ListItemIcon>
|
||||
<SettingsIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Einstellungen" />
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem
|
||||
component={Link}
|
||||
to="/dashboard"
|
||||
onClick={this.closeDrawer}
|
||||
button>
|
||||
<ListItemIcon>
|
||||
<HomeIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Dashboard" />
|
||||
</ListItem>
|
||||
<ListItem
|
||||
component={Link}
|
||||
to="/review/queue"
|
||||
onClick={this.closeDrawer}
|
||||
button>
|
||||
<ListItemIcon>
|
||||
<BookIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>
|
||||
Vokabeln üben
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
component={Link}
|
||||
to="/levelList"
|
||||
onClick={this.closeDrawer}
|
||||
button>
|
||||
<ListItemIcon>
|
||||
<ViewWeekIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>
|
||||
Levelübersicht
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem button onClick={() => {
|
||||
// Remove the auth token from the SessionStorage
|
||||
// window.sessionStorage.removeItem("authKey");
|
||||
// TODO: Perform logout
|
||||
}}>
|
||||
<ListItemText>
|
||||
Abmelden
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem button onClick={() => window.location = "https://gitlab.com/Polynomdivision/Lateinicus/tree/master"}>
|
||||
<ListItemIcon>
|
||||
<InfoIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Über" />
|
||||
</ListItem>
|
||||
</List>
|
||||
</SwipeableDrawer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
@ -1,25 +1,6 @@
|
||||
import * as React from "react";
|
||||
|
||||
import AppBar from "@material-ui/core/AppBar";
|
||||
import Toolbar from "@material-ui/core/Toolbar";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import SwipeableDrawer from "@material-ui/core/SwipeableDrawer";
|
||||
import List from "@material-ui/core/List";
|
||||
import ListItem from "@material-ui/core/ListItem";
|
||||
import ListItemIcon from "@material-ui/core/ListItemIcon";
|
||||
import ListItemText from "@material-ui/core/ListItemText";
|
||||
import Divider from "@material-ui/core/Divider";
|
||||
import Avatar from "@material-ui/core/Avatar";
|
||||
import MenuIcon from "@material-ui/icons/Menu";
|
||||
import SettingsIcon from "@material-ui/icons/Settings";
|
||||
import PersonIcon from "@material-ui/icons/Person";
|
||||
import InfoIcon from "@material-ui/icons/Info";
|
||||
import HomeIcon from "@material-ui/icons/Home";
|
||||
import BookIcon from "@material-ui/icons/Book";
|
||||
import ViewWeekIcon from "@material-ui/icons/ViewWeek";
|
||||
|
||||
import { BrowserRouter, Route, Redirect, Link } from "react-router-dom";
|
||||
import { BrowserRouter, Route, Redirect } from "react-router-dom";
|
||||
|
||||
import AuthRoute from "../security/AuthRoute";
|
||||
|
||||
@ -31,6 +12,8 @@ import ReviewPage from "../pages/review";
|
||||
import SummaryPage from "../pages/summary";
|
||||
import WelcomePage from "../pages/intro";
|
||||
|
||||
import Drawer from "../containers/Drawer";
|
||||
|
||||
import { BACKEND_URL } from "../config";
|
||||
|
||||
import { ILevel } from "../models/level";
|
||||
@ -39,20 +22,10 @@ import { IVocab, VocabType } from "../models/vocab";
|
||||
import { IReviewMetadata, ReviewType } from "../models/review";
|
||||
import { IUser } from "../models/user";
|
||||
|
||||
interface IState {
|
||||
loggedIn: boolean;
|
||||
user: IUser | {};
|
||||
|
||||
lastReview: IReviewMetadata;
|
||||
|
||||
drawerOpen: boolean;
|
||||
showDrawerButton: boolean;
|
||||
}
|
||||
|
||||
// TODO: Replace the sessionStorage with localStorage?
|
||||
// TODO: Cache API-Calls
|
||||
// TODO: When mounting without a login, check if the sessionToken is still valid
|
||||
export default class Application extends React.Component<{}, IState> {
|
||||
export default class Application extends React.Component<{}> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
|
||||
@ -61,20 +34,6 @@ export default class Application extends React.Component<{}, IState> {
|
||||
// TODO
|
||||
const loggedIn = authKey !== null;
|
||||
|
||||
// TODO: Fetch the last review
|
||||
this.state = {
|
||||
loggedIn,
|
||||
user: {},
|
||||
|
||||
lastReview: {
|
||||
correct: 0,
|
||||
wrong: 0,
|
||||
},
|
||||
|
||||
drawerOpen: false,
|
||||
showDrawerButton: true,
|
||||
};
|
||||
|
||||
this.login = this.login.bind(this);
|
||||
this.isAuthenticated = this.isAuthenticated.bind(this);
|
||||
}
|
||||
@ -101,7 +60,8 @@ export default class Application extends React.Component<{}, IState> {
|
||||
console.log("STUB: Application::getLastReview");
|
||||
|
||||
// TODO: Actually fetch this
|
||||
return this.state.lastReview;
|
||||
// TODO: Stub
|
||||
return {} as IReviewMetadata;
|
||||
}
|
||||
|
||||
setLastReview = (meta: IReviewMetadata) => {
|
||||
@ -256,7 +216,8 @@ export default class Application extends React.Component<{}, IState> {
|
||||
// Checks whether the user is logged in
|
||||
isAuthenticated() {
|
||||
// TODO: Security?
|
||||
return this.state.loggedIn === true;
|
||||
// TODO: Implement
|
||||
return true;
|
||||
}
|
||||
|
||||
closeDrawer = () => {
|
||||
@ -279,113 +240,7 @@ export default class Application extends React.Component<{}, IState> {
|
||||
return <BrowserRouter
|
||||
basename="/app/">
|
||||
<div className="flex">
|
||||
<AppBar position="static">
|
||||
<Toolbar>
|
||||
{
|
||||
(this.isAuthenticated() && this.state.showDrawerButton) ? (
|
||||
<IconButton
|
||||
color="inherit"
|
||||
onClick={() => this.setState({ drawerOpen: true })}>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
) : undefined
|
||||
}
|
||||
<Typography className="flex" variant="title" color="inherit">
|
||||
Lateinicus
|
||||
</Typography>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<SwipeableDrawer
|
||||
anchor="left"
|
||||
open={this.state.drawerOpen}
|
||||
onClose={() => this.setState({ drawerOpen: false, })}
|
||||
onOpen={() => this.setState({ drawerOpen: true })}>
|
||||
<List component="nav">
|
||||
<ListItem>
|
||||
<Avatar alt="{Username}" style={{ width: 80, height: 80 }} src="https://avatarfiles.alphacoders.com/105/105250.jpg" />
|
||||
<ListItemText primary={this.state.user.username} />
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem button>
|
||||
<ListItemIcon>
|
||||
<PersonIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Profil" />
|
||||
</ListItem>
|
||||
<ListItem button>
|
||||
<ListItemIcon>
|
||||
<SettingsIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Einstellungen" />
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem
|
||||
component={Link}
|
||||
to="/dashboard"
|
||||
onClick={this.closeDrawer}
|
||||
button>
|
||||
<ListItemIcon>
|
||||
<HomeIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Dashboard" />
|
||||
</ListItem>
|
||||
<ListItem
|
||||
component={Link}
|
||||
to="/review/queue"
|
||||
onClick={this.closeDrawer}
|
||||
button>
|
||||
<ListItemIcon>
|
||||
<BookIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>
|
||||
Vokabeln üben
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
component={Link}
|
||||
to="/levelList"
|
||||
onClick={this.closeDrawer}
|
||||
button>
|
||||
<ListItemIcon>
|
||||
<ViewWeekIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>
|
||||
Levelübersicht
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem button onClick={() => {
|
||||
// Remove the auth token from the SessionStorage
|
||||
window.sessionStorage.removeItem("authKey");
|
||||
// Set the loggedIn State to false
|
||||
this.setState({
|
||||
loggedIn: false,
|
||||
// In case the drawer was open
|
||||
drawerOpen: false,
|
||||
});
|
||||
}}>
|
||||
<ListItemText>
|
||||
Abmelden
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ListItem button onClick={() => window.location = "https://gitlab.com/Polynomdivision/Lateinicus/tree/master"}>
|
||||
<ListItemIcon>
|
||||
<InfoIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Über" />
|
||||
</ListItem>
|
||||
</List>
|
||||
</SwipeableDrawer>
|
||||
|
||||
<Drawer />
|
||||
<div className="content">
|
||||
<Route exact path="/" component={() => <Redirect to="/login" />} />
|
||||
<Route exact path="/login" component={() => {
|
||||
|
22
src/containers/Drawer.ts
Normal file
22
src/containers/Drawer.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { setDrawer } from "../actions";
|
||||
|
||||
import Drawer from "../components/Drawer";
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
open: state.drawer,
|
||||
authenticated: state.authenticated,
|
||||
showButton: state.drawerButton,
|
||||
};
|
||||
};
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
setDrawer: (show: boolean) => dispatch(setDrawer(show)),
|
||||
};
|
||||
};
|
||||
|
||||
const DrawerContainer = connect(mapStateToProps,
|
||||
mapDispatchToProps)(Drawer);
|
||||
export default DrawerContainer;
|
@ -1,6 +1,17 @@
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
|
||||
import { createStore } from "redux";
|
||||
import { Provider } from "react-redux";
|
||||
|
||||
import { LateinicusApp } from "./reducers";
|
||||
|
||||
import Application from "./components/app";
|
||||
|
||||
ReactDOM.render(<Application />, document.getElementById("app"));
|
||||
const store = createStore(LateinicusApp);
|
||||
|
||||
ReactDOM.render((
|
||||
<Provider store={store}>
|
||||
<Application />
|
||||
</Provider>
|
||||
), document.getElementById("app"));
|
||||
|
26
src/reducers/index.ts
Normal file
26
src/reducers/index.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as Actions from "../actions";
|
||||
|
||||
const initialState = {
|
||||
// Show the drawer?
|
||||
drawer: false,
|
||||
// Should we show the button to open the drawer?
|
||||
drawerButton: true,
|
||||
// Is the user authenticated?
|
||||
// TODO: Set this to false
|
||||
authenticated: true,
|
||||
};
|
||||
|
||||
export function LateinicusApp(state = initialState, action: any) {
|
||||
switch (action.type) {
|
||||
case Actions.SET_DRAWER:
|
||||
return Object.assign({}, state, {
|
||||
drawer: action.show,
|
||||
});
|
||||
case Actions.SET_DRAWER_BUTTON:
|
||||
return Object.assign({}, state, {
|
||||
drawerButton: action.show,
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user