Skip to content

Commit

Permalink
Merge pull request #559 from MeetDOD/issue-558
Browse files Browse the repository at this point in the history
Feat: Added download report feature in comments, reactions and favorite in admin panel successfully issue 558
  • Loading branch information
VaibhavArora314 authored Aug 5, 2024
2 parents 0d8d46d + a9436aa commit f4b3d17
Show file tree
Hide file tree
Showing 5 changed files with 310 additions and 1 deletion.
29 changes: 29 additions & 0 deletions admin/src/pages/Comments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<IPost[]>([]);
Expand Down Expand Up @@ -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 (
<div>
<div className="flex-1 flex flex-col lg:ml-80">
Expand All @@ -68,6 +90,7 @@ const Comments = () => {
/>
</div>
:
<>
<div className="mx-5 lg:mr-11 overflow-x-auto shadow-md rounded-xl mb-5">
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
<thead className="text-xs text-white uppercase bg-sky-500">
Expand Down Expand Up @@ -123,6 +146,12 @@ const Comments = () => {
</tbody>
</table>
</div>
<div className="mx-5 overflow-x-auto rounded-xl mb-5">
<button onClick={downloadUsersCommentsReport} className="flex items-center py-2.5 px-4 rounded-lg transition duration-200 bg-yellow-500 hover:bg-yellow-600 text-gray-100"><TbReportAnalytics size={23} className='mr-3'/>
Download Comments Info
</button>
</div>
</>
}
</div>
</div>
Expand Down
29 changes: 29 additions & 0 deletions admin/src/pages/Favorites.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<IFavoritePost[]>([]);
Expand Down Expand Up @@ -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 (
<div>
<div className="flex-1 flex flex-col lg:ml-80">
Expand All @@ -53,6 +75,7 @@ const Favorites = () => {
/>
</div>
:
<>
<div className="mx-5 lg:mr-11 overflow-x-auto shadow-md rounded-xl mb-5">
<table className="w-full rtl:text-right text-gray-500 dark:text-gray-400">
<thead className="text-xs md:text-sm text-white uppercase bg-sky-500 text-center">
Expand Down Expand Up @@ -82,6 +105,12 @@ const Favorites = () => {
</tbody>
</table>
</div>
<div className="mx-5 overflow-x-auto rounded-xl mb-5">
<button onClick={downloadUsersFavoritesReport} className="flex items-center py-2.5 px-4 rounded-lg transition duration-200 bg-yellow-500 hover:bg-yellow-600 text-gray-100"><TbReportAnalytics size={23} className='mr-3'/>
Download Favorites Info
</button>
</div>
</>
}
</div>
</div>
Expand Down
29 changes: 29 additions & 0 deletions admin/src/pages/Reactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<IReaction[]>([]);
Expand Down Expand Up @@ -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 (
<div>
<div className="flex-1 flex flex-col lg:ml-80">
Expand All @@ -53,6 +75,7 @@ const Reactions = () => {
/>
</div>
:
<>
<div className="mx-5 lg:mr-11 overflow-x-auto shadow-md rounded-xl mb-5">
<table className="w-full rtl:text-right text-gray-500 dark:text-gray-400">
<thead className="text-xs md:text-sm text-white uppercase bg-sky-500 text-center">
Expand Down Expand Up @@ -86,6 +109,12 @@ const Reactions = () => {
</tbody>
</table>
</div>
<div className="mx-5 overflow-x-auto rounded-xl mb-5">
<button onClick={downloadUsersReactionsReport} className="flex items-center py-2.5 px-4 rounded-lg transition duration-200 bg-yellow-500 hover:bg-yellow-600 text-gray-100"><TbReportAnalytics size={23} className='mr-3'/>
Download Reactions Info
</button>
</div>
</>
}
</div>
</div>
Expand Down
216 changes: 216 additions & 0 deletions backend/src/routes/admin/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,222 @@ export const downloadContactMessagesReportController = async (req: Request, res:
doc.moveDown();
});

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);
Expand Down
Loading

0 comments on commit f4b3d17

Please sign in to comment.