From b891a2dde61f9ef9c1f79a1aaf7c81221554dbe8 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Tue, 22 Apr 2025 16:43:51 +0330 Subject: [PATCH] comment blog --- src/config/Pages.ts | 1 + src/langs/fa.json | 5 +- src/pages/blog/Comments.tsx | 70 +++++++++++++++++++++++++++ src/pages/blog/hooks/useBlogData.ts | 14 ++++++ src/pages/blog/service/BlogService.ts | 12 +++++ src/pages/blog/types/BlogTypes.ts | 19 ++++++++ src/router/Main.tsx | 2 + src/shared/components/BlogSubMenu.tsx | 5 ++ 8 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 src/pages/blog/Comments.tsx diff --git a/src/config/Pages.ts b/src/config/Pages.ts index fd667ef..93585a2 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -87,6 +87,7 @@ export const Pages = { create: "/blog/create", category: "/blog/category", detail: "/blog/detail/", + comments: "/blog/comments", }, messages: { list: "/messages/list", diff --git a/src/langs/fa.json b/src/langs/fa.json index 71b4c8d..a3a3c7c 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -402,7 +402,10 @@ "meta_title": "عنوان متا", "enter_your_meta_title": "عنوان متا بلاگ را وارد کنید", "meta_description": "توضیحات متا", - "enter_your_meta_description": "توضیحات متا بلاگ را وارد کنید" + "enter_your_meta_description": "توضیحات متا بلاگ را وارد کنید", + "comments": "نظرات", + "user": "کاربر", + "comment": "نظر" }, "receip": { "receips": "صورتحساب ها", diff --git a/src/pages/blog/Comments.tsx b/src/pages/blog/Comments.tsx new file mode 100644 index 0000000..aa46a0d --- /dev/null +++ b/src/pages/blog/Comments.tsx @@ -0,0 +1,70 @@ +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import Td from '../../components/Td' +import { useChangeStatusComment, useGetBlogComments } from './hooks/useBlogData' +import { BlogCommentType } from './types/BlogTypes' +import moment from 'moment-jalaali' +import { CloseCircle, TickCircle } from 'iconsax-react' +import { ErrorType } from '../../helpers/types' +import { toast } from 'react-toastify' +const Comments: FC = () => { + const { t } = useTranslation('global') + const getBlogComments = useGetBlogComments() + const changeStatusComment = useChangeStatusComment() + const handleChangeStatus = (id: string, status: string) => { + changeStatusComment.mutate({ id, status }, { + onSuccess: () => { + getBlogComments.refetch() + }, + onError: (error: ErrorType) => { + toast.error(error.response?.data?.error.message[0]) + } + }) + } + return ( +
+
+
+ {t('blog.comments')} +
+
+ +
+ + + + + + + {getBlogComments.data?.data?.comments?.map((item: BlogCommentType) => ( + + + + ))} + +
+ + + + +
+ + + + + { + item.status === 'PENDING' && +
+ handleChangeStatus(item.id, 'APPROVED')} color='green' size={20} /> + handleChangeStatus(item.id, 'REJECTED')} color='red' size={20} /> +
+ } + +
+
+ +
+ ) +} + +export default Comments \ No newline at end of file diff --git a/src/pages/blog/hooks/useBlogData.ts b/src/pages/blog/hooks/useBlogData.ts index 9c0e16b..321f8df 100644 --- a/src/pages/blog/hooks/useBlogData.ts +++ b/src/pages/blog/hooks/useBlogData.ts @@ -71,3 +71,17 @@ export const useDeleteBlog = () => { mutationFn: api.deleteBlog, }); }; + +export const useGetBlogComments = () => { + return useQuery({ + queryKey: ["blog-comments"], + queryFn: api.getBlogComments, + }); +}; + +export const useChangeStatusComment = () => { + return useMutation({ + mutationFn: (data: { id: string; status: string }) => + api.changeStatusComment(data.id, data.status), + }); +}; diff --git a/src/pages/blog/service/BlogService.ts b/src/pages/blog/service/BlogService.ts index 3845a97..f023fca 100644 --- a/src/pages/blog/service/BlogService.ts +++ b/src/pages/blog/service/BlogService.ts @@ -53,3 +53,15 @@ export const deleteBlog = async (id: string) => { const { data } = await axios.delete(`/blogs/${id}`); return data; }; + +export const getBlogComments = async () => { + const { data } = await axios.get("/blogs/comments"); + return data; +}; + +export const changeStatusComment = async (id: string, status: string) => { + const { data } = await axios.patch(`/blogs/comments/${id}/status`, { + status, + }); + return data; +}; diff --git a/src/pages/blog/types/BlogTypes.ts b/src/pages/blog/types/BlogTypes.ts index 9829d74..4197366 100644 --- a/src/pages/blog/types/BlogTypes.ts +++ b/src/pages/blog/types/BlogTypes.ts @@ -49,3 +49,22 @@ export type CreateBlogCategoryType = { iconUrl: string; isActive: boolean; }; + +export type BlogCommentType = { + content: string; + createdAt: string; + id: string; + status: string; + title: string; + updatedAt: string; + user: { + firstName: string; + id: string; + lastName: string; + profilePic: string; + }; + blog: { + id: string; + title: string; + }; +}; diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 36de4e8..538b217 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -64,6 +64,7 @@ import UpdateUser from '../pages/users/Update' import CreateSlider from '../pages/slider/Create' import SliderList from '../pages/slider/List' import UpdateSlider from '../pages/slider/Update' +import Comments from '../pages/blog/Comments' const MainRouter: FC = () => { const { hasSubMenu } = useSharedStore() @@ -139,6 +140,7 @@ const MainRouter: FC = () => { } /> } /> } /> + } /> diff --git a/src/shared/components/BlogSubMenu.tsx b/src/shared/components/BlogSubMenu.tsx index 6e5d53b..4f108f7 100644 --- a/src/shared/components/BlogSubMenu.tsx +++ b/src/shared/components/BlogSubMenu.tsx @@ -36,6 +36,11 @@ const BlogSubMenu: FC = () => { isActive={isActive('create')} link={Pages.blog.category} /> +