Commit 4c47e536 by qiuzhi99

23_like_post

1 parent 63d0cc84
......@@ -13,6 +13,7 @@
"jwt-decode": "^2.2.0",
"moment": "^2.24.0",
"react": "^16.10.2",
"react-apollo": "^3.1.3",
"react-dom": "^16.10.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0",
......
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;
import React from "react";
import React, { useContext } from "react";
import { Card, Image, Button, Label, Icon } from "semantic-ui-react";
import moment from "moment";
import { Link } from "react-router-dom";
import { AuthContext } from "../context/auth";
import LikeButton from "./LikeButton";
const PostCard = ({
post: { username, body, id, createdAt, likeCount, commentCount, likes }
}) => {
const likePost = () => {};
const { user } = useContext(AuthContext);
return (
<Card fluid>
<Card.Content>
......@@ -22,15 +24,8 @@ const PostCard = ({
<Card.Description>{body}</Card.Description>
</Card.Content>
<Card.Content extra>
<Button as="div" labelPosition="right" onClick={likePost}>
<Button color="teal" basic>
<Icon name="heart" />
</Button>
<Label basic color="teal" pointing="left">
{likeCount}
</Label>
</Button>
<Button as="div" labelPosition="right">
<LikeButton user={user} post={{ id, likes, likeCount }} />
<Button labelPosition="right" as={Link} to={`/posts/${id}`}>
<Button color="blue" basic>
<Icon name="comment" />
</Button>
......@@ -38,6 +33,16 @@ const PostCard = ({
{commentCount}
</Label>
</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>
);
......
......@@ -3,6 +3,7 @@ import { Form, Button } from "semantic-ui-react";
import { useForm } from "../utils/hook";
import { useMutation } from "@apollo/react-hooks";
import gql from "graphql-tag";
import { FETCH_POSTS_QUERY } from "../utils/grahpql";
function PostForm() {
const { onChange, onSubmit, values } = useForm(createPostCallback, {
......@@ -10,14 +11,24 @@ function PostForm() {
});
const [createPost, { error }] = useMutation(CREATE_POST_MUTATION, {
update(_, result) {
update(
proxy,
{
data: { createPost }
}
) {
values.body = "";
const { getPosts } = proxy.readQuery({ query: FETCH_POSTS_QUERY });
proxy.writeQuery({
query: FETCH_POSTS_QUERY,
data: { getPosts: getPosts.concat(createPost) }
});
},
variables: values
});
console.dir(error);
function createPostCallback() {
createPost();
}
......
import React, { useContext } from "react";
import gql from "graphql-tag";
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 { AuthContext } from "../context/auth";
import PostForm from "../components/PostForm";
import { FETCH_POSTS_QUERY } from "../utils/grahpql";
const FETCH_POSTS_QUERY = gql`
{
getPosts {
id
body
createdAt
username
likeCount
likes {
username
}
commentCount
comments {
id
username
createdAt
body
}
}
}
`;
const Home = () => {
function Home() {
const { user } = useContext(AuthContext);
const { loading, data } = useQuery(FETCH_POSTS_QUERY);
......@@ -46,16 +24,18 @@ const Home = () => {
{loading ? (
<h1>Loading posts...</h1>
) : (
data.getPosts &&
<Transition.Group>
{data.getPosts &&
data.getPosts.map(post => (
<Grid.Column key={post.id} style={{ marginBottom: 20 }}>
<PostCard post={post} />
</Grid.Column>
))
))}
</Transition.Group>
)}
</Grid.Row>
</Grid>
);
};
}
export default Home;
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
}
}
}
`;
......@@ -10,6 +10,28 @@
ts-invariant "^0.4.4"
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":
version "3.1.3"
resolved "https://registry.npm.taobao.org/@apollo/react-hooks/download/@apollo/react-hooks-3.1.3.tgz#ad42c7af78e81fee0f30e53242640410d5bd0293"
......@@ -20,6 +42,15 @@
ts-invariant "^0.4.4"
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":
version "7.5.5"
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:
minimalistic-assert "^1.0.0"
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"
resolved "https://registry.npm.taobao.org/hoist-non-react-statics/download/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
integrity sha1-sJF48BIhhPuVrPUl2q7LTY9FlYs=
......@@ -8268,6 +8299,17 @@ rc@^1.2.7:
minimist "^1.2.0"
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:
version "1.0.4"
resolved "https://registry.npm.taobao.org/react-app-polyfill/download/react-app-polyfill-1.0.4.tgz#4dd2636846b585c2d842b1e44e1bc29044345874"
......
......@@ -5,6 +5,7 @@ const { AuthenticationError, UserInputError } = require("apollo-server");
module.exports = {
Query: {
async getPosts() {
console.log("getPosts");
try {
const posts = await Post.find().sort({ createdAt: -1 });
return posts;
......@@ -13,6 +14,7 @@ module.exports = {
}
},
async getPost(_, { postId }) {
console.log("getPost");
try {
const post = await Post.findById(postId);
......@@ -28,6 +30,7 @@ module.exports = {
},
Mutation: {
async createPost(_, { body }, context) {
console.log("createPost");
const user = checkAuth(context);
if (body.trim() === "") {
......
......@@ -57,9 +57,7 @@ module.exports = {
},
async register(
_,
{
registerInput: { username, email, password, confirmPassword }
}
{ registerInput: { username, email, password, confirmPassword } }
) {
// TODO: Validate user data
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!