'use client' import { DeletePostDocument, DownvoteDocument, MeDocument, PostDocument, Post as PostType, RemoveDownvoteDocument, RemoveUpvoteDocument, UpvoteDocument } from '@/generated/graphql/graphql' import { useMutation, useQuery } from '@apollo/client/react' import { ArrowDownIcon, ArrowUpIcon, DeleteIcon, EditIcon } from '@chakra-ui/icons' import { Box, Flex, Heading, IconButton, Text } from '@chakra-ui/react' import Link from 'next/link' import { useRouter } from 'next/navigation' interface Props { post: PostType } export const Post: React.FC = ({ post: p }) => { const { data } = useQuery(MeDocument) const router = useRouter() const { refetch } = useQuery(PostDocument, { returnPartialData: false, variables: { id: p.id } }) const [upvote, { loading: upvoting }] = useMutation(UpvoteDocument) const [downvote, { loading: downvoting }] = useMutation(DownvoteDocument) const [removeUpvote, { loading: removingUpvote }] = useMutation(RemoveUpvoteDocument) const [removeDownvote, { loading: removingDownvote }] = useMutation(RemoveDownvoteDocument) const [deletePost, { loading: deletingPost }] = useMutation(DeletePostDocument) return ( } color={p.upvoted ? 'green' : ''} isLoading={upvoting || removingUpvote} onClick={async () => { if (!data?.me) { router.push('/login') } if (p.upvoted) { await removeUpvote({ variables: { postID: p.id } }) // Apollo Client automatically refetches one single post and merge it with the cache of previous posts and updating the result of useQuery(PostsDocument), so we don't need to refetch every post. await refetch() } else { await upvote({ variables: { postID: p.id } }) await refetch() } }} /> {p.points} } color={p.downvoted ? 'red' : ''} isLoading={downvoting || removingDownvote} onClick={async () => { if (!data?.me) { router.push('/login') } if (p.downvoted) { await removeDownvote({ variables: { postID: p.id } }) await refetch() } else { await downvote({ variables: { postID: p.id } }) await refetch() } }} /> {p.title} Posted by {p.author.username} {p.snippet} { p.authorID == data?.me?.id && } /> } colorScheme='red' isLoading={deletingPost} onClick={async () => { await deletePost({ variables: { id: p.id }, // https://stackoverflow.com/questions/63192774/apollo-client-delete-item-from-cache // https://www.apollographql.com/docs/react/caching/garbage-collection/#cacheevict update: cache => { const normalizedId = cache.identify({ id: p.id, __typename: 'Post' }) cache.evict({ id: normalizedId }) cache.gc() } }) }} /> } ) }