Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/MeetDOD/StyleShare into iss…
Browse files Browse the repository at this point in the history
…ue-558
  • Loading branch information
MeetDOD committed Aug 5, 2024
2 parents 9f0df6d + 0d8d46d commit a9436aa
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 12 deletions.
29 changes: 29 additions & 0 deletions admin/src/pages/ContactMessages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'react-responsive-modal/styles.css';
import '../styles/Model.css'
import { ColorRing } from 'react-loader-spinner';
import { MdMessage } from "react-icons/md";
import { TbReportAnalytics } from "react-icons/tb";

const ContactMessages = () => {
const [contactMessages, setContactMessages] = useState<IContactMessage[]>([]);
Expand Down Expand Up @@ -37,6 +38,27 @@ const ContactMessages = () => {
fetchMessages();
}, [token]);

const downloadContactMessagesReport = async () => {
try {
const response = await axios.get('/api/v1/admin/downloadcontactmessagereport', {
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_Contact_Messages_Report.pdf');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
console.error('Error downloading the Contact Messages report:', error);
}
};

const handleOpenModal = (message: IContactMessage) => {
setSelectedMessage(message);
setOpen(true);
Expand Down Expand Up @@ -68,6 +90,7 @@ const ContactMessages = () => {
/>
</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 @@ -112,6 +135,12 @@ const ContactMessages = () => {
</tbody>
</table>
</div>
<div className="mx-5 overflow-x-auto rounded-xl mb-5">
<button onClick={downloadContactMessagesReport} 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 Messages
</button>
</div>
</>
}
</div>
<Modal open={open} onClose={handleCloseModal} center classNames={{ modal: 'customModal',overlay: 'customOverlay'}}>
Expand Down
29 changes: 29 additions & 0 deletions admin/src/pages/Posts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import toast from "react-hot-toast";
import { Link } from "react-router-dom";
import { ColorRing } from 'react-loader-spinner';
import { BsFillPostcardFill } from "react-icons/bs";
import { TbReportAnalytics } from "react-icons/tb";

const Posts = () => {
const [posts, setPosts] = useState<IPost[]>([]);
Expand Down Expand Up @@ -48,6 +49,27 @@ const Posts = () => {
}
};

const downloadPostsReport = async () => {
try {
const response = await axios.get('/api/v1/admin/downloadpostsreport', {
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_Posts_Report.pdf');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
console.error('Error downloading the Posts report:', error);
}
};

return (
<div>
<div className="flex-1 flex flex-col lg:ml-80">
Expand All @@ -69,6 +91,7 @@ const Posts = () => {
/>
</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 @@ -107,6 +130,12 @@ const Posts = () => {
</tbody>
</table>
</div>
<div className="mx-5 overflow-x-auto rounded-xl mb-5">
<button onClick={downloadPostsReport} 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 Posts Info
</button>
</div>
</>
}
</div>
</div>
Expand Down
29 changes: 29 additions & 0 deletions admin/src/pages/Users.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import toast from "react-hot-toast";
import { IUser } from "../types";
import { ColorRing } from 'react-loader-spinner';
import { FaUsers } from "react-icons/fa";
import { TbReportAnalytics } from "react-icons/tb";

const Users = () => {
const [allUsers, setAllUsers] = useState<IUser[]>([]);
Expand Down Expand Up @@ -72,6 +73,27 @@ const Users = () => {
}
};

const downloadUsersReport = async () => {
try {
const response = await axios.get('/api/v1/admin/downloadusersreport', {
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_Users_Report.pdf');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
console.error('Error downloading the Users report:', error);
}
};

return (
<div>
<div className="flex-1 flex flex-col lg:ml-80">
Expand All @@ -93,6 +115,7 @@ const Users = () => {
/>
</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 @@ -136,6 +159,12 @@ const Users = () => {
</tbody>
</table>
</div>
<div className="mx-5 overflow-x-auto rounded-xl mb-5">
<button onClick={downloadUsersReport} 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 Users Info
</button>
</div>
</>
}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ PORT=3001
# EMAIL_USER=user_email_id
# EMAIL_PASS=16char_app_password
# SEND_EMAIL=true # Uncomment this to turn on email functionality on development
# API_KEY="your google gemini api key"
# API_KEY="your google gemini api key"
184 changes: 184 additions & 0 deletions backend/src/routes/admin/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,190 @@ export const toggleFeedbackVisibility = async (req: Request, res: Response) => {
}
};

export const downloadUsersReportController = async (req: Request, res: Response) => {
try {
const currentDate = new Date().toLocaleDateString();

const users = await prisma.user.findMany({
select: {
username: true,
email: true,
createdAt: true,
blocked: true,
},
});

const totalUsers = users.length;

const doc = new PDFDocument();
let filename = `StyleShare_Users_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 Users 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 Users: ${totalUsers}`);
doc.moveDown();

doc.fontSize(15).text('User Details:');
doc.moveDown();

users.forEach(user => {
doc.text(`Username: ${user.username}`);
doc.text(`Email: ${user.email}`);
doc.text(`Created At: ${user.createdAt.toLocaleDateString()}`);
doc.text(`Blocked: ${user.blocked ? 'Yes' : 'No'}`);
doc.moveDown();
});

doc.end();
} catch (error) {
console.error(error);
res.status(500).json({
error: "An unexpected exception occurred!",
});
}
};

export const downloadPostsReportController = async (req: Request, res: Response) => {
try {
const currentDate = new Date().toLocaleDateString();

const posts = await prisma.post.findMany({
select: {
title: true,
description: true,
createdAt: true,
author: {
select: {
username: true,
email: true,
},
},
},
});

const totalPosts = posts.length;

const doc = new PDFDocument();
let filename = `StyleShare_Posts_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 Posts 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 Posts: ${totalPosts}`);
doc.moveDown();

doc.fontSize(15).text('Post Details:');
doc.moveDown();

posts.forEach(post => {
doc.text(`Title: ${post.title}`);
doc.text(`Description: ${post.description}`);
doc.text(`Created At: ${post.createdAt.toLocaleDateString()}`);
doc.text(`Author: ${post.author.username} (${post.author.email})`);
doc.moveDown();
});

doc.end();
} catch (error) {
console.error(error);
res.status(500).json({
error: "An unexpected exception occurred!",
});
}
};

export const downloadContactMessagesReportController = async (req: Request, res: Response) => {
try {
const currentDate = new Date().toLocaleDateString();

const contactMessages = await prisma.contactMessage.findMany({
select: {
name: true,
email: true,
subject: true,
message: true,
createdAt: true,
},
});

const totalContactMessages = contactMessages.length;

const doc = new PDFDocument();
let filename = `StyleShare_Contact_Messages_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 Contact Messages 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 Contact Messages: ${totalContactMessages}`);
doc.moveDown();

doc.fontSize(15).text('Contact Message Details:');
doc.moveDown();

contactMessages.forEach(message => {
doc.text(`Name: ${message.name}`);
doc.text(`Email: ${message.email}`);
doc.text(`Subject: ${message.subject}`);
doc.text(`Message: ${message.message}`);
doc.text(`Created At: ${message.createdAt.toLocaleDateString()}`);
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();
Expand Down
8 changes: 7 additions & 1 deletion backend/src/routes/admin/route.ts
Original file line number Diff line number Diff line change
@@ -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, getFeedbacks, toggleFeedbackVisibility, downloadCommentsReportController, downloadFavoritesReportController, downloadReactionsReportController } from './controller';
import { getPostReactionsController,getFavoritesController,adminLoginController, adminProfileController, allUserForAdmin, blockUserController, unblockUserController, getAdminPostsController, getAdminTrendingPostsController, getAdminStatsController, getGraphsStatsController, updatePostController, deletePostController, getPostByIdController, getAllContactMessages, deleteCommentController, downloadReportController, getFeedbacks, toggleFeedbackVisibility, downloadCommentsReportController, downloadFavoritesReportController, downloadReactionsReportController, downloadUsersReportController, downloadContactMessagesReportController, downloadPostsReportController } from './controller';
import { isAdmin } from '../../middleware/adminAuth';

const adminRouter = Router();
Expand Down Expand Up @@ -38,6 +38,12 @@ adminRouter.get('/favorites', isAdmin, getFavoritesController);

adminRouter.get('/downloadReport',isAdmin, downloadReportController);

adminRouter.get('/downloadusersreport',isAdmin, downloadUsersReportController);

adminRouter.get('/downloadpostsreport',isAdmin, downloadPostsReportController);

adminRouter.get('/downloadcontactmessagereport',isAdmin, downloadContactMessagesReportController);

adminRouter.get('/getfeedback',isAdmin, getFeedbacks);

adminRouter.patch('/toggleFeedbackVisibility/:id', isAdmin, toggleFeedbackVisibility);
Expand Down
Loading

0 comments on commit a9436aa

Please sign in to comment.