diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/index.js | 30 | ||||
| -rw-r--r-- | src/pages/Profile/Profile.js | 85 | ||||
| -rw-r--r-- | src/pages/Profile/Registration/Registration.js | 80 | ||||
| -rw-r--r-- | src/pages/Timer/Timer.js | 19 | ||||
| -rw-r--r-- | src/pages/Timer/TimerButton/TimerButton.js | 2 | 
5 files changed, 199 insertions, 17 deletions
| diff --git a/src/index.js b/src/index.js index 0c3d415..6563c60 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react';  import ReactDOM from 'react-dom';  import CssBaseline from '@material-ui/core/CssBaseline'; @@ -10,37 +10,49 @@ import Header from './components/Header/Header';  import Timer from "./pages/Timer/Timer";  import Scoreboard from "./pages/Scoreboard/Scoreboard";  import Contribute from "./pages/Contribute/Contribute"; +import Profile from "./pages/Profile/Profile"; + +import { get } from "./requests";  const App = () => {    const [page, setPage] = useState('app'); +  const [user, setUser] = useState({ username: 'anonymous', id: null });    const [recentSolutions, setRecentSolutions] = useState([]); +  useEffect(() => { +    const userId = +localStorage.getItem('userId'); +    if (userId) { +      get('users/').then(response => { +        setUser(response.data.filter(user => user.id === +userId)[0]); +      }); +    } +  }, []); +    const Page = ({ page }) => {      switch (page) {        case 'app':          return (            <Timer +            user={user}              recentSolutions={recentSolutions}              setRecentSolutions={setRecentSolutions}              setPage={setPage}            />          ); +      case 'profile': +        return <Profile user={user} setUser={setUser} />; +        case 'scoreboard': -        return (<Scoreboard />); +        return <Scoreboard />;        case 'contribute': -        return (<Contribute />); +        return <Contribute />;        default: -        return ( -          <p> -            This text is rendered outside of <code>Header</code> component, but -            interacting with <code>Header</code> can influence content of this page! -          </p> -        ) +        return <Contribute />;      }    }; diff --git a/src/pages/Profile/Profile.js b/src/pages/Profile/Profile.js new file mode 100644 index 0000000..861e58e --- /dev/null +++ b/src/pages/Profile/Profile.js @@ -0,0 +1,85 @@ +import React, { useState, useEffect } from 'react'; +import Window from "../../components/Window/Window"; + +import { +  Button, +  makeStyles, +} from "@material-ui/core"; + +import Registration from "./Registration/Registration"; +import ContentSection from "../../components/ContentSection/ContentSection"; +import SmartList from "../../components/SmartList/SmartList"; + +import { get } from "../../requests"; +import SolutionCard from "../../components/SolutionCard/SolutionCard"; + + +const useStyles = makeStyles(theme => ({ +  primary: { +    padding: theme.spacing(4), +  }, +  cell: { +    padding: theme.spacing(5), +  }, +})); + + +const Profile = ({ user, setUser }) => { +  const classes = useStyles(); + +  const [profileSolutions, setProfileSolutions] = useState([]); + +  const handleLogout = () => { +    setUser({ username: 'anonymous', id: null }); +    localStorage.clear(); +  }; + +  useEffect(() => { +    get(`solutions/?author=${user.id}`).then(response => { +      setProfileSolutions(response.data.reverse()); +    }); +  }, [user]); + +  const removeSolution = (id) => { +    setProfileSolutions(profileSolutions.filter((solution => solution.id !== id))); +  }; + +  const renderItem = ({ index, style }) => { +    return ( +      <div style={style} className={classes.cell}> +        <SolutionCard data={profileSolutions[index]} removeThisCard={removeSolution} /> +      </div> +    ); +  }; + +  return ( +    <> +      <Window type="primary"> +        <div className={classes.primary}> +          { user.id? ( +            <ContentSection sectionName={`Welcome back, ${user.username}!`}> +              <p> Total amount of solutions: {profileSolutions.length} </p> +              <p> You can always log out from your account! </p> +              <Button variant="contained" color="secondary" onClick={handleLogout}> +                Logout +              </Button> +            </ContentSection> +          ): ( +            <Registration setUser={setUser} /> +          ) +          } +        </div> +      </Window> +      <Window type="secondary" name="History"> +        <SmartList +          itemSize={270} +          itemCount={profileSolutions.length} +          renderItem={renderItem} +        /> +      </Window> +    </> +  ) +}; + + +export default Profile; diff --git a/src/pages/Profile/Registration/Registration.js b/src/pages/Profile/Registration/Registration.js new file mode 100644 index 0000000..45c83bc --- /dev/null +++ b/src/pages/Profile/Registration/Registration.js @@ -0,0 +1,80 @@ +import React, {useState} from 'react'; + +import { +  TextField, +  Button, +  Checkbox, +  FormControlLabel, +  Grid, +} from "@material-ui/core"; + +import ContentSection from "../../../components/ContentSection/ContentSection"; +import {get, post} from "../../../requests"; + + +const Registration = ({ setUser }) => { + +  const [username, setUsername] = useState(''); +  const [isRememberMe, setIsRememberMe] = useState(false); + +  const handleChange = (event) => { +    setUsername(event.target.value); +  }; + +  const handleCheck = (event) => { +    setIsRememberMe(event.target.checked); +  }; + +  const handleSubmit = () => { +    if (username !== '') { +      post('users/', { username }) +        .then(response => { +          const user = response.data; +          setUser(user); +          if (isRememberMe) { +            localStorage.setItem('userId', user.id); +          } +        }) +        .catch(err => { +          get('users/').then(response => { +            const user = response.data.filter(user => user.username === username)[0]; +            setUser(user); +            if (isRememberMe) { +              localStorage.setItem('userId', user.id); +            } +          }); +        }); +    } +  }; + +  return ( +    <ContentSection sectionName="Tell us who you are"> +      <p> Choose yourself a username to track your progress and compete with others: </p> +      <Grid container direction="column"> +        <Grid item> +          <TextField +            variant="outlined" +            color="secondary" +            label="Username" +            value={username} +            onChange={handleChange} +          /> +        </Grid> +        <Grid item> +          <FormControlLabel +            control={<Checkbox color="secondary" onChange={handleCheck} />} +            label="Remember me" +          /> +        </Grid> +        <Grid item> +          <Button variant="contained" color="secondary" size="large" onClick={handleSubmit}> +            Submit! +          </Button> +        </Grid> +      </Grid> +    </ContentSection> +  ); +}; + + +export default Registration; diff --git a/src/pages/Timer/Timer.js b/src/pages/Timer/Timer.js index d63c661..a41c47b 100644 --- a/src/pages/Timer/Timer.js +++ b/src/pages/Timer/Timer.js @@ -8,7 +8,7 @@ import TimerButton from "./TimerButton/TimerButton";  import SmartList from "../../components/SmartList/SmartList";  import SolutionCard from "../../components/SolutionCard/SolutionCard"; -import { Typography, Button, makeStyles } from "@material-ui/core"; +import { Button, makeStyles } from "@material-ui/core";  const useStyles = makeStyles(theme => ({ @@ -20,14 +20,9 @@ const useStyles = makeStyles(theme => ({    },  })); -const Timer = ({ recentSolutions, setRecentSolutions, setPage }) => { +const Timer = ({ user, recentSolutions, setRecentSolutions, setPage }) => {    const classes = useStyles(); -  const user = { -    id: null, -    username: 'anonymous', -  }; -    const registerResult = result => {      const solution = { author_id: user.id, result };      post('solutions/', solution).then(response => { @@ -39,6 +34,10 @@ const Timer = ({ recentSolutions, setRecentSolutions, setPage }) => {      setPage('contribute');    }; +  const handleLogin = () => { +    setPage('profile'); +  }; +    const removeSolution = (id) => {      setRecentSolutions(recentSolutions.filter((solution => solution.id !== id)));    }; @@ -66,6 +65,12 @@ const Timer = ({ recentSolutions, setRecentSolutions, setPage }) => {              </p>              <Button variant="contained" color="secondary" onClick={handleLearnMore}> Learn more </Button>            </ContentSection> +          {user.id === null && +          <ContentSection sectionName="Log into an account"> +            <p> Tell us your name so we can track your progress</p> +            <Button variant="contained" color="secondary" onClick={handleLogin} size="large"> Login </Button> +          </ContentSection> +          }            <TimerButton registerResult={registerResult} />          </div>        </Window> diff --git a/src/pages/Timer/TimerButton/TimerButton.js b/src/pages/Timer/TimerButton/TimerButton.js index 56d3084..82af6ec 100644 --- a/src/pages/Timer/TimerButton/TimerButton.js +++ b/src/pages/Timer/TimerButton/TimerButton.js @@ -8,7 +8,7 @@ const useStyles = makeStyles(theme => ({      textAlign: 'center',      padding: theme.spacing(5),      background: theme.palette.primary.main, -    marginTop: theme.spacing(20), +    marginTop: theme.spacing(10),    },  })); | 
