2020-11-19 17:11:23 +03:00
|
|
|
import React, { useState } from 'react'
|
|
|
|
import { Link, useHistory } from 'react-router-dom'
|
2020-11-27 18:10:02 +03:00
|
|
|
import moment from 'moment'
|
2020-11-19 17:11:23 +03:00
|
|
|
|
|
|
|
import useAuth from '@wasp/auth/useAuth.js'
|
|
|
|
import logout from '@wasp/auth/logout.js'
|
|
|
|
import updateUser from '@wasp/actions/updateUser'
|
|
|
|
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'
|
|
|
|
import setArticleFavorited from '@wasp/actions/setArticleFavorited'
|
2020-11-27 18:10:02 +03:00
|
|
|
import followUser from '@wasp/actions/followUser'
|
2020-11-19 17:11:23 +03:00
|
|
|
import { useQuery } from '@wasp/queries'
|
|
|
|
|
2020-11-19 17:32:37 +03:00
|
|
|
import Navbar from './Navbar'
|
|
|
|
import smileyImageUrl from './smiley.jpg'
|
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
const UserProfilePage = (props) => {
|
|
|
|
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 ? (
|
|
|
|
<div>
|
2020-11-19 17:32:37 +03:00
|
|
|
<Navbar />
|
|
|
|
|
|
|
|
<img src={user.profilePictureUrl || smileyImageUrl} />
|
2020-11-19 17:11:23 +03:00
|
|
|
<p> { user.username } </p>
|
|
|
|
<p> { user.bio } </p>
|
2020-11-27 18:10:02 +03:00
|
|
|
{ me && me.username === username && (
|
|
|
|
<div>
|
|
|
|
<Link to='/settings'>Edit Profile Settings</Link>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{ me && me.username !== username && (
|
|
|
|
<div>
|
|
|
|
<FollowUserButton user={user} />
|
|
|
|
</div>
|
|
|
|
)}
|
2020-11-20 20:22:49 +03:00
|
|
|
|
|
|
|
<Articles user={user} />
|
|
|
|
</div>
|
|
|
|
) : 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
|
|
|
|
}
|
|
|
|
|
2020-11-20 20:22:49 +03:00
|
|
|
const Articles = (props) => {
|
2020-11-27 00:48:35 +03:00
|
|
|
const user = props.user
|
|
|
|
|
2020-11-27 18:10:02 +03:00
|
|
|
const { data: authoredArticles } = useQuery(getArticlesByUser, { username: props.user.username })
|
2020-11-27 00:48:35 +03:00
|
|
|
const { data: favoritedArticles } = useQuery(getFavoritedArticles, { username: props.user.username })
|
2020-11-20 20:22:49 +03:00
|
|
|
|
2020-11-27 00:48:35 +03:00
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<h1> My Articles </h1>
|
2020-11-27 18:10:02 +03:00
|
|
|
<ArticleList articles={authoredArticles} />
|
2020-11-27 00:48:35 +03:00
|
|
|
<h1> Favorited Articles </h1>
|
|
|
|
<ArticleList articles={favoritedArticles} />
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2020-11-20 20:22:49 +03:00
|
|
|
|
2020-11-27 00:48:35 +03:00
|
|
|
const ArticleList = (props) => {
|
|
|
|
const articles = props.articles
|
|
|
|
// TODO: Should I have pagination here, probably I should?
|
2020-11-20 20:22:49 +03:00
|
|
|
return articles ? (
|
|
|
|
<div>
|
|
|
|
{ articles.map(article => <Article article={article} key={article.id} />) }
|
2020-11-19 17:11:23 +03:00
|
|
|
</div>
|
|
|
|
) : null
|
|
|
|
}
|
|
|
|
|
2020-11-20 20:22:49 +03:00
|
|
|
const Article = (props) => {
|
|
|
|
const article = props.article
|
2020-11-27 00:48:35 +03:00
|
|
|
|
|
|
|
const toggleArticleFavorited = async () => {
|
|
|
|
await setArticleFavorited({ id: article.id, favorited: !article.favorited })
|
|
|
|
}
|
|
|
|
|
2020-11-20 20:22:49 +03:00
|
|
|
return (
|
2020-11-27 18:10:02 +03:00
|
|
|
<div style={{ border: '1px solid black' }}>
|
2020-11-24 23:10:26 +03:00
|
|
|
<Link to={`/article/${article.slug}`}>
|
2020-11-20 20:22:49 +03:00
|
|
|
<h2> { article.title } </h2>
|
|
|
|
</Link>
|
|
|
|
<p> { article.description } </p>
|
2020-11-27 18:10:02 +03:00
|
|
|
<p>
|
|
|
|
<em> Tags: </em>
|
|
|
|
{ article.tags.map(t => t.name).join('; ') }
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
<img src={ article.user.profilePictureUrl || smileyImageUrl } width='30px' />
|
|
|
|
<div> { article.user.username } </div>
|
|
|
|
<div> { moment(article.createdAt).format('MMMM DD, YYYY') } </div>
|
|
|
|
</p>
|
2020-11-27 00:48:35 +03:00
|
|
|
<div>
|
|
|
|
<button onClick={toggleArticleFavorited}>
|
|
|
|
{ article.favorited ? 'Unlike' : 'Like' } ({ article.favoritesCount })
|
|
|
|
</button>
|
|
|
|
</div>
|
2020-11-20 20:22:49 +03:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-11-19 17:11:23 +03:00
|
|
|
export default UserProfilePage
|