Skip to content

Commit

Permalink
feat: deleting replies owned
Browse files Browse the repository at this point in the history
  • Loading branch information
chimobi-justice committed Nov 6, 2024
1 parent 72e0e13 commit aa4e27d
Show file tree
Hide file tree
Showing 16 changed files with 212 additions and 43 deletions.
1 change: 1 addition & 0 deletions src/api/axiosInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const handleErrorResponse = (error: any) => {
// Handle 401 (unauthorized) by removing token from localStorage
if (error.response?.status === 401 && localStorage.getItem('ucType_')) {
localStorage.removeItem('ucType_');
localStorage.removeItem('clu');
window.location.href = '/auth/login'
}
return Promise.reject(error);
Expand Down
2 changes: 2 additions & 0 deletions src/api/endpoints/articleEndpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const GET_ARTHORED_ARTICLES_ENDPOINT = `${API_BASE_URL}/articles/authored

export const CREATE_ARTICLE_COMMENT_ENDPOINT = `${API_BASE_URL}/articles`;

export const DELETE_ARTICLE_COMMENT_ENDPOINT = `${API_BASE_URL}/articles`;

export const ARTICLE_LIKE_ENDPOINT = `${API_BASE_URL}/articles`;

export const ARTICLE_DISLIKE_ENDPOINT = `${API_BASE_URL}/articles`;
Expand Down
2 changes: 2 additions & 0 deletions src/api/endpoints/threadEndpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const GET_ARTHORED_THREADS_ENDPOINT = `${API_BASE_URL}/threads/authored`;

export const CREATE_THREAD_COMMENT_ENDPOINT = `${API_BASE_URL}/threads`;

export const DELETE_THREAD_COMMENT_ENDPOINT = `${API_BASE_URL}/threads`;

export const THREAD_LIKE_ENDPOINT = `${API_BASE_URL}/threads`;

export const THREAD_DISLIKE_ENDPOINT = `${API_BASE_URL}/threads`;
42 changes: 22 additions & 20 deletions src/components/FollowSection/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { FunctionComponent, Fragment } from 'react'
import { Link } from 'react-router-dom'
import { Avatar, Box, Flex, Heading, Spacer, Text } from '@chakra-ui/react'
import { Avatar, Box, Flex, Heading, Spacer, Text, useDisclosure } from '@chakra-ui/react'

import { Button } from '@components/index'
import { Button, ShowLoginModal } from '@components/index'
import truncate from '@helpers/truncate'
import { useCreateFollowUser } from '@hooks/user/useCreateFollowUser'
import { useCreateOnFollowUser } from '@hooks/user/useCreateUnFollowUser'
Expand All @@ -16,20 +16,21 @@ interface IProps {
isFetching: boolean;
}

const FollowSection: FunctionComponent<IProps> = ({
people,
hasMore,
fetchNext,
isFetching
const FollowSection: FunctionComponent<IProps> = ({
people,
hasMore,
fetchNext,
isFetching
}) => {
const { user } = useUser();
const { createFollowUserMutation } = useCreateFollowUser()
const { createOnFollowUserMutation } = useCreateOnFollowUser();
const { isOpen, onOpen, onClose } = useDisclosure();

const handleFollowUnfollow = (userId: string, following: boolean) => {
following
? createOnFollowUserMutation.mutate(userId) // Unfollow the user
: createFollowUserMutation.mutate(userId); // Follow the user
following
? createOnFollowUserMutation.mutate(userId) // Unfollow the user
: createFollowUserMutation.mutate(userId); // Follow the user
}

return (
Expand Down Expand Up @@ -64,16 +65,15 @@ const FollowSection: FunctionComponent<IProps> = ({
)}

{!user && (
<Link to={"/auth/login"}>
<Button
size="sm"
rounded="lg"
type="button"
variant="outline"
>
follow
</Button>
</Link>
<Button
size="sm"
rounded="lg"
type="button"
variant="outline"
onClick={onOpen}
>
follow
</Button>
)}
</Flex>

Expand Down Expand Up @@ -104,6 +104,8 @@ const FollowSection: FunctionComponent<IProps> = ({
</Button>
</Box>
)}

<ShowLoginModal isOpen={isOpen} onClose={onClose} />
</>
)
}
Expand Down
31 changes: 25 additions & 6 deletions src/context/userContext.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
createContext,
ReactElement,
ReactNode,
useContext
import {
createContext,
ReactElement,
ReactNode,
useContext,
useEffect,
useState
} from 'react'

import { useGetUser } from '@hooks/user/useGetUser'
Expand All @@ -22,7 +24,24 @@ const defaultContextValue: UserContextType = {
const UserContext = createContext<UserContextType>(defaultContextValue);

const UserContextProvider = ({ children }: { children: ReactNode }): ReactElement => {
const { data: user, isLoading, isSuccess } = useGetUser();
const [user, setUser] = useState<any>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isSuccess, setIsSuccess] = useState<boolean>(false);

const clu = JSON.parse(localStorage.getItem('clu') || "false");

const { data, isLoading: loading, isSuccess: success } = useGetUser();

useEffect(() => {
if (clu && success && data) {
setUser(data);
setIsLoading(loading);
setIsSuccess(success);
} else {
setIsLoading(false);
setIsSuccess(false);
}
}, [clu, data, loading, success]);

return (
<UserContext.Provider value={{ user, isLoading, isSuccess }}>
Expand Down
23 changes: 23 additions & 0 deletions src/hooks/article/useDeleteArticleComment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'

import { errorNotification, successNotification } from '@helpers/notification'
import { deleteArticleComment } from '@services/articles';

export const useDeleteArticleComment = () => {
const queryClient = useQueryClient();

const deleteArticleCommentMutation = useMutation({
mutationFn: deleteArticleComment,
onSuccess: (data) => {
successNotification(data.message);

queryClient.invalidateQueries({ queryKey: ['articles'] })
queryClient.invalidateQueries({ queryKey: ['article'] })
},
onError: (error: any) => {
errorNotification(error?.response?.data?.message);
}
})

return { deleteArticleCommentMutation }
}
1 change: 1 addition & 0 deletions src/hooks/auth/useSignOut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const useSignOut = () => {
queryClient.invalidateQueries({ queryKey: ['user'] })

localStorage.removeItem('ucType_');
localStorage.removeItem('clu');

window.location.href = "/?auth&session=signout";
},
Expand Down
1 change: 1 addition & 0 deletions src/hooks/auth/useSignin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const useSignin = () => {
queryClient.invalidateQueries({ queryKey: ['user'] })

localStorage.setItem('ucType_', data?.access_token);
localStorage.setItem('clu', JSON.stringify(true));

if (location.pathname === '/auth/login') {
navigate('/');
Expand Down
23 changes: 23 additions & 0 deletions src/hooks/thread/useDeleteThreadComment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'

import { errorNotification, successNotification } from '@helpers/notification'
import { deleteThreadComment } from '@services/threads'

export const useDeleteThreadComment = () => {
const queryClient = useQueryClient();

const deleteThreadCommentMutation = useMutation({
mutationFn: deleteThreadComment,
onSuccess: (data) => {
successNotification(data.message);

queryClient.invalidateQueries({ queryKey: ['threads'] })
queryClient.invalidateQueries({ queryKey: ['thread'] })
},
onError: (error: any) => {
errorNotification(error?.response?.data?.message);
}
})

return { deleteThreadCommentMutation }
}
37 changes: 34 additions & 3 deletions src/pages/Articles/components/commentComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { FormEvent, Fragment, FunctionComponent, useState } from 'react'
import { Link, useParams } from 'react-router-dom'
import { Avatar, Box, Divider, Flex, Text } from '@chakra-ui/react'
import { Avatar, Box, Divider, Flex, Text, useDisclosure } from '@chakra-ui/react'

import { IArticleComments } from 'src/types'
import { useUser } from '@context/userContext'
import { useCreateArticleComment } from '@hooks/article/useCreateArticleComment'
import { Button, ContentBlockContent, Editor } from '@components/index'
import { Button, ContentBlockContent, Editor, ShowLoginModal } from '@components/index'
import { useDeleteArticleComment } from '@hooks/article/useDeleteArticleComment'

const CommentComponent: FunctionComponent<{ comment: IArticleComments, level: number }> = ({ comment, level }) => {
const { user } = useUser();
const { createArticlCommentMutation } = useCreateArticleComment();
const { deleteArticleCommentMutation } = useDeleteArticleComment();
const { isOpen, onOpen, onClose } = useDisclosure();

const { id } = useParams();

Expand Down Expand Up @@ -99,10 +102,35 @@ const CommentComponent: FunctionComponent<{ comment: IArticleComments, level: nu
<Text fontSize="13px" cursor="pointer" onClick={() => handleShowCommentInput(comment.id)} as={"span"}>
Reply
</Text>

{comment.isOwner && (
<Text fontSize={"13px"} color={"red.500"} cursor={"pointer"} onClick={() => {
deleteArticleCommentMutation.mutate(comment.id)
}}>
Delete
</Text>
)}
</Flex>
</Flex>
)}

{!user && (
<Flex alignItems={"center"} gap={2} mb={"10px"}>
<Flex gap={2} alignItems={"center"}>
<Text fontSize="13px" cursor="pointer">
{comment.replies_count && comment.replies_count > 1 ? (
<span onClick={handleToggleReplies}>
replies {comment.replies_count} &bull;
</span>
) : (
<></>
)}
</Text>

{/* <Text fontSize={"13px"} color={"red.500"}>Delete</Text> */}
<Text fontSize="13px" cursor="pointer" onClick={onOpen} as={"span"}>
Reply
</Text>
</Flex>
</Flex>
)}

Expand Down Expand Up @@ -149,6 +177,9 @@ const CommentComponent: FunctionComponent<{ comment: IArticleComments, level: nu
))}
</>
)}

<ShowLoginModal isOpen={isOpen} onClose={onClose} />

</Fragment>
);
};
Expand Down
45 changes: 35 additions & 10 deletions src/pages/Threads/components/commentComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { FormEvent, Fragment, FunctionComponent, useState } from 'react'
import { Link, useParams } from "react-router-dom";
import { Avatar, Box, Flex, Spacer, Text } from '@chakra-ui/react'
import { Avatar, Box, Flex, Text, useDisclosure } from '@chakra-ui/react'

import { IThreadComments } from 'src/types'
import { useUser } from '@context/userContext';
import { Button, ContentBlockContent, Editor } from '@components/index';
import { useCreateThreadComment } from '@hooks/thread/useCreateThreadComment';
import { Button, ContentBlockContent, Editor, ShowLoginModal } from '@components/index'
import { useCreateThreadComment } from '@hooks/thread/useCreateThreadComment'
import { useDeleteThreadComment } from '@hooks/thread/useDeleteThreadComment';

const CommentComponent: FunctionComponent<{ comment: IThreadComments, level: number }> = ({ comment, level }) => {
const { user } = useUser();
const { createThreadCommentMutation } = useCreateThreadComment();
const { deleteThreadCommentMutation } = useDeleteThreadComment();
const { id } = useParams();
const { isOpen, onOpen, onClose } = useDisclosure();

const [showCommentInput, setShowCommentInput] = useState<string | null>(null);
const [replyContent, setReplyContent] = useState<string>('');
Expand Down Expand Up @@ -68,22 +71,42 @@ const CommentComponent: FunctionComponent<{ comment: IThreadComments, level: num
<span onClick={handleToggleReplies}>
replies {comment.replies_count} &bull;
</span>
): (
) : (
<></>
)}
</Text>

<Text fontSize="13px" cursor="pointer" onClick={() => handleShowCommentInput(comment.id)} as={"span"}>
Reply
Reply
</Text>
</Flex>

<Spacer />

<Flex gap={2}>
{/* <Text fontSize={"13px"} color={"red.500"}>Delete</Text> */}
{comment.isOwner && (
<Text fontSize={"13px"} color={"red.500"} cursor={"pointer"} onClick={() => {
deleteThreadCommentMutation.mutate(comment.id)
}}>
Delete
</Text>
)}
</Flex>
)}

{!user && (
<Flex alignItems={"center"} gap={2} mb={"10px"}>
<Flex gap={2} alignItems={"center"}>
<Text fontSize="13px" cursor="pointer">
{comment.replies_count && comment.replies_count > 1 ? (
<span onClick={handleToggleReplies}>
replies {comment.replies_count} &bull;
</span>
) : (
<></>
)}
</Text>


<Text fontSize="13px" cursor="pointer" onClick={onOpen} as={"span"}>
Reply
</Text>
</Flex>
</Flex>
)}
Expand Down Expand Up @@ -128,6 +151,8 @@ const CommentComponent: FunctionComponent<{ comment: IThreadComments, level: num
</>
)}
</Box>

<ShowLoginModal isOpen={isOpen} onClose={onClose} />
</Fragment>
);
};
Expand Down
Loading

0 comments on commit aa4e27d

Please sign in to comment.