diff options
author | eug-vs <eugene@eug-vs.xyz> | 2022-05-04 12:52:25 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2022-05-04 12:52:25 +0300 |
commit | f35c1cf5480f7506442ac4c9170c5e0a1a4a8b15 (patch) | |
tree | 94fa0fa38e8a90df08933c05910bea6bed461291 /src/components | |
parent | 8dc803f882f31430abb600fba250fdcf3334d9bf (diff) | |
download | chrono-cube-ui-f35c1cf5480f7506442ac4c9170c5e0a1a4a8b15.tar.gz |
feat: remove material UI and useless functionality
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/GithubAvatar/GithubAvatar.tsx | 39 | ||||
-rw-r--r-- | src/components/Loading/Loading.tsx | 33 | ||||
-rw-r--r-- | src/components/SolutionCard/SolutionCard.tsx | 117 | ||||
-rw-r--r-- | src/components/Timer.tsx | 90 |
4 files changed, 90 insertions, 189 deletions
diff --git a/src/components/GithubAvatar/GithubAvatar.tsx b/src/components/GithubAvatar/GithubAvatar.tsx deleted file mode 100644 index 32ac553..0000000 --- a/src/components/GithubAvatar/GithubAvatar.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; - -import { - Avatar, - Link, -} from '@material-ui/core'; - -interface PropTypes { - username: string; -} - -const githubUrl = 'https://github.com/'; -const getUserGithubUrl = (username: string): string => githubUrl + username; - -const GithubAvatar: React.FC<PropTypes> = ({ username }) => { - if (username === 'anonymous') return <Avatar/>; - - const userGithubUrl = getUserGithubUrl(username); - const avatarUrl = userGithubUrl + '.png'; - const usernameTokens = username.split(/[ ,.\-_#@;]/g); - const altText = ( - (usernameTokens.length > 1)? - (usernameTokens[0][0] + usernameTokens[1][0]) - : - usernameTokens[0][0] - ).toUpperCase() - - return ( - <Link href={userGithubUrl}> - <Avatar> - <img src={avatarUrl} alt={altText} /> - </Avatar> - </Link> - ) -}; - -export { getUserGithubUrl }; -export default GithubAvatar; - diff --git a/src/components/Loading/Loading.tsx b/src/components/Loading/Loading.tsx deleted file mode 100644 index a784be1..0000000 --- a/src/components/Loading/Loading.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; - -import { - Card, - CardHeader, -} from '@material-ui/core'; - -import { makeStyles } from '@material-ui/core/styles'; -import CircularProgress from '@material-ui/core/CircularProgress'; - - -const useStyles = makeStyles(theme => ({ - root: { - padding: theme.spacing(1), - background: theme.palette.background.elevation2, - }, -})); - -const Loading: React.FC = () => { - const classes = useStyles(); - - return ( - <Card className={classes.root}> - <CardHeader - avatar={(<CircularProgress color="secondary" />)} - title="Loading" - subheader="Please, wait." - /> - </Card> - ) -}; - -export default Loading; diff --git a/src/components/SolutionCard/SolutionCard.tsx b/src/components/SolutionCard/SolutionCard.tsx deleted file mode 100644 index 7ec8888..0000000 --- a/src/components/SolutionCard/SolutionCard.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import React, { useState } from 'react'; - -import { - Typography, - Card, - CardHeader, - CardContent, - IconButton, - Grid, - Menu, - MenuItem, -} from '@material-ui/core'; -import { Solution } from '../../types'; - -import { makeStyles } from '@material-ui/core/styles'; -import TimerIcon from '@material-ui/icons/Timer'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; -import DeleteIcon from '@material-ui/icons/Delete'; - -import GithubAvatar from '../GithubAvatar/GithubAvatar'; -import { del } from '../../requests'; - - -const DATE_FORMAT = { - month: 'long', - day: 'numeric', - year: 'numeric', - hour: '2-digit', - minute: '2-digit', -}; - -const useStyles = makeStyles(theme => ({ - root: { - padding: theme.spacing(1), - background: theme.palette.background.elevation2, - - '& .MuiTypography-h3': { - margin: theme.spacing(2), - }, - }, - menu: { - '& ul': { - background: theme.palette.background.elevation3, - } - }, -})); - - -interface PropTypes { - data: Solution; - removeThisCard: (id: number) => void; -} - - -const SolutionCard: React.FC<PropTypes> = ({ data, removeThisCard }) => { - const classes = useStyles(); - const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null); - - const author = data.author? data.author.username : 'anonymous'; - const date = new Date(data.date); - - const handleOpenMenu = (event: React.MouseEvent<HTMLButtonElement>): void => { - setAnchorEl(event.currentTarget); - }; - - const handleClose = (): void => { - setAnchorEl(null); - }; - - const handleDelete = (): void => { - del(`solutions/${data.id}/`).then(() => { - removeThisCard(data.id); - }); - handleClose(); - }; - - return ( - <Card className={classes.root}> - <CardHeader - avatar={<GithubAvatar username={author} />} - title={author} - subheader={date.toLocaleString('default', DATE_FORMAT)} - action={ - <IconButton onClick={handleOpenMenu}> - <MoreVertIcon /> - </IconButton> - } - /> - <Menu - anchorEl={anchorEl} - open={Boolean(anchorEl)} - keepMounted - onClose={handleClose} - className={classes.menu} - > - <MenuItem onClick={handleDelete}> - <DeleteIcon /> - Delete - </MenuItem> - </Menu> - <CardContent> - <Grid container direction="row" justify="center" alignItems="center"> - <Grid item> - <TimerIcon/> - </Grid> - <Grid item> - <Typography variant="h3" color="primary"> - { data.result } - </Typography> - </Grid> - </Grid> - </CardContent> - </Card> - ) -}; - -export default SolutionCard; diff --git a/src/components/Timer.tsx b/src/components/Timer.tsx new file mode 100644 index 0000000..c9d7adf --- /dev/null +++ b/src/components/Timer.tsx @@ -0,0 +1,90 @@ +import React, { useState, useEffect } from 'react'; +import convertTimeToString from '../utils/convertTimeToString'; + +enum Mode { + 'idle', + 'countdown', + 'running' , + 'over', +}; + +const helperText = { + [Mode.idle]: 'Hold SPACE to start countdown', + [Mode.countdown]: 'Release SPACE to begin', + [Mode.running]: 'Go fast!', + [Mode.over]: 'You are too late!', +}; + +// TODO: add to props +const registerResult = (result: string): void => { + console.log(result) +}; + +const Timer: React.FC = () => { + const KEY_CODE = 32; // Space key + const maxCountdown = 15000; + + const [mode, setMode] = useState<Mode>(Mode.idle); + const [displayTime, setDisplayTime] = useState<string>('00:00:00'); + + useEffect(() => { + const timestamp = Date.now(); + + if (mode === Mode.countdown) { + const repeater = setInterval(() => { + const timeDelta = maxCountdown - (Date.now() - timestamp); + if (timeDelta <= 0) setMode(Mode.over); + setDisplayTime(convertTimeToString(timeDelta)); + }, 10); + return (): void => clearInterval(repeater); + } + + if (mode === Mode.running) { + const repeater = setInterval(() => { + setDisplayTime(convertTimeToString(Date.now() - timestamp)); + }, 10); + return (): void => clearInterval(repeater); + } + + if (mode === Mode.over) { + setDisplayTime('00:00:00'); + } + }, [mode]); + + const handleKeyPress = (event: KeyboardEvent): void => { + event.preventDefault(); + if (event.keyCode === KEY_CODE && mode === Mode.idle) setMode(Mode.countdown); + }; + + const handleKeyUp = (event: KeyboardEvent): void => { + if (event.keyCode === KEY_CODE) { + if (mode === Mode.running) { + registerResult(displayTime); + setMode(Mode.idle); + } else if (mode === Mode.over) { + setMode(Mode.idle); + } else { + setMode(Mode.running); + } + } + }; + + useEffect(() => { + window.addEventListener('keyup', handleKeyUp); + window.addEventListener('keypress', handleKeyPress); + + return () => { + window.removeEventListener('keyup', handleKeyUp); + window.removeEventListener('keypress', handleKeyPress); + }; + }); + + return ( + <> + <span>{ displayTime }</span> + <p>{ helperText[mode] }</p> + </> + ); +}; + +export default Timer; |