Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
hfpp2012
/
merng
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 4c47e536
authored
Nov 22, 2019
by
qiuzhi99
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
23_like_post
1 parent
63d0cc84
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
172 additions
and
50 deletions
client/package.json
client/src/components/LikeButton.js
client/src/components/PostCard.js
client/src/components/PostForm.js
client/src/pages/Home.js
client/src/utils/grahpql.js
client/yarn.lock
graphql/resolvers/posts.js
graphql/resolvers/users.js
client/package.json
View file @
4c47e53
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
"jwt-decode"
:
"^2.2.0"
,
"jwt-decode"
:
"^2.2.0"
,
"moment"
:
"^2.24.0"
,
"moment"
:
"^2.24.0"
,
"react"
:
"^16.10.2"
,
"react"
:
"^16.10.2"
,
"react-apollo"
:
"^3.1.3"
,
"react-dom"
:
"^16.10.2"
,
"react-dom"
:
"^16.10.2"
,
"react-router-dom"
:
"^5.1.2"
,
"react-router-dom"
:
"^5.1.2"
,
"react-scripts"
:
"3.2.0"
,
"react-scripts"
:
"3.2.0"
,
...
...
client/src/components/LikeButton.js
0 → 100644
View file @
4c47e53
import
React
,
{
useState
,
useEffect
}
from
"react"
;
import
gql
from
"graphql-tag"
;
import
{
useMutation
}
from
"@apollo/react-hooks"
;
import
{
Button
,
Icon
,
Label
}
from
"semantic-ui-react"
;
import
{
Link
}
from
"react-router-dom"
;
function
LikeButton
({
user
,
post
:
{
id
,
likes
,
likeCount
}
})
{
const
[
liked
,
setLiked
]
=
useState
(
false
);
const
[
likePost
]
=
useMutation
(
LIKE_POST_MUTATION
,
{
variables
:
{
postId
:
id
}
});
useEffect
(()
=>
{
if
(
user
&&
likes
.
find
(
like
=>
like
.
username
===
user
.
username
))
{
setLiked
(
true
);
}
else
setLiked
(
false
);
},
[
user
,
likes
]);
const
likeButton
=
user
?
(
liked
?
(
<
Button
color
=
"teal"
>
<
Icon
name
=
"heart"
/>
<
/Button
>
)
:
(
<
Button
color
=
"teal"
basic
>
<
Icon
name
=
"heart"
/>
<
/Button
>
)
)
:
(
<
Button
as
=
{
Link
}
to
=
"/login"
color
=
"teal"
basic
>
<
Icon
name
=
"heart"
/>
<
/Button
>
);
return
(
<
Button
as
=
"div"
labelPosition
=
"right"
onClick
=
{
likePost
}
>
{
likeButton
}
<
Label
basic
color
=
"teal"
pointing
=
"left"
>
{
likeCount
}
<
/Label
>
<
/Button
>
);
}
const
LIKE_POST_MUTATION
=
gql
`
mutation likePost($postId: ID!) {
likePost(postId: $postId) {
id
likes {
id
username
}
likeCount
}
}
`
;
export
default
LikeButton
;
client/src/components/PostCard.js
View file @
4c47e53
import
React
from
"react"
;
import
React
,
{
useContext
}
from
"react"
;
import
{
Card
,
Image
,
Button
,
Label
,
Icon
}
from
"semantic-ui-react"
;
import
{
Card
,
Image
,
Button
,
Label
,
Icon
}
from
"semantic-ui-react"
;
import
moment
from
"moment"
;
import
moment
from
"moment"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
AuthContext
}
from
"../context/auth"
;
import
LikeButton
from
"./LikeButton"
;
const
PostCard
=
({
const
PostCard
=
({
post
:
{
username
,
body
,
id
,
createdAt
,
likeCount
,
commentCount
,
likes
}
post
:
{
username
,
body
,
id
,
createdAt
,
likeCount
,
commentCount
,
likes
}
})
=>
{
})
=>
{
const
likePost
=
()
=>
{}
;
const
{
user
}
=
useContext
(
AuthContext
)
;
return
(
return
(
<
Card
fluid
>
<
Card
fluid
>
<
Card
.
Content
>
<
Card
.
Content
>
...
@@ -22,15 +24,8 @@ const PostCard = ({
...
@@ -22,15 +24,8 @@ const PostCard = ({
<
Card
.
Description
>
{
body
}
<
/Card.Description
>
<
Card
.
Description
>
{
body
}
<
/Card.Description
>
<
/Card.Content
>
<
/Card.Content
>
<
Card
.
Content
extra
>
<
Card
.
Content
extra
>
<
Button
as
=
"div"
labelPosition
=
"right"
onClick
=
{
likePost
}
>
<
LikeButton
user
=
{
user
}
post
=
{{
id
,
likes
,
likeCount
}}
/
>
<
Button
color
=
"teal"
basic
>
<
Button
labelPosition
=
"right"
as
=
{
Link
}
to
=
{
`/posts/
${
id
}
`
}
>
<
Icon
name
=
"heart"
/>
<
/Button
>
<
Label
basic
color
=
"teal"
pointing
=
"left"
>
{
likeCount
}
<
/Label
>
<
/Button
>
<
Button
as
=
"div"
labelPosition
=
"right"
>
<
Button
color
=
"blue"
basic
>
<
Button
color
=
"blue"
basic
>
<
Icon
name
=
"comment"
/>
<
Icon
name
=
"comment"
/>
<
/Button
>
<
/Button
>
...
@@ -38,6 +33,16 @@ const PostCard = ({
...
@@ -38,6 +33,16 @@ const PostCard = ({
{
commentCount
}
{
commentCount
}
<
/Label
>
<
/Label
>
<
/Button
>
<
/Button
>
{
user
&&
user
.
username
===
username
&&
(
<
Button
onClick
=
{()
=>
console
.
log
(
"deleted"
)}
as
=
"div"
color
=
"red"
floated
=
"right"
>
<
Icon
name
=
"trash"
style
=
{{
margin
:
0
}}
/
>
<
/Button
>
)}
<
/Card.Content
>
<
/Card.Content
>
<
/Card
>
<
/Card
>
);
);
...
...
client/src/components/PostForm.js
View file @
4c47e53
...
@@ -3,6 +3,7 @@ import { Form, Button } from "semantic-ui-react";
...
@@ -3,6 +3,7 @@ import { Form, Button } from "semantic-ui-react";
import
{
useForm
}
from
"../utils/hook"
;
import
{
useForm
}
from
"../utils/hook"
;
import
{
useMutation
}
from
"@apollo/react-hooks"
;
import
{
useMutation
}
from
"@apollo/react-hooks"
;
import
gql
from
"graphql-tag"
;
import
gql
from
"graphql-tag"
;
import
{
FETCH_POSTS_QUERY
}
from
"../utils/grahpql"
;
function
PostForm
()
{
function
PostForm
()
{
const
{
onChange
,
onSubmit
,
values
}
=
useForm
(
createPostCallback
,
{
const
{
onChange
,
onSubmit
,
values
}
=
useForm
(
createPostCallback
,
{
...
@@ -10,14 +11,24 @@ function PostForm() {
...
@@ -10,14 +11,24 @@ function PostForm() {
});
});
const
[
createPost
,
{
error
}]
=
useMutation
(
CREATE_POST_MUTATION
,
{
const
[
createPost
,
{
error
}]
=
useMutation
(
CREATE_POST_MUTATION
,
{
update
(
_
,
result
)
{
update
(
proxy
,
{
data
:
{
createPost
}
}
)
{
values
.
body
=
""
;
values
.
body
=
""
;
const
{
getPosts
}
=
proxy
.
readQuery
({
query
:
FETCH_POSTS_QUERY
});
proxy
.
writeQuery
({
query
:
FETCH_POSTS_QUERY
,
data
:
{
getPosts
:
getPosts
.
concat
(
createPost
)
}
});
},
},
variables
:
values
variables
:
values
});
});
console
.
dir
(
error
);
function
createPostCallback
()
{
function
createPostCallback
()
{
createPost
();
createPost
();
}
}
...
...
client/src/pages/Home.js
View file @
4c47e53
import
React
,
{
useContext
}
from
"react"
;
import
React
,
{
useContext
}
from
"react"
;
import
gql
from
"graphql-tag"
;
import
{
useQuery
}
from
"@apollo/react-hooks"
;
import
{
useQuery
}
from
"@apollo/react-hooks"
;
import
{
Grid
}
from
"semantic-ui-react"
;
import
{
Grid
,
Transition
}
from
"semantic-ui-react"
;
import
PostCard
from
"../components/PostCard"
;
import
PostCard
from
"../components/PostCard"
;
import
{
AuthContext
}
from
"../context/auth"
;
import
{
AuthContext
}
from
"../context/auth"
;
import
PostForm
from
"../components/PostForm"
;
import
PostForm
from
"../components/PostForm"
;
import
{
FETCH_POSTS_QUERY
}
from
"../utils/grahpql"
;
const
FETCH_POSTS_QUERY
=
gql
`
function
Home
()
{
{
getPosts {
id
body
createdAt
username
likeCount
likes {
username
}
commentCount
comments {
id
username
createdAt
body
}
}
}
`
;
const
Home
=
()
=>
{
const
{
user
}
=
useContext
(
AuthContext
);
const
{
user
}
=
useContext
(
AuthContext
);
const
{
loading
,
data
}
=
useQuery
(
FETCH_POSTS_QUERY
);
const
{
loading
,
data
}
=
useQuery
(
FETCH_POSTS_QUERY
);
...
@@ -46,16 +24,18 @@ const Home = () => {
...
@@ -46,16 +24,18 @@ const Home = () => {
{
loading
?
(
{
loading
?
(
<
h1
>
Loading
posts
...
<
/h1
>
<
h1
>
Loading
posts
...
<
/h1
>
)
:
(
)
:
(
data
.
getPosts
&&
<
Transition
.
Group
>
data
.
getPosts
.
map
(
post
=>
(
{
data
.
getPosts
&&
<
Grid
.
Column
key
=
{
post
.
id
}
style
=
{{
marginBottom
:
20
}}
>
data
.
getPosts
.
map
(
post
=>
(
<
PostCard
post
=
{
post
}
/
>
<
Grid
.
Column
key
=
{
post
.
id
}
style
=
{{
marginBottom
:
20
}}
>
<
/Grid.Column
>
<
PostCard
post
=
{
post
}
/
>
))
<
/Grid.Column
>
))}
<
/Transition.Group
>
)}
)}
<
/Grid.Row
>
<
/Grid.Row
>
<
/Grid
>
<
/Grid
>
);
);
}
;
}
export
default
Home
;
export
default
Home
;
client/src/utils/grahpql.js
0 → 100644
View file @
4c47e53
import
gql
from
"graphql-tag"
;
export
const
FETCH_POSTS_QUERY
=
gql
`
{
getPosts {
id
body
createdAt
username
likeCount
likes {
username
}
commentCount
comments {
id
username
createdAt
body
}
}
}
`
;
client/yarn.lock
View file @
4c47e53
...
@@ -10,6 +10,28 @@
...
@@ -10,6 +10,28 @@
ts-invariant "^0.4.4"
ts-invariant "^0.4.4"
tslib "^1.10.0"
tslib "^1.10.0"
"@apollo/react-components@^3.1.3":
version "3.1.3"
resolved "https://registry.npm.taobao.org/@apollo/react-components/download/@apollo/react-components-3.1.3.tgz#8f6726847cd9b0eb4b22586b1a038d29aa8b1da4"
integrity sha1-j2cmhHzZsOtLIlhrGgONKaqLHaQ=
dependencies:
"@apollo/react-common" "^3.1.3"
"@apollo/react-hooks" "^3.1.3"
prop-types "^15.7.2"
ts-invariant "^0.4.4"
tslib "^1.10.0"
"@apollo/react-hoc@^3.1.3":
version "3.1.3"
resolved "https://registry.npm.taobao.org/@apollo/react-hoc/download/@apollo/react-hoc-3.1.3.tgz#5742ee74f57611058f5ea1f966c38fc6429dda7b"
integrity sha1-V0LudPV2EQWPXqH5ZsOPxkKd2ns=
dependencies:
"@apollo/react-common" "^3.1.3"
"@apollo/react-components" "^3.1.3"
hoist-non-react-statics "^3.3.0"
ts-invariant "^0.4.4"
tslib "^1.10.0"
"@apollo/react-hooks@^3.1.3":
"@apollo/react-hooks@^3.1.3":
version "3.1.3"
version "3.1.3"
resolved "https://registry.npm.taobao.org/@apollo/react-hooks/download/@apollo/react-hooks-3.1.3.tgz#ad42c7af78e81fee0f30e53242640410d5bd0293"
resolved "https://registry.npm.taobao.org/@apollo/react-hooks/download/@apollo/react-hooks-3.1.3.tgz#ad42c7af78e81fee0f30e53242640410d5bd0293"
...
@@ -20,6 +42,15 @@
...
@@ -20,6 +42,15 @@
ts-invariant "^0.4.4"
ts-invariant "^0.4.4"
tslib "^1.10.0"
tslib "^1.10.0"
"@apollo/react-ssr@^3.1.3":
version "3.1.3"
resolved "https://registry.npm.taobao.org/@apollo/react-ssr/download/@apollo/react-ssr-3.1.3.tgz#0791280d5b735f42f87dbfe849564e78843045bc"
integrity sha1-B5EoDVtzX0L4fb/oSVZOeIQwRbw=
dependencies:
"@apollo/react-common" "^3.1.3"
"@apollo/react-hooks" "^3.1.3"
tslib "^1.10.0"
"@babel/code-frame@7.5.5", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5":
"@babel/code-frame@7.5.5", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5":
version "7.5.5"
version "7.5.5"
resolved "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
resolved "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
...
@@ -4732,7 +4763,7 @@ hmac-drbg@^1.0.0:
...
@@ -4732,7 +4763,7 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.1.0:
hoist-non-react-statics@^3.1.0
, hoist-non-react-statics@^3.3.0
:
version "3.3.0"
version "3.3.0"
resolved "https://registry.npm.taobao.org/hoist-non-react-statics/download/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
resolved "https://registry.npm.taobao.org/hoist-non-react-statics/download/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
integrity sha1-sJF48BIhhPuVrPUl2q7LTY9FlYs=
integrity sha1-sJF48BIhhPuVrPUl2q7LTY9FlYs=
...
@@ -8268,6 +8299,17 @@ rc@^1.2.7:
...
@@ -8268,6 +8299,17 @@ rc@^1.2.7:
minimist "^1.2.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
strip-json-comments "~2.0.1"
react-apollo@^3.1.3:
version "3.1.3"
resolved "https://registry.npm.taobao.org/react-apollo/download/react-apollo-3.1.3.tgz#5d8540b401bba36173b63e6c5e75fa561960c63e"
integrity sha1-XYVAtAG7o2Fztj5sXnX6Vhlgxj4=
dependencies:
"@apollo/react-common" "^3.1.3"
"@apollo/react-components" "^3.1.3"
"@apollo/react-hoc" "^3.1.3"
"@apollo/react-hooks" "^3.1.3"
"@apollo/react-ssr" "^3.1.3"
react-app-polyfill@^1.0.4:
react-app-polyfill@^1.0.4:
version "1.0.4"
version "1.0.4"
resolved "https://registry.npm.taobao.org/react-app-polyfill/download/react-app-polyfill-1.0.4.tgz#4dd2636846b585c2d842b1e44e1bc29044345874"
resolved "https://registry.npm.taobao.org/react-app-polyfill/download/react-app-polyfill-1.0.4.tgz#4dd2636846b585c2d842b1e44e1bc29044345874"
...
...
graphql/resolvers/posts.js
View file @
4c47e53
...
@@ -5,6 +5,7 @@ const { AuthenticationError, UserInputError } = require("apollo-server");
...
@@ -5,6 +5,7 @@ const { AuthenticationError, UserInputError } = require("apollo-server");
module
.
exports
=
{
module
.
exports
=
{
Query
:
{
Query
:
{
async
getPosts
()
{
async
getPosts
()
{
console
.
log
(
"getPosts"
);
try
{
try
{
const
posts
=
await
Post
.
find
().
sort
({
createdAt
:
-
1
});
const
posts
=
await
Post
.
find
().
sort
({
createdAt
:
-
1
});
return
posts
;
return
posts
;
...
@@ -13,6 +14,7 @@ module.exports = {
...
@@ -13,6 +14,7 @@ module.exports = {
}
}
},
},
async
getPost
(
_
,
{
postId
})
{
async
getPost
(
_
,
{
postId
})
{
console
.
log
(
"getPost"
);
try
{
try
{
const
post
=
await
Post
.
findById
(
postId
);
const
post
=
await
Post
.
findById
(
postId
);
...
@@ -28,6 +30,7 @@ module.exports = {
...
@@ -28,6 +30,7 @@ module.exports = {
},
},
Mutation
:
{
Mutation
:
{
async
createPost
(
_
,
{
body
},
context
)
{
async
createPost
(
_
,
{
body
},
context
)
{
console
.
log
(
"createPost"
);
const
user
=
checkAuth
(
context
);
const
user
=
checkAuth
(
context
);
if
(
body
.
trim
()
===
""
)
{
if
(
body
.
trim
()
===
""
)
{
...
...
graphql/resolvers/users.js
View file @
4c47e53
...
@@ -57,9 +57,7 @@ module.exports = {
...
@@ -57,9 +57,7 @@ module.exports = {
},
},
async
register
(
async
register
(
_
,
_
,
{
{
registerInput
:
{
username
,
email
,
password
,
confirmPassword
}
}
registerInput
:
{
username
,
email
,
password
,
confirmPassword
}
}
)
{
)
{
// TODO: Validate user data
// TODO: Validate user data
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment