From 7fada34410c16bf31fb797fb38cefccf6667bd87 Mon Sep 17 00:00:00 2001 From: meet Date: Fri, 2 Aug 2024 17:47:08 +0530 Subject: [PATCH] Added download report feature in comments, reactions and favorite for admin successfully --- admin/src/pages/Comments.tsx | 29 ++++ admin/src/pages/Favorites.tsx | 29 ++++ admin/src/pages/Reactions.tsx | 29 ++++ backend/src/routes/admin/controller.ts | 216 +++++++++++++++++++++++++ backend/src/routes/admin/route.ts | 8 +- 5 files changed, 310 insertions(+), 1 deletion(-) diff --git a/admin/src/pages/Comments.tsx b/admin/src/pages/Comments.tsx index 0717b62d..b67df3e0 100644 --- a/admin/src/pages/Comments.tsx +++ b/admin/src/pages/Comments.tsx @@ -6,6 +6,7 @@ import { tokenState } from "../store/atoms/auth"; import toast from "react-hot-toast"; import { ColorRing } from 'react-loader-spinner'; import { FaComments } from "react-icons/fa"; +import { TbReportAnalytics } from "react-icons/tb"; const Comments = () => { const [posts, setPosts] = useState([]); @@ -47,6 +48,27 @@ const Comments = () => { } }; + const downloadUsersCommentsReport = async () => { + try { + const response = await axios.get('/api/v1/admin/downloaduserscommentsreport', { + headers: { + Authorization: `Bearer ${token}`, + }, + responseType: 'blob', + }); + + const url = window.URL.createObjectURL(new Blob([response.data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', 'StyleShare_Comments_Report.pdf'); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } catch (error) { + console.error('Error downloading users comments report:', error); + } + }; + return (
@@ -68,6 +90,7 @@ const Comments = () => { />
: + <>
@@ -123,6 +146,12 @@ const Comments = () => {
+
+ +
+ }
diff --git a/admin/src/pages/Favorites.tsx b/admin/src/pages/Favorites.tsx index 7677a19a..bb2b3b76 100644 --- a/admin/src/pages/Favorites.tsx +++ b/admin/src/pages/Favorites.tsx @@ -5,6 +5,7 @@ import { tokenState } from "../store/atoms/auth"; import { IFavoritePost } from "../types"; import { ColorRing } from 'react-loader-spinner'; import { RiHeartsFill } from "react-icons/ri"; +import { TbReportAnalytics } from "react-icons/tb"; const Favorites = () => { const [favoritePosts, setFavoritePosts] = useState([]); @@ -32,6 +33,27 @@ const Favorites = () => { fetchFavoritePosts(); }, [token]); + const downloadUsersFavoritesReport = async () => { + try { + const response = await axios.get('/api/v1/admin/downloadusersfavoritesreport', { + headers: { + Authorization: `Bearer ${token}`, + }, + responseType: 'blob', + }); + + const url = window.URL.createObjectURL(new Blob([response.data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', 'StyleShare_Favorites_Report.pdf'); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } catch (error) { + console.error('Error downloading users favorites report:', error); + } + }; + return (
@@ -53,6 +75,7 @@ const Favorites = () => { />
: + <>
@@ -82,6 +105,12 @@ const Favorites = () => {
+
+ +
+ }
diff --git a/admin/src/pages/Reactions.tsx b/admin/src/pages/Reactions.tsx index b007dcdd..90e303e3 100644 --- a/admin/src/pages/Reactions.tsx +++ b/admin/src/pages/Reactions.tsx @@ -5,6 +5,7 @@ import { tokenState } from "../store/atoms/auth"; import { ColorRing } from 'react-loader-spinner'; import { MdAddReaction } from "react-icons/md"; import { IReaction} from "../types"; +import { TbReportAnalytics } from "react-icons/tb"; const Reactions = () => { const [reactions, setReactions] = useState([]); @@ -32,6 +33,27 @@ const Reactions = () => { fetchReactions(); }, [token]); + const downloadUsersReactionsReport = async () => { + try { + const response = await axios.get('/api/v1/admin/downloadusersreactionreport', { + headers: { + Authorization: `Bearer ${token}`, + }, + responseType: 'blob', + }); + + const url = window.URL.createObjectURL(new Blob([response.data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', 'StyleShare_Reactions_Report.pdf'); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } catch (error) { + console.error('Error downloading users reactions report:', error); + } + }; + return (
@@ -53,6 +75,7 @@ const Reactions = () => { />
: + <>
@@ -86,6 +109,12 @@ const Reactions = () => {
+
+ +
+ }
diff --git a/backend/src/routes/admin/controller.ts b/backend/src/routes/admin/controller.ts index f4d59bf6..a6e50fe5 100644 --- a/backend/src/routes/admin/controller.ts +++ b/backend/src/routes/admin/controller.ts @@ -633,6 +633,222 @@ export const downloadReportController = async (req: UserAuthRequest, res: Respon doc.fontSize(12).text(`${index + 1}. ${post.title}`); }); + doc.end(); + } catch (error) { + console.error(error); + res.status(500).json({ + error: "An unexpected exception occurred!", + }); + } +}; + +export const downloadCommentsReportController = async (req: Request, res: Response) => { + try { + const currentDate = new Date().toLocaleDateString(); + + const comments = await prisma.comment.findMany({ + select: { + content: true, + createdAt: true, + user: { + select: { + username: true, + email: true, + }, + }, + post: { + select: { + title: true, + }, + }, + }, + }); + + const totalComments = comments.length; + + const doc = new PDFDocument(); + let filename = `StyleShare_Comments_Report.pdf`; + filename = encodeURIComponent(filename); + + res.setHeader('Content-disposition', `attachment; filename="${filename}"`); + res.setHeader('Content-type', 'application/pdf'); + + doc.pipe(res); + + doc.fontSize(25).text('StyleShare Comments Report', { + align: 'center' + }); + + doc.moveDown(); + doc.fontSize(20).text('Overview', { + align: 'center' + }); + doc.moveDown(); + doc.fontSize(15).text(`Date: ${currentDate}`); + doc.moveDown(); + + doc.fontSize(12).text(`Total Comments: ${totalComments}`); + doc.moveDown(); + + doc.fontSize(15).text('Comment Details:'); + doc.moveDown(); + + comments.forEach(comment => { + doc.text(`Content: ${comment.content}`); + doc.text(`Created At: ${comment.createdAt.toLocaleDateString()}`); + doc.text(`User: ${comment.user.username} (${comment.user.email})`); + doc.text(`Post: ${comment.post.title}`); + doc.moveDown(); + }); + + doc.end(); + } catch (error) { + console.error(error); + res.status(500).json({ + error: "An unexpected exception occurred!", + }); + } +}; + +export const downloadReactionsReportController = async (req: Request, res: Response) => { + try { + const currentDate = new Date().toLocaleDateString(); + + const reactions = await prisma.reaction.findMany({ + select: { + type: true, + createdAt: true, + user: { + select: { + username: true, + email: true, + }, + }, + post: { + select: { + title: true, + description: true, + author: { + select: { + username: true, + email: true, + }, + }, + }, + }, + }, + }); + + const totalReactions = reactions.length; + + const doc = new PDFDocument(); + let filename = `StyleShare_Reactions_Report.pdf`; + filename = encodeURIComponent(filename); + + res.setHeader('Content-disposition', `attachment; filename="${filename}"`); + res.setHeader('Content-type', 'application/pdf'); + + doc.pipe(res); + + doc.fontSize(25).text('StyleShare Reactions Report', { + align: 'center' + }); + + doc.moveDown(); + doc.fontSize(20).text('Overview', { + align: 'center' + }); + doc.moveDown(); + doc.fontSize(15).text(`Date: ${currentDate}`); + doc.moveDown(); + + doc.fontSize(12).text(`Total Reactions: ${totalReactions}`); + doc.moveDown(); + + doc.fontSize(15).text('Reaction Details:'); + doc.moveDown(); + + reactions.forEach(reaction => { + doc.fontSize(12).text(`Type: ${reaction.type}`); + doc.text(`Created At: ${reaction.createdAt.toLocaleDateString()}`); + doc.text(`User: ${reaction.user.username} (${reaction.user.email})`); + doc.text(`Post: ${reaction.post.title}`); + doc.text(`Post Description: ${reaction.post.description}`); + doc.text(`Post Author: ${reaction.post.author.username} (${reaction.post.author.email})`); + doc.moveDown(); + }); + + doc.end(); + } catch (error) { + console.error(error); + res.status(500).json({ + error: "An unexpected exception occurred!", + }); + } +}; + +export const downloadFavoritesReportController = async (req: Request, res: Response) => { + try { + const currentDate = new Date().toLocaleDateString(); + + const favorites = await prisma.favorite.findMany({ + select: { + createdAt: true, + user: { + select: { + username: true, + email: true + } + }, + post: { + select: { + title: true, + description: true + } + } + }, + orderBy: { + createdAt: 'desc' + } + }); + + const totalFavorites = favorites.length; + + const doc = new PDFDocument(); + let filename = `StyleShare_Favorites_Report.pdf`; + filename = encodeURIComponent(filename); + + res.setHeader('Content-disposition', `attachment; filename="${filename}"`); + res.setHeader('Content-type', 'application/pdf'); + + doc.pipe(res); + + doc.fontSize(25).text('StyleShare Favorites Report', { + align: 'center' + }); + + doc.moveDown(); + doc.fontSize(20).text('Overview', { + align: 'center' + }); + doc.moveDown(); + doc.fontSize(15).text(`Date: ${currentDate}`); + doc.moveDown(); + + doc.fontSize(12).text(`Total Favorites: ${totalFavorites}`); + doc.moveDown(); + + doc.fontSize(15).text('Favorite Details:'); + doc.moveDown(); + + favorites.forEach(favorite => { + doc.text(`Created At: ${favorite.createdAt.toLocaleDateString()}`); + doc.text(`User: ${favorite.user.username} (${favorite.user.email})`); + doc.text(`Post: ${favorite.post.title}`); + doc.text(`Post Description: ${favorite.post.description}`); + doc.moveDown(); + }); + doc.end(); } catch (error) { console.error(error); diff --git a/backend/src/routes/admin/route.ts b/backend/src/routes/admin/route.ts index 0dbbf246..43fad171 100644 --- a/backend/src/routes/admin/route.ts +++ b/backend/src/routes/admin/route.ts @@ -1,5 +1,5 @@ import {Router} from 'express'; -import { getPostReactionsController,getFavoritesController,adminLoginController, adminProfileController, allUserForAdmin, blockUserController, unblockUserController, getAdminPostsController, getAdminTrendingPostsController, getAdminStatsController, getGraphsStatsController, updatePostController, deletePostController, getPostByIdController, getAllContactMessages, deleteCommentController, downloadReportController } from './controller'; +import { getPostReactionsController,getFavoritesController,adminLoginController, adminProfileController, allUserForAdmin, blockUserController, unblockUserController, getAdminPostsController, getAdminTrendingPostsController, getAdminStatsController, getGraphsStatsController, updatePostController, deletePostController, getPostByIdController, getAllContactMessages, deleteCommentController, downloadReportController, downloadCommentsReportController, downloadFavoritesReportController, downloadReactionsReportController } from './controller'; import { isAdmin } from '../../middleware/adminAuth'; const adminRouter = Router(); @@ -38,4 +38,10 @@ adminRouter.get('/favorites', isAdmin, getFavoritesController); adminRouter.get('/downloadReport',isAdmin, downloadReportController); +adminRouter.get("/downloaduserscommentsreport", downloadCommentsReportController); + +adminRouter.get("/downloadusersfavoritesreport", downloadFavoritesReportController); + +adminRouter.get("/downloadusersreactionreport", downloadReactionsReportController); + export default adminRouter; \ No newline at end of file