diff options
| author | ilyayudovin <ilyayudovin123@gmail.com> | 2020-06-28 19:09:20 +0300 | 
|---|---|---|
| committer | ilyayudovin <ilyayudovin123@gmail.com> | 2020-06-28 19:09:20 +0300 | 
| commit | 7ad127942bb12ee9de691e10dc9386849459ea46 (patch) | |
| tree | 1e576177546a8d3fe7f0f5dbf40bed34ca23a75e /src | |
| parent | ccb26a42a3ad8d748e00cfbe9687f3198d5b8cb4 (diff) | |
| download | which-ui-7ad127942bb12ee9de691e10dc9386849459ea46.tar.gz | |
feat: add poll submission component
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/UploadImage/UploadImage.tsx | 28 | ||||
| -rw-r--r-- | src/index.tsx | 2 | ||||
| -rw-r--r-- | src/pages/FeedPage/FeedPage.tsx | 14 | ||||
| -rw-r--r-- | src/pages/FeedPage/PollSubmission.tsx | 87 | ||||
| -rw-r--r-- | src/pages/FeedPage/PollSubmissionImage.tsx | 60 | ||||
| -rw-r--r-- | src/pages/FeedPage/types.ts | 7 | ||||
| -rw-r--r-- | src/pages/ProfilePage/ProfileInfo.tsx | 12 | ||||
| -rw-r--r-- | src/types.d.ts | 1 | 
8 files changed, 190 insertions, 21 deletions
| diff --git a/src/components/UploadImage/UploadImage.tsx b/src/components/UploadImage/UploadImage.tsx index 42ee989..464a9cf 100644 --- a/src/components/UploadImage/UploadImage.tsx +++ b/src/components/UploadImage/UploadImage.tsx @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react';  import Button from '@material-ui/core/Button';  import TextField from '@material-ui/core/TextField';  import Dialog from '@material-ui/core/Dialog'; @@ -6,35 +6,32 @@ import DialogActions from '@material-ui/core/DialogActions';  import DialogContent from '@material-ui/core/DialogContent';  import DialogContentText from '@material-ui/core/DialogContentText';  import DialogTitle from '@material-ui/core/DialogTitle'; -import { User } from 'which-types'; -import { patch } from '../../requests';  interface PropTypes {    displayD: boolean;    setDisplayD: (d: boolean) => void; -  setUserInfo: (a: User) => void; -  setUser: (a: User) => void +  callback: (a: string) => void;  }  const UploadImage: React.FC<PropTypes> = ({ -  displayD, setDisplayD, setUserInfo, setUser +  displayD, setDisplayD, callback  }) => { -  const urlRef = useRef<HTMLInputElement>(null); +  const urlRef = useRef<HTMLInputElement | null>(null); +  const [url, setUrl] = useState('');    const handleClose = () => {      setDisplayD(false);    }; -  const updateAvatar = () => { -    const id = localStorage.getItem('userId'); -    const newAvatar = urlRef.current?.value; -    patch(`/users/${id}`, { avatarUrl: newAvatar }).then(res => { -      setUserInfo(res.data); -      setUser(res.data); -    }); +  const update = () => { +    callback(urlRef.current?.value || '');      setDisplayD(false);    }; +  const handleChange = (event:React.ChangeEvent<HTMLInputElement>) => { +    setUrl(event.target.value); +  }; +    return (      <div>        <Dialog open={displayD} onClose={handleClose}> @@ -52,13 +49,14 @@ const UploadImage: React.FC<PropTypes> = ({              fullWidth              autoComplete="off"              inputRef={urlRef} +            onChange={handleChange}            />          </DialogContent>          <DialogActions>            <Button onClick={handleClose} color="primary">              Cancel            </Button> -          <Button onClick={updateAvatar} color="primary"> +          <Button onClick={update} color="primary" disabled={!url.length}>              Submit            </Button>          </DialogActions> diff --git a/src/index.tsx b/src/index.tsx index 49c177b..02f7969 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -104,7 +104,7 @@ const App: React.FC = () => {              setUser={setUser}            />          ) } -        { page.prefix === 'feed' && <FeedPage navigate={navigate} /> } +        { page.prefix === 'feed' && <FeedPage navigate={navigate} user={user} /> }          { page.prefix === 'auth' && <AuthPage logIn={logIn} /> }        </div>        <ScrollTopArrow /> diff --git a/src/pages/FeedPage/FeedPage.tsx b/src/pages/FeedPage/FeedPage.tsx index b7d719e..afe2ef7 100644 --- a/src/pages/FeedPage/FeedPage.tsx +++ b/src/pages/FeedPage/FeedPage.tsx @@ -1,14 +1,17 @@  import React, { useState, useEffect } from 'react'; -import { Poll } from 'which-types'; +import { Poll, User } from 'which-types';  import Feed from '../../components/Feed/Feed';  import { get } from '../../requests'; +import PollSubmission from './PollSubmission'; +  interface PropTypes {    navigate: (prefix: string, id: string) => void; +  user: User | undefined;  } -const FeedPage: React.FC<PropTypes> = ({ navigate }) => { +const FeedPage: React.FC<PropTypes> = ({ navigate, user }) => {    const [polls, setPolls] = useState<Poll[]>([]);    useEffect(() => { @@ -17,7 +20,12 @@ const FeedPage: React.FC<PropTypes> = ({ navigate }) => {      });    }, []); -  return <Feed polls={polls} navigate={navigate} />; +  return ( +    <> +      {user && <PollSubmission user={user} />} +      <Feed polls={polls} navigate={navigate} /> +    </> +  );  };  export default FeedPage; diff --git a/src/pages/FeedPage/PollSubmission.tsx b/src/pages/FeedPage/PollSubmission.tsx new file mode 100644 index 0000000..c76e9fb --- /dev/null +++ b/src/pages/FeedPage/PollSubmission.tsx @@ -0,0 +1,87 @@ +import React, { useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Collapse from '@material-ui/core/Collapse'; +import { +  Button, Card, CardMedia, ClickAwayListener, Divider +} from '@material-ui/core'; +import { User } from 'which-types'; +import PollSubmissionImage from './PollSubmissionImage'; +import UserStrip from '../../components/UserStrip/UserStrip'; +import { post } from '../../requests'; +import { Contents } from './types'; + + +interface PropTypes{ +  user: User; +} +const useStyles = makeStyles(theme => ({ +  root: { +    textAlign: 'center', +    cursor: 'pointer' +  }, +  card: { +    height: 400, +    display: 'flex' +  }, +  images: { +    height: theme.spacing(50), +    width: 300, +    display: 'flex', +    justifyContent: 'center', +    alignItems: 'center', +    cursor: 'pointer' +  }, +  button: { +    width: '100%' +  } +})); + +const PollSubmission: React.FC<PropTypes> = ({ user }) => { +  const classes = useStyles(); +  const [expanded, setExpanded] = useState(false); +  const [contents, setContents] = useState<Contents>({ +    left: { +      url: '' +    }, +    right: { +      url: '' +    } +  }); + +  const handleClickAway = () => { +    setExpanded(false); +  }; + +  const handleClick = () => { +    if (expanded) { +      post('/polls/', { authorId: user._id, contents }).then(res => { +        console.log(res.data); +      }); +    } +    setExpanded(!expanded); +  }; + +  return ( +    <ClickAwayListener onClickAway={handleClickAway}> +      <Card className={classes.root}> +        <Collapse in={expanded} timeout="auto" unmountOnExit> +          <UserStrip user={user} info="" navigate={() => {}} /> +          <Divider /> +          <CardMedia className={classes.card}> +            <PollSubmissionImage which="left" setContents={setContents} /> +            <PollSubmissionImage which="right" setContents={setContents} /> +          </CardMedia> +        </Collapse> +        <Button onClick={handleClick} color="primary" variant="outlined" className={classes.button}> +          { +          expanded === false +            ? 'Create a Poll' +            : 'Submit' +        } +        </Button> +      </Card> +    </ClickAwayListener> +  ); +}; + +export default PollSubmission; diff --git a/src/pages/FeedPage/PollSubmissionImage.tsx b/src/pages/FeedPage/PollSubmissionImage.tsx new file mode 100644 index 0000000..c7e638c --- /dev/null +++ b/src/pages/FeedPage/PollSubmissionImage.tsx @@ -0,0 +1,60 @@ +import React, { useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import CloudUploadIcon from '@material-ui/icons/CloudUpload'; +import { CardActionArea, CardMedia } from '@material-ui/core'; +import UploadImage from '../../components/UploadImage/UploadImage'; +import { Contents } from './types'; + +interface PropTypes { +  setContents: (a: Contents) => void; +  which: 'left' | 'right'; +} + +const useStyles = makeStyles(theme => ({ +  images: { +    height: theme.spacing(50), +    width: 300, +    display: 'flex', +    justifyContent: 'center', +    alignItems: 'center', +    cursor: 'pointer' +  } +})); + +const PollSubmissionImage: React.FC<PropTypes> = ({ setContents, which }) => { +  const classes = useStyles(); +  const [display, setDisplay] = useState(false); +  const [image, setImage] = useState(''); + +  const handleClick = () => { +    setDisplay(!display); +  }; + +  const patchUrl = (url: string) => { +    setImage(url); +    let nextImage; +    which === 'left' ? nextImage = 'right' : nextImage = 'left'; +    setContents({ +      [which]: { +        url +      }, +      [nextImage]: { +        url +      } +    }); +  }; + + +  return ( +    <> +      <CardActionArea onClick={handleClick}> +        <CardMedia className={classes.images} image={image}> +          <CloudUploadIcon /> +        </CardMedia> +      </CardActionArea> +      <UploadImage displayD={display} setDisplayD={setDisplay} callback={patchUrl} /> +    </> +  ); +}; + +export default PollSubmissionImage; diff --git a/src/pages/FeedPage/types.ts b/src/pages/FeedPage/types.ts new file mode 100644 index 0000000..a3c95ff --- /dev/null +++ b/src/pages/FeedPage/types.ts @@ -0,0 +1,7 @@ +export interface ImageData { +  url: string; +} +export interface Contents { +  left?: ImageData; +  right?: ImageData; +} diff --git a/src/pages/ProfilePage/ProfileInfo.tsx b/src/pages/ProfilePage/ProfileInfo.tsx index 2b9227e..fada65f 100644 --- a/src/pages/ProfilePage/ProfileInfo.tsx +++ b/src/pages/ProfilePage/ProfileInfo.tsx @@ -7,6 +7,7 @@ import VerifiedIcon from '@material-ui/icons/CheckCircleOutline';  import MoreMenu from './MoreMenu';  import Highlight from './Highlight';  import UploadImage from '../../components/UploadImage/UploadImage'; +import { patch } from '../../requests';  interface PropTypes { @@ -82,12 +83,21 @@ const ProfileInfo: React.FC<PropTypes> = ({    const classes = useStyles();    const [input, setInput] = useState(false); +    const dateSince = new Date(user?.createdAt || '').toLocaleDateString();    const handleClick = () => {      setInput(!input);    }; +  const patchAvatar = (url: string) => { +    const id = localStorage.getItem('userId'); +    patch(`/users/${id}`, { avatarUrl: url }).then(res => { +      setUserInfo(res.data); +      setUser(res.data); +    }); +  }; +    return (      <div className={classes.root}>        { @@ -112,7 +122,7 @@ const ProfileInfo: React.FC<PropTypes> = ({                    <Avatar className={classes.avatar} src={user?.avatarUrl} />                  </Badge>                </div> -              <UploadImage displayD={input} setDisplayD={setInput} setUserInfo={setUserInfo} setUser={setUser} /> +              <UploadImage displayD={input} setDisplayD={setInput} callback={patchAvatar} />              </div>  )            : <Avatar className={classes.avatar} src={user?.avatarUrl} /> diff --git a/src/types.d.ts b/src/types.d.ts index 73346ce..4b1ffd6 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -2,4 +2,3 @@ export interface Page {    prefix: string;    id: string;  } - | 
