Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions src/components/PollCard/PollCard.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { Card, CardActionArea, Typography } from '@material-ui/core/';
import { Card, CardActionArea, Typography, IconButton } from '@material-ui/core/';
import { Which, Poll } from 'which-types';
import { useSnackbar } from 'notistack';
import DeleteIcon from '@material-ui/icons/Delete';

import PercentageBar from './PercentageBar';
import UserStrip from '../UserStrip/UserStrip';
import DateString from '../DateString/DateString';
import BackgroundImage from '../Image/BackgroundImage';
import { post } from '../../requests';
import requests from '../../requests';
import { useAuth } from '../../hooks/useAuth';

interface PropTypes {
poll: Poll;
setPoll: (poll: Poll) => void;
setPoll: (poll: Poll | null) => void;
}

const useStyles = makeStyles(theme => ({
Expand Down Expand Up @@ -48,10 +49,10 @@ const PollCard: React.FC<PropTypes> = React.memo(({ poll, setPoll }) => {
const classes = useStyles();
const { author, contents: { left, right }, vote } = poll;
const { enqueueSnackbar } = useSnackbar();
const { isAuthenticated } = useAuth();
const { user } = useAuth();

const handleVote = (which: Which) => () => {
if (!isAuthenticated) {
if (!user) {
enqueueSnackbar('Unauthorized users can not vote in polls', {
variant: 'error'
});
Expand All @@ -71,10 +72,15 @@ const PollCard: React.FC<PropTypes> = React.memo(({ poll, setPoll }) => {
};
setPoll(newPoll);

post('votes/', newVote);
requests.post('votes/', newVote);
}
};

const handleDelete = async () => {
await requests.delete(`polls/${poll._id}`);
setPoll(null);
};

let leftPercentage;
let rightPercentage;

Expand All @@ -90,7 +96,13 @@ const PollCard: React.FC<PropTypes> = React.memo(({ poll, setPoll }) => {

return (
<Card elevation={3}>
<UserStrip user={author} info={<DateString value={poll.createdAt} />} />
<UserStrip
user={author}
info={<DateString value={poll.createdAt} />}
action={author._id === user?._id ? (
<IconButton onClick={handleDelete}><DeleteIcon /></IconButton>
) : undefined}
/>
{poll.description && (
<Typography className={classes.description}>
{poll.description}
Expand Down
7 changes: 4 additions & 3 deletions src/components/PollsList/RenderItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ const RenderItem: React.FC<PropTypes> = React.memo(({
}) => {
const classes = useStyles();
const poll = polls[index];
const setPoll = useCallback((newPoll: Poll) => {
const newPolls = [...polls];
newPolls[index] = newPoll;
const setPoll = useCallback((newPoll: Poll | null) => {
let newPolls = polls;
if (newPoll) newPolls[index] = newPoll;
else newPolls = newPolls.filter((poll, pollIndex) => pollIndex !== index);

// Force-update list-size so everything re-renders
mutate([], false);
Expand Down
91 changes: 46 additions & 45 deletions src/components/UserStrip/UserStrip.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,46 @@
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import VerifiedIcon from '@material-ui/icons/CheckCircleOutline';
import { CardHeader } from '@material-ui/core/';
import { User } from 'which-types';

import Avatar from '../Avatar/Avatar';


interface PropTypes {
user: User;
info?: string | JSX.Element
}


const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
alignItems: 'center'
},
verified: {
marginLeft: theme.spacing(0.5),
width: theme.spacing(2),
height: theme.spacing(2)
}
}));


const UserStrip: React.FC<PropTypes> = ({ user, info }) => {
const classes = useStyles();
const { username, verified } = user;

const avatar = <Avatar user={user} />;

const title = (
<div className={classes.root}>
{username}
{verified && <VerifiedIcon color="primary" className={classes.verified} />}
</div>
);

return <CardHeader avatar={avatar} title={title} subheader={info} />;
};

export default UserStrip;
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import VerifiedIcon from '@material-ui/icons/CheckCircleOutline';
import { CardHeader } from '@material-ui/core/';
import { User } from 'which-types';

import Avatar from '../Avatar/Avatar';


interface PropTypes {
user: User;
info?: string | JSX.Element;
action?: JSX.Element;
}


const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
alignItems: 'center'
},
verified: {
marginLeft: theme.spacing(0.5),
width: theme.spacing(2),
height: theme.spacing(2)
}
}));


const UserStrip: React.FC<PropTypes> = ({ user, info, action }) => {
const classes = useStyles();
const { username, verified } = user;

const avatar = <Avatar user={user} />;

const title = (
<div className={classes.root}>
{username}
{verified && <VerifiedIcon color="primary" className={classes.verified} />}
</div>
);

return <CardHeader avatar={avatar} title={title} subheader={info} action={action} />;
};

export default UserStrip;