diff options
Diffstat (limited to 'src/pages/HomePage')
| -rw-r--r-- | src/pages/HomePage/HomePage.tsx | 73 | ||||
| -rw-r--r-- | src/pages/HomePage/ReviewForm.tsx | 74 | 
2 files changed, 140 insertions, 7 deletions
| diff --git a/src/pages/HomePage/HomePage.tsx b/src/pages/HomePage/HomePage.tsx index f00289a..5a33b42 100644 --- a/src/pages/HomePage/HomePage.tsx +++ b/src/pages/HomePage/HomePage.tsx @@ -4,9 +4,10 @@ import {    Divider,    Grid,    Button, -  Link +  Link, +  useMediaQuery  } from '@material-ui/core/'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles, useTheme } from '@material-ui/core/styles';  import TrendingUpIcon from '@material-ui/icons/TrendingUp';  import { Rating } from '@material-ui/lab';  import { Feedback } from 'which-types'; @@ -14,6 +15,8 @@ import { Feedback } from 'which-types';  import { useNavigate } from '../../hooks/useNavigate';  import { useAuth } from '../../hooks/useAuth';  import { get } from '../../requests'; +import ReviewCard from '../../components/ReviewCard/ReviewCard'; +import ReviewForm from './ReviewForm';  const useStyles = makeStyles(theme => ({    root: { @@ -29,6 +32,11 @@ const useStyles = makeStyles(theme => ({    },    signup: {      marginLeft: theme.spacing(2) +  }, +  reviews: { +    [theme.breakpoints.up('md')]: { +      padding: theme.spacing(0, 10) +    }    }  })); @@ -36,7 +44,9 @@ const HomePage: React.FC = () => {    const [feedbacks, setFeedbacks] = useState<Feedback[]>([]);    const classes = useStyles();    const { navigate } = useNavigate(); -  const { isAuthenticated } = useAuth(); +  const { isAuthenticated, user } = useAuth(); +  const theme = useTheme(); +  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));    const rating = feedbacks.length && feedbacks.reduce(      (acc: number, feedback: Feedback) => acc + feedback.score, @@ -62,6 +72,40 @@ const HomePage: React.FC = () => {    const ReactLink = <Link href="https://reactjs.org/">React</Link>;    const FeathersLink = <Link href="https://feathersjs.com">Feathers</Link>;    const MUILink = <Link href="https://material-ui.com">Material-UI</Link>; +  const EmailLink = <Link href="mailto: eug-vs@keemail.me">eug-vs@keemail.me</Link>; + +  const Reviews = ( +    <div className={classes.reviews}> +      {feedbacks.map(feedback => <ReviewCard feedback={feedback} />)} +    </div> +  ); + +  const FeedbackSection = feedbacks.findIndex((feedback: Feedback) => feedback.author._id === user?._id) >= 0 ? ( +    <p> +      You have already left feedback for this version. +      If you have more to say, please open GitHub issue or contact us directly via email: {EmailLink}. +      Alternatively, you can just wait for another application patch to come out. +    </p> +  ) : ( +    <> +      <p> +        Here you can share your thougts about Which with us! +        Note that you can ony leave feedback once per application version (there will be plenty of them later). +      </p> +      {isAuthenticated() ? <ReviewForm /> : ( +        <> +          <p> You must be authorized to leave feedback.</p> +          <Button +            variant="outlined" +            color="primary" +            onClick={handleSignUp} +          > +            sign in +          </Button> +        </> +      )} +    </> +  );    return (      <div className={classes.root}> @@ -72,14 +116,17 @@ const HomePage: React.FC = () => {                <img src={`${process.env.PUBLIC_URL}/which-logo-512.png`} alt="logo" className={classes.logo} />              </Grid>              <Grid item> -              <Rating value={rating} readOnly size="large" /> +              {rating && <Rating value={rating} readOnly size="large" />}              </Grid>              <Grid item> -              <Typography variant="h5" className={classes.score}> -                User score: {rating.toFixed(1)} -              </Typography> +              {rating && ( +                <Typography variant="h5" className={classes.score}> +                  User score: {rating.toFixed(1)} +                </Typography> +              )}              </Grid>            </Grid> +          {isMobile || Reviews}          </Grid>          <Grid item xs={12} md={5}>            <Grid container direction="column" spacing={6}> @@ -133,6 +180,18 @@ const HomePage: React.FC = () => {                  </Button>                </Typography>              </Grid> +            <Grid item> +              <Typography variant="h4"> Leave feedback </Typography> +              <Divider /> +              <Typography> +                {FeedbackSection} +              </Typography> +            </Grid> +            {isMobile && ( +              <Grid item> +                {Reviews} +              </Grid> +            )}            </Grid>          </Grid>        </Grid> diff --git a/src/pages/HomePage/ReviewForm.tsx b/src/pages/HomePage/ReviewForm.tsx new file mode 100644 index 0000000..7ad0880 --- /dev/null +++ b/src/pages/HomePage/ReviewForm.tsx @@ -0,0 +1,74 @@ +import React, { useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import { TextField, Button } from '@material-ui/core'; +import { Rating } from '@material-ui/lab'; +import { useSnackbar } from 'notistack'; + +import { post } from '../../requests'; +import { useNavigate } from '../../hooks/useNavigate'; + +const version = 'v1.0.0'; + +const useStyles = makeStyles(theme => ({ +  root: { +    display: 'flex', +    flexDirection: 'column' +  }, +  textField: { +    margin: theme.spacing(2, 0) +  } +})); + +const ReviewForm: React.FC = () => { +  const [contents, setContents] = useState<string>(''); +  const [score, setScore] = useState<number>(0); +  const classes = useStyles(); +  const { navigate } = useNavigate(); +  const { enqueueSnackbar } = useSnackbar(); + +  const handleSubmit = (): void => { +    if (contents && score) { +      post('/feedback', { contents, score, version }).then(() => { +        enqueueSnackbar('Your feedback has been submitted!', { +          variant: 'success' +        }); +        navigate('feed'); +      }); +    } +  }; + +  const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => { +    setContents(event.target?.value || ''); +  }; + +  const handleChangeRating = (event: React.ChangeEvent<Record<string, unknown>>, newScore: number | null): void => { +    setScore(newScore || 0); +  }; + +  return ( +    <div className={classes.root}> +      <Rating value={score} onChange={handleChangeRating} size="large" /> +      <TextField +        value={contents} +        onChange={handleChange} +        label="Feedback" +        variant="outlined" +        className={classes.textField} +        rows={4} +        multiline +      /> +      <div> +        <Button +          variant="contained" +          color="primary" +          size="large" +          onClick={handleSubmit} +        > +          submit +        </Button> +      </div> +    </div> +  ); +}; + +export default ReviewForm; | 
