diff options
author | Eugene <eug-vs@keemail.me> | 2020-01-12 15:18:00 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-12 15:18:00 +0000 |
commit | 8b163ac33a8bb7fc77f934d20ab8454758abf0d7 (patch) | |
tree | a3edf615afdc83d364d58b84065017fae7fb5e98 | |
parent | d131fe1c40da4faf8fe850994d000263f867c9d6 (diff) | |
parent | fff9eae8022e1e3bb88884a47bfd4153b089f444 (diff) | |
download | chrono-cube-ui-8b163ac33a8bb7fc77f934d20ab8454758abf0d7.tar.gz |
Merge pull request #35 from Eug-VS/profile-window
Markup Profile page
-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), }, })); |