aboutsummaryrefslogtreecommitdiff
path: root/src/containers/PollCreation
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2020-08-12 01:59:27 +0300
committereug-vs <eug-vs@keemail.me>2020-08-13 17:16:17 +0300
commit5744923265ff51e392575edfd6a8182589105dc6 (patch)
tree9294f30455405ddaecfdd4ecf7eedf6c5c80c872 /src/containers/PollCreation
parent86a946b2b0535829857757eeaa2226e6f0814f3b (diff)
downloadwhich-ui-5744923265ff51e392575edfd6a8182589105dc6.tar.gz
feat: PollCreation page and Fab component
Diffstat (limited to 'src/containers/PollCreation')
-rw-r--r--src/containers/PollCreation/PollCreation.tsx105
-rw-r--r--src/containers/PollCreation/PollCreationImage.tsx95
-rw-r--r--src/containers/PollCreation/types.ts7
3 files changed, 207 insertions, 0 deletions
diff --git a/src/containers/PollCreation/PollCreation.tsx b/src/containers/PollCreation/PollCreation.tsx
new file mode 100644
index 0000000..1f3a802
--- /dev/null
+++ b/src/containers/PollCreation/PollCreation.tsx
@@ -0,0 +1,105 @@
+import React, { useState } from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import Collapse from '@material-ui/core/Collapse';
+import {
+ Button,
+ Card,
+ ClickAwayListener,
+ Divider,
+ Container
+} from '@material-ui/core';
+import { Poll } from 'which-types';
+import { useSnackbar } from 'notistack';
+import axios from 'axios';
+
+import PollCreationImage from './PollCreationImage';
+import UserStrip from '../../components/UserStrip/UserStrip';
+import { get, post } from '../../requests';
+import { useAuth } from '../../hooks/useAuth';
+
+interface PropTypes{
+ addPoll: (poll: Poll) => void;
+}
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ marginBottom: theme.spacing(4)
+ },
+ images: {
+ height: theme.spacing(50),
+ display: 'flex'
+ }
+}));
+
+const PollCreation: React.FC<PropTypes> = ({ addPoll }) => {
+ const classes = useStyles();
+ const [expanded, setExpanded] = useState(true);
+ const [left, setLeft] = useState<File>();
+ const [right, setRight] = useState<File>();
+ const { enqueueSnackbar } = useSnackbar();
+ const { user } = useAuth();
+
+ const readyToSubmit = left && right;
+
+ const handleClickAway = () => {
+ setExpanded(false);
+ };
+
+ const uploadImage = (file?: File) => {
+ const headers = { 'Content-Type': 'image/png' };
+ return get('/files')
+ .then(response => response.data)
+ .then(uploadUrl => axios.put(uploadUrl, file, { headers }))
+ .then(response => {
+ const { config: { url } } = response;
+ return url && url.slice(0, url.indexOf('.png') + 4);
+ });
+ };
+
+ const handleClick = async () => {
+ if (expanded && readyToSubmit) {
+ const [leftUrl, rightUrl] = await Promise.all([uploadImage(left), uploadImage(right)]);
+
+ const contents = {
+ left: { url: leftUrl },
+ right: { url: rightUrl }
+ };
+
+ post('/polls/', { contents }).then(response => {
+ addPoll(response.data);
+ enqueueSnackbar('Your poll has been successfully created!', {
+ variant: 'success'
+ });
+ });
+ }
+ setExpanded(!expanded);
+ };
+
+ return (
+ <Container maxWidth="sm" disableGutters>
+ <ClickAwayListener onClickAway={handleClickAway}>
+ <Card className={classes.root}>
+ <Collapse in={expanded} timeout="auto" unmountOnExit>
+ {user && <UserStrip user={user} info="" />}
+ <Divider />
+ <div className={classes.images}>
+ <PollCreationImage file={left} setFile={setLeft} />
+ <PollCreationImage file={right} setFile={setRight} />
+ </div>
+ </Collapse>
+ <Button
+ color="primary"
+ disabled={expanded && !readyToSubmit}
+ variant={expanded ? 'contained' : 'outlined'}
+ onClick={handleClick}
+ fullWidth
+ >
+ {expanded ? 'Submit' : 'Create a Poll'}
+ </Button>
+ </Card>
+ </ClickAwayListener>
+ </Container>
+ );
+};
+
+export default PollCreation;
diff --git a/src/containers/PollCreation/PollCreationImage.tsx b/src/containers/PollCreation/PollCreationImage.tsx
new file mode 100644
index 0000000..d3203a6
--- /dev/null
+++ b/src/containers/PollCreation/PollCreationImage.tsx
@@ -0,0 +1,95 @@
+import React, { useState, useEffect } from 'react';
+import { useFilePicker, utils } from 'react-sage';
+import { makeStyles } from '@material-ui/core/styles';
+import CloudUploadIcon from '@material-ui/icons/CloudUpload';
+import { CardActionArea, CardMedia, Typography } from '@material-ui/core';
+import CancelOutlinedIcon from '@material-ui/icons/CancelOutlined';
+
+interface PropTypes {
+ file: File | undefined;
+ setFile: (file: File | undefined) => void;
+}
+
+const useStyles = makeStyles({
+ root: {
+ display: 'flex',
+ justifyContent: 'center',
+ flexDirection: 'column',
+ alignItems: 'center'
+ },
+ clearIcon: {
+ opacity: '.5',
+ fontSize: 50
+ },
+ media: {
+ height: '100%',
+ width: '100%',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center'
+ },
+ text: {
+ textAlign: 'center'
+ }
+});
+
+
+const PollCreationImage: React.FC<PropTypes> = ({ file, setFile }) => {
+ const classes = useStyles();
+ const { files, onClick, HiddenFileInput } = useFilePicker();
+ const [url, setUrl] = useState<string>();
+ const [isMediaHover, setIsMediaHover] = useState(false);
+
+ const handleMouseEnter = (): void => {
+ setIsMediaHover(true);
+ };
+
+ const handleMouseLeave = (): void => {
+ setIsMediaHover(false);
+ };
+
+ useEffect(() => {
+ if (files?.length) {
+ const chosenFile = files[0];
+ setFile(chosenFile);
+ utils.loadFile(chosenFile).then(result => setUrl(result));
+ }
+ }, [files, setFile]);
+
+
+ const handleClick = () => {
+ if (file) {
+ setFile(undefined);
+ } else onClick();
+ };
+
+
+ const Upload = (
+ <>
+ <CloudUploadIcon fontSize="large" color="primary" />
+ <Typography variant="h5" className={classes.text}> Upload an image </Typography>
+ <HiddenFileInput accept=".jpg, .jpeg, .png, .gif" multiple={false} />
+ </>
+ );
+
+ const Media = (
+ <CardMedia
+ image={url}
+ className={classes.media}
+ onMouseEnter={handleMouseEnter}
+ onMouseLeave={handleMouseLeave}
+ >
+ {isMediaHover && <CancelOutlinedIcon className={classes.clearIcon} />}
+ </CardMedia>
+ );
+
+ return (
+ <>
+ <CardActionArea onClick={handleClick} className={classes.root}>
+ {file ? (url && Media) : Upload}
+ </CardActionArea>
+ </>
+ );
+};
+
+export default PollCreationImage;
diff --git a/src/containers/PollCreation/types.ts b/src/containers/PollCreation/types.ts
new file mode 100644
index 0000000..24ace4e
--- /dev/null
+++ b/src/containers/PollCreation/types.ts
@@ -0,0 +1,7 @@
+export interface ImageData {
+ url: string;
+}
+export interface Contents {
+ left: ImageData;
+ right: ImageData;
+}