2020-11-19 17:11:23 +03:00
|
|
|
import React, { useState } from 'react'
|
|
|
|
import { Link, useHistory } from 'react-router-dom'
|
|
|
|
|
2021-02-05 12:57:26 +03:00
|
|
|
import Container from '@material-ui/core/Container'
|
|
|
|
import TextField from '@material-ui/core/TextField'
|
|
|
|
import Grid from '@material-ui/core/Grid'
|
|
|
|
import Tabs from '@material-ui/core/Tabs'
|
|
|
|
import Tab from '@material-ui/core/Tab'
|
|
|
|
import Box from '@material-ui/core/Box'
|
|
|
|
import Button from '@material-ui/core/Button'
|
|
|
|
import { makeStyles } from '@material-ui/core/styles'
|
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
import useAuth from '@wasp/auth/useAuth.js'
|
2020-11-30 20:11:40 +03:00
|
|
|
import { useQuery } from '@wasp/queries'
|
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
import getUser from '@wasp/queries/getUser'
|
2020-11-20 20:22:49 +03:00
|
|
|
import getArticlesByUser from '@wasp/queries/getArticlesByUser'
|
2020-11-27 00:48:35 +03:00
|
|
|
import getFavoritedArticles from '@wasp/queries/getFavoritedArticles'
|
2020-11-27 18:10:02 +03:00
|
|
|
import followUser from '@wasp/actions/followUser'
|
2020-11-30 20:11:40 +03:00
|
|
|
import Navbar from '../../Navbar'
|
|
|
|
import ArticleListPaginated from '../../article/components/ArticleListPaginated'
|
|
|
|
import smileyImageUrl from '../../smiley.jpg'
|
2020-11-19 17:32:37 +03:00
|
|
|
|
2021-02-05 12:57:26 +03:00
|
|
|
const useStyles = makeStyles((theme) => ({
|
|
|
|
articles: {
|
|
|
|
marginTop: theme.spacing(5)
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
const UserProfilePage = (props) => {
|
2021-02-05 12:57:26 +03:00
|
|
|
const classes = useStyles()
|
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
const history = useHistory()
|
|
|
|
|
2020-11-27 18:10:02 +03:00
|
|
|
const { data: me } = useAuth()
|
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
const username = props.match.params.username
|
|
|
|
const { data: user, error: userError } = useQuery(getUser, { username })
|
|
|
|
|
2020-11-19 17:32:37 +03:00
|
|
|
// NOTE: use-query will retry multiple times in case of error, making user
|
|
|
|
// wait relatively long before giving up on for example 404 and returning error,
|
|
|
|
// while on the other hand we would probably like it to give up on 404 immediatelly!
|
|
|
|
// Should we modify react-query default settings to not do any retrying?
|
2020-11-19 17:11:23 +03:00
|
|
|
if (userError) {
|
|
|
|
console.log(userError)
|
|
|
|
history.push("/")
|
|
|
|
}
|
|
|
|
|
|
|
|
return user ? (
|
2021-02-05 12:57:26 +03:00
|
|
|
<Container maxWidth="lg">
|
2020-11-19 17:32:37 +03:00
|
|
|
<Navbar />
|
|
|
|
|
2021-02-05 12:57:26 +03:00
|
|
|
<Grid container direction="row" justify="center">
|
|
|
|
<Grid item xs={8}>
|
|
|
|
<img src={user.profilePictureUrl || smileyImageUrl} />
|
|
|
|
<p> { user.username } </p>
|
|
|
|
<p> { user.bio } </p>
|
|
|
|
{ me && me.username === username && (
|
|
|
|
<div>
|
|
|
|
<Button component={ Link } to="/settings" variant="contained" color="primary">
|
|
|
|
Edit Profile Settings
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{ me && me.username !== username && (
|
|
|
|
<div>
|
|
|
|
<FollowUserButton user={user} />
|
|
|
|
</div>
|
|
|
|
)}
|
2020-11-20 20:22:49 +03:00
|
|
|
|
2021-02-05 12:57:26 +03:00
|
|
|
<Articles user={user} />
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Container>
|
2020-11-20 20:22:49 +03:00
|
|
|
) : null
|
|
|
|
}
|
|
|
|
|
2020-11-27 18:10:02 +03:00
|
|
|
const FollowUserButton = (props) => {
|
|
|
|
const user = props.user
|
|
|
|
const { data: me } = useAuth()
|
|
|
|
|
|
|
|
const toggleFollow = async () => {
|
|
|
|
try {
|
|
|
|
followUser({ username: user.username, follow: !user.following })
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err)
|
|
|
|
window.alert(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return me && me.username !== user.username ? (
|
|
|
|
<button onClick={toggleFollow}>
|
|
|
|
{ user.following ? 'Unfollow' : 'Follow' }
|
|
|
|
</button>
|
|
|
|
) : null
|
|
|
|
}
|
|
|
|
|
2021-02-05 12:57:26 +03:00
|
|
|
const useStylesFeedTabs = makeStyles((theme) => ({
|
|
|
|
root: {
|
|
|
|
marginBottom: theme.spacing(2),
|
|
|
|
},
|
|
|
|
}))
|
|
|
|
|
|
|
|
const ProfileFeedTabs = (props) => {
|
|
|
|
const classes = useStylesFeedTabs()
|
|
|
|
|
|
|
|
const [value, setValue] = useState(0);
|
|
|
|
|
|
|
|
const handleChange = (event, newValue) => setValue(newValue)
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Tabs value={value} onChange={handleChange} className={classes.root}>
|
|
|
|
<Tab label="My Articles" id="feed-tabpanel-0"/>
|
|
|
|
<Tab label="Favorited articles" id="feed-tabpanel-1"/>
|
|
|
|
</Tabs>
|
|
|
|
|
|
|
|
<TabPanel value={value} index={0}>
|
|
|
|
<ArticleListPaginated
|
|
|
|
query={getArticlesByUser}
|
|
|
|
makeQueryArgs={({ skip, take }) => ({ username: props.user.username, skip, take })}
|
|
|
|
pageSize={5}
|
|
|
|
/>
|
|
|
|
</TabPanel>
|
|
|
|
|
|
|
|
<TabPanel value={value} index={1}>
|
|
|
|
<ArticleListPaginated
|
|
|
|
query={getFavoritedArticles}
|
|
|
|
makeQueryArgs={({ skip, take }) => ({ username: props.user.username, skip, take })}
|
|
|
|
pageSize={5}
|
|
|
|
/>
|
|
|
|
</TabPanel>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
function TabPanel(props) {
|
|
|
|
const { children, value, index, ...other } = props
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
role="tabpanel"
|
|
|
|
hidden={value !== index}
|
|
|
|
id={`feed-tabpanel-${index}`}
|
|
|
|
{...other}
|
|
|
|
>
|
|
|
|
{value === index && (
|
|
|
|
<Box>
|
|
|
|
{children}
|
|
|
|
</Box>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-11-20 20:22:49 +03:00
|
|
|
const Articles = (props) => {
|
2021-02-05 12:57:26 +03:00
|
|
|
const classes = useStyles()
|
|
|
|
|
2020-11-27 00:48:35 +03:00
|
|
|
const user = props.user
|
|
|
|
|
|
|
|
return (
|
2021-02-05 12:57:26 +03:00
|
|
|
<div className={classes.articles}>
|
|
|
|
<ProfileFeedTabs {...props} />
|
2020-11-27 00:48:35 +03:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2020-11-20 20:22:49 +03:00
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
export default UserProfilePage
|