feat: Replace Redirect with withRouter
This commit is contained in:
parent
286927663a
commit
1c15c6653f
@ -52,18 +52,10 @@ export function setUser(user: IUser) {
|
||||
};
|
||||
}
|
||||
|
||||
export const LEVEL_SET_REVIEW = "LEVEL_SET_REVIEW";
|
||||
export function setLevelReview(state: boolean) {
|
||||
return {
|
||||
type: LEVEL_SET_REVIEW,
|
||||
state,
|
||||
};
|
||||
};
|
||||
|
||||
export const LEVEL_SET_LOOKEDAT = "LEVEL_SET_LOOKEDAT";
|
||||
export function setLevelLookedAt(ids: number[]) {
|
||||
return {
|
||||
type: LEVEL_SET_REVIEW,
|
||||
type: LEVEL_SET_LOOKEDAT,
|
||||
lookedAt: ids,
|
||||
};
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ import LoginPage from "../containers/LoginPage";
|
||||
import LevelListPage from "../containers/LevelList";
|
||||
import LevelPage from "../containers/LevelPage";
|
||||
import ReviewPage from "../containers/Review";
|
||||
import SummaryPage from "../pages/summary";
|
||||
import SummaryPage from "../containers/SummaryPage";
|
||||
import WelcomePage from "../pages/intro";
|
||||
|
||||
import Drawer from "../containers/Drawer";
|
||||
@ -309,8 +309,7 @@ export default class Application extends React.Component<IProps> {
|
||||
isAuth={this.isAuthenticated}
|
||||
path="/review/summary"
|
||||
component={() => {
|
||||
return <SummaryPage
|
||||
reviewMeta={this.getLastReview} />
|
||||
return <SummaryPage />
|
||||
}} />
|
||||
</div>
|
||||
</div >
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import {
|
||||
setDrawerButton, setLevelReview, setLevelLookedAt,
|
||||
setDrawerButton, setLevelLookedAt,
|
||||
setLevelCurrentVocab, setLevelVocab, setLevelLoading
|
||||
} from "../actions";
|
||||
|
||||
@ -10,12 +10,11 @@ import { IVocab } from "../models/vocab";
|
||||
import LevelPage from "../pages/level";
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const { currentVocab, lookedAt, toReview, vocab, loading } = state.level;
|
||||
const { currentVocab, lookedAt, vocab, loading } = state.level;
|
||||
|
||||
return {
|
||||
currentVocab,
|
||||
lookedAt,
|
||||
toReview,
|
||||
vocab,
|
||||
loading,
|
||||
};
|
||||
@ -24,7 +23,6 @@ const mapStateToProps = state => {
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
drawerButtonState: (state: boolean) => dispatch(setDrawerButton(state)),
|
||||
setReview: (state: boolean) => dispatch(setLevelReview(state)),
|
||||
setLookedAt: (ids: number[]) => dispatch(setLevelLookedAt(ids)),
|
||||
setCurrentVocab: (vocab: IVocab) => dispatch(setLevelCurrentVocab(vocab)),
|
||||
setVocab: (vocab: IVocab[]) => dispatch(setLevelVocab(vocab)),
|
||||
|
21
src/containers/SummaryPage.ts
Normal file
21
src/containers/SummaryPage.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { setDrawerButton } from "../actions";
|
||||
|
||||
import SummaryPage from "../pages/summary";
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
reviewMeta: state.lastReview,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
setDrawerButton: (state: boolean) => dispatch(setDrawerButton(state)),
|
||||
};
|
||||
};
|
||||
|
||||
const SummaryPageContainer = connect(mapStateToProps,
|
||||
mapDispatchToProps)(SummaryPage);
|
||||
export default SummaryPageContainer;
|
@ -10,7 +10,7 @@ import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
|
||||
import { Redirect } from "react-router-dom";
|
||||
import { withRouter } from "react-router-dom";
|
||||
|
||||
import { IVocab } from "../models/vocab";
|
||||
|
||||
@ -18,183 +18,170 @@ interface IProps {
|
||||
id: string;
|
||||
levelVocab: (id: string) => Promise<IVocab[]>;
|
||||
|
||||
history: any;
|
||||
|
||||
loading: boolean;
|
||||
setLoading: (state: boolean) => void;
|
||||
vocab: IVocab[];
|
||||
setVocab: (vocab: IVocab[]) => void;
|
||||
setLookedAt: (ids: number[]) => void;
|
||||
setCurrentVocab: (vocab: IVocab) => void;
|
||||
setReview: (state: boolean) => void;
|
||||
drawerButtonState: (state: boolean) => void;
|
||||
currentVocab: IVocab;
|
||||
lookedAt: number[];
|
||||
toReview: boolean;
|
||||
};
|
||||
|
||||
export default class LevelPage extends React.Component<IProps> {
|
||||
private uid = 0;
|
||||
// To prevent React from redrawing the vocabulary list and prematurely
|
||||
// cancelling the animation
|
||||
private uids: { [key: string]: string } = {};
|
||||
const LevelPageWithRouter = withRouter(
|
||||
class LevelPage extends React.Component<IProps> {
|
||||
private uid = 0;
|
||||
// To prevent React from redrawing the vocabulary list and prematurely
|
||||
// cancelling the animation
|
||||
private uids: { [key: string]: string } = {};
|
||||
|
||||
componentDidMount() {
|
||||
// Hide the drawer
|
||||
this.props.drawerButtonState(false);
|
||||
componentDidMount() {
|
||||
// Hide the drawer
|
||||
this.props.drawerButtonState(false);
|
||||
|
||||
// Fetch the vocabulary
|
||||
this.props.setLoading(true);
|
||||
// Fetch the vocabulary
|
||||
this.props.setLoading(true);
|
||||
|
||||
// TODO: Error handling
|
||||
this.props.levelVocab(this.props.id).then(vocab => {
|
||||
this.props.setVocab(vocab);
|
||||
this.props.setCurrentVocab(vocab[0]);
|
||||
this.props.setLoading(false);
|
||||
});
|
||||
// TODO: Error handling
|
||||
this.props.levelVocab(this.props.id).then(vocab => {
|
||||
this.props.setVocab(vocab);
|
||||
this.props.setCurrentVocab(vocab[0]);
|
||||
this.props.setLoading(false);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
genUID = (vocab: IVocab): string => {
|
||||
const { grundform } = vocab.latin;
|
||||
if (grundform in this.uids) {
|
||||
return this.uids[grundform];
|
||||
} else {
|
||||
this.uids[grundform] = "LEVELPAGE" + this.uid++;
|
||||
return this.uids[grundform];
|
||||
}
|
||||
}
|
||||
|
||||
renderVocabListItem = (vocab: IVocab): any => {
|
||||
// Check if the vocab was already looked at
|
||||
const lookedAt = this.props.lookedAt.find((el) => el === vocab.id) || vocab.id === 0;
|
||||
|
||||
return <ListItem button key={this.genUID(vocab)} onClick={() => {
|
||||
// Prevent the user from using too much memory by always clicking on the elements
|
||||
// Show the clicked at vocab word
|
||||
|
||||
this.props.setCurrentVocab(vocab);
|
||||
this.props.setLookedAt(lookedAt ? (
|
||||
this.props.lookedAt
|
||||
) : this.props.lookedAt.concat(vocab.id));
|
||||
}}>
|
||||
<ListItemText>
|
||||
{`${vocab.latin.grundform} ${lookedAt ? "✔" : ""}`}
|
||||
</ListItemText>
|
||||
</ListItem>;
|
||||
}
|
||||
|
||||
toReview = () => {
|
||||
const { vocab, lookedAt } = this.props;
|
||||
// Only go to the review if all vocabulary item have been looked at
|
||||
if (vocab.length === lookedAt.length) {
|
||||
this.props.setReview(true);
|
||||
genUID = (vocab: IVocab): string => {
|
||||
const { grundform } = vocab.latin;
|
||||
if (grundform in this.uids) {
|
||||
return this.uids[grundform];
|
||||
} else {
|
||||
this.uids[grundform] = "LEVELPAGE" + this.uid++;
|
||||
return this.uids[grundform];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.loading) {
|
||||
return <div>
|
||||
{/*
|
||||
* This would be the case when the user presses the "to
|
||||
* review" button. That is because we need the state of loading
|
||||
* to be true, when this page gets called
|
||||
* TODO:?
|
||||
*/}
|
||||
{
|
||||
this.props.toReview ? (
|
||||
<Redirect to={`/review/level/${this.props.id}`} />
|
||||
) : undefined
|
||||
}
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justify="center"
|
||||
style={{ minHeight: '100vh' }}>
|
||||
<Grid item xs={12}>
|
||||
<Paper className="paper">
|
||||
<Grid container direction="column" spacing={8}>
|
||||
<CircularProgress />
|
||||
</Grid>
|
||||
</Paper>
|
||||
renderVocabListItem = (vocab: IVocab): any => {
|
||||
// Check if the vocab was already looked at
|
||||
const lookedAt = this.props.lookedAt.find((el) => el === vocab.id) || vocab.id === 0;
|
||||
|
||||
return <ListItem button key={this.genUID(vocab)} onClick={() => {
|
||||
// Prevent the user from using too much memory by always clicking on the elements
|
||||
// Show the clicked at vocab word
|
||||
|
||||
this.props.setCurrentVocab(vocab);
|
||||
this.props.setLookedAt(lookedAt ? (
|
||||
this.props.lookedAt
|
||||
) : this.props.lookedAt.concat(vocab.id));
|
||||
}}>
|
||||
<ListItemText>
|
||||
{`${vocab.latin.grundform} ${lookedAt ? "✔" : ""}`}
|
||||
</ListItemText>
|
||||
</ListItem>;
|
||||
}
|
||||
|
||||
toReview = () => {
|
||||
const { vocab, lookedAt, id } = this.props;
|
||||
// Only go to the review if all vocabulary item have been looked at
|
||||
if (vocab.length === lookedAt.length) {
|
||||
this.props.setLoading(true);
|
||||
this.props.history.push(`/review/level/${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.loading) {
|
||||
return <div>
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justify="center"
|
||||
style={{ minHeight: '100vh' }}>
|
||||
<Grid item xs={12}>
|
||||
<Paper className="paper">
|
||||
<Grid container direction="column" spacing={8}>
|
||||
<CircularProgress />
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</div>;
|
||||
}
|
||||
</div>;
|
||||
}
|
||||
|
||||
const { currentVocab } = this.props;
|
||||
return <div>
|
||||
<Grid container direction="row">
|
||||
<Grid item xs={3}>
|
||||
<List>
|
||||
{this.props.vocab
|
||||
.map(this.renderVocabListItem)}
|
||||
{/* TODO*/}
|
||||
<ListItem button onClick={this.toReview}>
|
||||
<ListItemText>
|
||||
Zur Übung
|
||||
const { currentVocab } = this.props;
|
||||
return <div>
|
||||
<Grid container direction="row">
|
||||
<Grid item xs={3}>
|
||||
<List>
|
||||
{this.props.vocab
|
||||
.map(this.renderVocabListItem)}
|
||||
<ListItem button onClick={this.toReview}>
|
||||
<ListItemText>
|
||||
Zur Übung
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Grid>
|
||||
{
|
||||
this.props.toReview ? (
|
||||
<Redirect to={`/review/level/${this.props.id}`} />
|
||||
) : undefined
|
||||
}
|
||||
<Grid item lg={7} xs={9}>
|
||||
<Grid container direction="column">
|
||||
<Grid item style={{ margin: 12 }}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="headline" component="h2">
|
||||
{currentVocab.latin.grundform}
|
||||
</Typography>
|
||||
<Typography gutterBottom variant="headline" component="h3">
|
||||
{currentVocab.german.join(", ")}
|
||||
</Typography>
|
||||
{
|
||||
currentVocab.hint ? (
|
||||
<div style={{
|
||||
border: "dashed",
|
||||
borderColor: "red",
|
||||
padding: 12,
|
||||
}}>
|
||||
<Typography variant="subheading" component="p">
|
||||
<b>Tipp:</b>
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
{currentVocab.hint}
|
||||
</Typography>
|
||||
</div>
|
||||
) : undefined
|
||||
}
|
||||
{
|
||||
currentVocab.mnemonic ? (
|
||||
<div style={{
|
||||
border: "dashed",
|
||||
borderColor: "#f1c40f",
|
||||
marginTop: 12,
|
||||
padding: 12,
|
||||
}}>
|
||||
<Typography variant="subheading" component="p">
|
||||
<b>Eselsbrücke:</b>
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
{currentVocab.mnemonic}
|
||||
</Typography>
|
||||
</div>
|
||||
) : undefined
|
||||
}
|
||||
</CardContent>
|
||||
{/*TODO: Maybe "next" and "prev" buttons?*/}
|
||||
</Card>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Grid>
|
||||
<Grid item lg={7} xs={9}>
|
||||
<Grid container direction="column">
|
||||
<Grid item style={{ margin: 12 }}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="headline" component="h2">
|
||||
{currentVocab.latin.grundform}
|
||||
</Typography>
|
||||
<Typography gutterBottom variant="headline" component="h3">
|
||||
{currentVocab.german.join(", ")}
|
||||
</Typography>
|
||||
{
|
||||
currentVocab.hint ? (
|
||||
<div style={{
|
||||
border: "dashed",
|
||||
borderColor: "red",
|
||||
padding: 12,
|
||||
}}>
|
||||
<Typography variant="subheading" component="p">
|
||||
<b>Tipp:</b>
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
{currentVocab.hint}
|
||||
</Typography>
|
||||
</div>
|
||||
) : undefined
|
||||
}
|
||||
{
|
||||
currentVocab.mnemonic ? (
|
||||
<div style={{
|
||||
border: "dashed",
|
||||
borderColor: "#f1c40f",
|
||||
marginTop: 12,
|
||||
padding: 12,
|
||||
}}>
|
||||
<Typography variant="subheading" component="p">
|
||||
<b>Eselsbrücke:</b>
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
{currentVocab.mnemonic}
|
||||
</Typography>
|
||||
</div>
|
||||
) : undefined
|
||||
}
|
||||
</CardContent>
|
||||
{/*TODO: Maybe "next" and "prev" buttons?*/}
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>;
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
export default LevelPageWithRouter;
|
||||
|
@ -6,55 +6,51 @@ import Grid from "@material-ui/core/Grid";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import SummaryTable from "../components/SummaryTable";
|
||||
|
||||
import { Redirect } from "react-router-dom";
|
||||
import { withRouter } from "react-router-dom";
|
||||
|
||||
import { IReviewMetadata } from "../models/review";
|
||||
|
||||
interface IProps {
|
||||
reviewMeta: () => IReviewMetadata;
|
||||
history: any;
|
||||
|
||||
reviewMeta: IReviewMetadata;
|
||||
setDrawerButton: (state: boolean) => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
toDashboard: boolean;
|
||||
}
|
||||
// TODO: This stays at the default value
|
||||
const SummaryPageWithRouter = withRouter(
|
||||
class SummaryPage extends React.Component<IProps> {
|
||||
toDashboard = () => {
|
||||
// Show the drawer button
|
||||
this.props.setDrawerButton(true);
|
||||
|
||||
export default class SummaryPage extends React.Component<IProps, IState> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
// Go to the dashboard
|
||||
this.props.history.push("/dashboard");
|
||||
}
|
||||
|
||||
this.state = {
|
||||
toDashboard: false,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
{
|
||||
this.state.toDashboard ? (
|
||||
<Redirect to="/dashboard" />
|
||||
) : undefined
|
||||
}
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justify="center"
|
||||
style={{ minHeight: '100vh' }}>
|
||||
<Grid item xs={12}>
|
||||
<Paper className="paper">
|
||||
<Typography variant="title">Zusammenfassung</Typography>
|
||||
<Grid container direction="column">
|
||||
<SummaryTable reviewMeta={this.props.reviewMeta} />
|
||||
<Button onClick={() => this.setState({
|
||||
toDashboard: true,
|
||||
})}>
|
||||
Zum Dashboard
|
||||
render() {
|
||||
return <div>
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justify="center"
|
||||
style={{ minHeight: '100vh' }}>
|
||||
<Grid item xs={12}>
|
||||
<Paper className="paper">
|
||||
<Typography variant="title">Zusammenfassung</Typography>
|
||||
<Grid container direction="column">
|
||||
<SummaryTable reviewMeta={() => this.props.reviewMeta} />
|
||||
<Button onClick={this.toDashboard}>
|
||||
Zum Dashboard
|
||||
</Button>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>;
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
export default SummaryPageWithRouter;
|
||||
|
@ -26,7 +26,6 @@ interface IState {
|
||||
level: {
|
||||
currentVocab: IVocab;
|
||||
lookedAt: number[];
|
||||
toReview: boolean;
|
||||
vocab: IVocab[];
|
||||
loading: boolean;
|
||||
};
|
||||
@ -74,7 +73,6 @@ const initialState: IState = {
|
||||
level: {
|
||||
currentVocab: {} as IVocab,
|
||||
lookedAt: [0],
|
||||
toReview: false,
|
||||
vocab: [],
|
||||
loading: true,
|
||||
},
|
||||
@ -137,15 +135,6 @@ export function LateinicusApp(state: IState = initialState, action: any) {
|
||||
return Object.assign({}, state, {
|
||||
user: action.user,
|
||||
});
|
||||
case Actions.LEVEL_SET_REVIEW:
|
||||
return Object.assign({}, state, {
|
||||
level: Object.assign({}, state.level, {
|
||||
toReview: action.state,
|
||||
// Make sure that we are in a "loading mode", when the page gets
|
||||
// called the next time
|
||||
loading: true,
|
||||
}),
|
||||
});
|
||||
case Actions.LEVEL_SET_LOOKEDAT:
|
||||
return Object.assign({}, state, {
|
||||
level: Object.assign({}, state.level, {
|
||||
|
Reference in New Issue
Block a user