Skip to content

Commit d1fcd9b

Browse files
committed
added report api which will be used to fetch user,seller stats
1 parent c7ac790 commit d1fcd9b

File tree

11 files changed

+474
-2
lines changed

11 files changed

+474
-2
lines changed

src/controllers/admin/index.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { Request, Response } from "express";
2+
import Admin from "../../models/Admin";
3+
import { decodeAdminToken, generateAdminToken } from "../../helpers/jwt";
4+
5+
export const registerAdmin = async (req: Request, res: Response) => {
6+
const { email, password } = req.body;
7+
8+
try {
9+
const existingAdmin = await Admin.findOne({ email });
10+
if (existingAdmin) {
11+
return res.status(400).json({ message: "Admin already exists." });
12+
}
13+
14+
const newAdmin = await Admin.create({ email, password });
15+
return res.status(201).json({ message: "Admin registered successfully.", admin: newAdmin });
16+
} catch (error) {
17+
return res.status(500).json({ message: "An error occurred.", error });
18+
}
19+
};
20+
21+
export const loginAdmin = async (req: Request, res: Response) => {
22+
const { email, password } = req.body;
23+
24+
try {
25+
const admin = await Admin.findOne({ email });
26+
if (!admin) {
27+
return res.status(404).json({ message: "Admin not found." });
28+
}
29+
30+
const isPasswordMatch = admin.password === password
31+
if (!isPasswordMatch) {
32+
return res.status(401).json({ message: "Invalid credentials." });
33+
}
34+
35+
const token = generateAdminToken(admin)
36+
return res.status(200).json({ message: "Login successful.", token,admin });
37+
} catch (error) {
38+
return res.status(500).json({ message: "An error occurred.", error });
39+
}
40+
};
41+
42+
export const deactivateAdmin = async (req: Request, res: Response) => {
43+
const { id } = req.params;
44+
try {
45+
const admin = await Admin.findByIdAndUpdate(id, { isActive: false }, { new: true });
46+
if (!admin) {
47+
return res.status(404).json({ message: "Admin not found." });
48+
}
49+
50+
return res.status(200).json({ message: "Admin deactivated successfully.", admin });
51+
} catch (error) {
52+
return res.status(500).json({ message: "An error occurred.", error });
53+
}
54+
};
55+
56+
export const activateAdmin = async (req: Request, res: Response) => {
57+
const { id } = req.params;
58+
59+
try {
60+
const admin = await Admin.findByIdAndUpdate(id, { isActive: true }, { new: true });
61+
if (!admin) {
62+
return res.status(404).json({ message: "Admin not found." });
63+
}
64+
65+
return res.status(200).json({ message: "Admin activated successfully.", admin });
66+
} catch (error) {
67+
return res.status(500).json({ message: "An error occurred.", error });
68+
}
69+
};
70+
71+
export const getAdminInfo = async (req: Request, res: Response) => {
72+
const token = req.headers.authorization?.split(" ")[1];
73+
74+
if (!token) {
75+
return res.status(401).json({ message: "Authorization token missing." });
76+
}
77+
78+
try {
79+
const admin = await decodeAdminToken(token)
80+
81+
if (!admin) {
82+
return res.status(404).json({ message: "Admin not found." });
83+
}
84+
85+
return res.status(200).json(admin);
86+
} catch (error) {
87+
return res.status(401).json({ message: "Invalid or expired token.", error });
88+
}
89+
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Request, Response } from "express";
2+
import ReviewFeedback from "../../models/ReviewFeedback";
3+
import User from "../../models/User";
4+
5+
export const getReviewStatistics = async (req: Request, res: Response) => {
6+
try {
7+
const totalReviews = await ReviewFeedback.countDocuments();
8+
9+
const mostReviewedUser = await ReviewFeedback.aggregate([
10+
{ $group: { _id: "$review_receiver_id", count: { $sum: 1 } } },
11+
{ $sort: { count: -1 } },
12+
{ $limit: 1 },
13+
]);
14+
15+
const user = await User.findOne({
16+
pi_uid: mostReviewedUser[0]?._id,
17+
});
18+
19+
20+
const now = new Date();
21+
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
22+
const startOfNextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1);
23+
24+
const currentMonthReviews = await ReviewFeedback.countDocuments({
25+
review_date: { $gte: startOfMonth, $lt: startOfNextMonth },
26+
});
27+
28+
const currentMonthReviewPercentage =
29+
totalReviews > 0
30+
? ((currentMonthReviews / totalReviews) * 100).toFixed(2)
31+
: "0.00";
32+
33+
res.status(200).json({
34+
totalReviews,
35+
mostReviewedUser: {
36+
user: user || null,
37+
count: mostReviewedUser[0]?.count || 0,
38+
},
39+
currentMonthReviews,
40+
currentMonthReviewPercentage: `${currentMonthReviewPercentage}%`,
41+
});
42+
} catch (error) {
43+
res.status(500).json({ message: "Failed to fetch review statistics", error });
44+
}
45+
};
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
2+
3+
import { Request, Response } from "express";
4+
import Seller from "../../models/Seller";
5+
import logger from "../../config/loggingConfig";
6+
7+
export const getSellerStatistics = async (req: Request, res: Response) => {
8+
try {
9+
const now = new Date();
10+
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
11+
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0);
12+
13+
const totalSellers = await Seller.countDocuments();
14+
const activeSellersCount = await Seller.countDocuments({ seller_type: "activeSeller" });
15+
const inactiveSellers = await Seller.countDocuments({ seller_type: "inactiveSeller" });
16+
const testSellers = await Seller.countDocuments({ seller_type: "testSeller" });
17+
18+
const sellerGrowthThisMonth = await Seller.aggregate([
19+
{
20+
$match: {
21+
createdAt: { $gte: startOfMonth, $lte: endOfMonth },
22+
},
23+
},
24+
{
25+
$group: {
26+
_id: "$seller_type",
27+
count: { $sum: 1 },
28+
},
29+
},
30+
]);
31+
32+
const sellerGrowthByTypeThisMonth = sellerGrowthThisMonth.reduce((acc, item) => {
33+
acc[item._id] = item.count;
34+
return acc;
35+
}, {});
36+
37+
const newSellersThisMonth = sellerGrowthThisMonth.reduce((sum, item) => sum + item.count, 0);
38+
39+
const percentageGrowthThisMonth =
40+
totalSellers > 0 ? (newSellersThisMonth / totalSellers) * 100 : 0;
41+
42+
const months = [
43+
"January",
44+
"February",
45+
"March",
46+
"April",
47+
"May",
48+
"June",
49+
"July",
50+
"August",
51+
"September",
52+
"October",
53+
"November",
54+
"December",
55+
];
56+
57+
const sellerGrowth = await Seller.aggregate([
58+
{
59+
$group: {
60+
_id: { $month: "$createdAt" },
61+
count: { $sum: 1 },
62+
},
63+
},
64+
{ $sort: { "_id": 1 } },
65+
]);
66+
67+
const data = sellerGrowth.map((growth) => {
68+
return {
69+
month: months[growth._id - 1],
70+
count: growth.count,
71+
};
72+
});
73+
74+
75+
const statistics = {
76+
totalSellers,
77+
activeSellers: activeSellersCount,
78+
inactiveSellers,
79+
testSellers,
80+
newSellersThisMonth,
81+
percentageGrowthThisMonth: percentageGrowthThisMonth.toFixed(2),
82+
sellerGrowthByTypeThisMonth: {
83+
activeSeller: sellerGrowthByTypeThisMonth["activeSeller"] || 0,
84+
inactiveSeller: sellerGrowthByTypeThisMonth["inactiveSeller"] || 0,
85+
testSeller: sellerGrowthByTypeThisMonth["testSeller"] || 0,
86+
},
87+
sellerGrowth: data
88+
};
89+
90+
logger.info("Fetched seller statistics for the current month successfully", statistics);
91+
92+
return res.status(200).json(statistics);
93+
} catch (error) {
94+
logger.error("Failed to fetch seller statistics:", error);
95+
return res
96+
.status(500)
97+
.json({ message: "An error occurred while fetching seller statistics; please try again later." });
98+
}
99+
};
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { Request, Response } from "express";
2+
import User from "../../models/User";
3+
import ReviewFeedback from "../../models/ReviewFeedback";
4+
import { RatingScale } from "../../models/enums/ratingScale";
5+
6+
7+
8+
export const getTotalUser = async (req:Request, res:Response) => {
9+
try {
10+
const totalUsers = await User.find().countDocuments()
11+
return res.status(200).json(totalUsers);
12+
13+
} catch (error: any) {
14+
return res.status(500).json({
15+
message: 'Failed to fetch total users',
16+
error: error.message
17+
});
18+
}
19+
}
20+
21+
export const getUserStatistics = async (req: Request, res: Response) => {
22+
try {
23+
const fetchUsers = async (userIds: string[]) => {
24+
return await User.find({ pi_uid: { $in: userIds } }).select("pi_uid pi_username user_name");
25+
};
26+
27+
const mostReviewsReceived = await ReviewFeedback.aggregate([
28+
{ $group: { _id: "$review_receiver_id", count: { $sum: 1 } } },
29+
{ $sort: { count: -1 } },
30+
{ $limit: 5 },
31+
]);
32+
33+
const mostReviewsReceivedUsers = await fetchUsers(mostReviewsReceived.map(user => user._id));
34+
35+
const mostReviewsGiven = await ReviewFeedback.aggregate([
36+
{ $group: { _id: "$review_giver_id", count: { $sum: 1 } } },
37+
{ $sort: { count: -1 } },
38+
{ $limit: 5 },
39+
]);
40+
41+
const mostReviewsGivenUsers = await fetchUsers(mostReviewsGiven.map(user => user._id));
42+
43+
const mostTrustworthyReviewsReceived = await ReviewFeedback.aggregate([
44+
{ $match: { rating: RatingScale.DELIGHT } },
45+
{ $group: { _id: "$review_receiver_id", count: { $sum: 1 } } },
46+
{ $sort: { count: -1 } },
47+
{ $limit: 5 },
48+
]);
49+
50+
const mostTrustworthyReviewsReceivedUsers = await fetchUsers(
51+
mostTrustworthyReviewsReceived.map(user => user._id)
52+
);
53+
54+
const mostTrustworthyReviewsGiven = await ReviewFeedback.aggregate([
55+
{ $match: { rating: RatingScale.DELIGHT } },
56+
{ $group: { _id: "$review_giver_id", count: { $sum: 1 } } },
57+
{ $sort: { count: -1 } },
58+
{ $limit: 5 },
59+
]);
60+
61+
const mostTrustworthyReviewsGivenUsers = await fetchUsers(
62+
mostTrustworthyReviewsGiven.map(user => user._id)
63+
);
64+
65+
const mostDespairReviewsReceived = await ReviewFeedback.aggregate([
66+
{ $match: { rating: RatingScale.DESPAIR } },
67+
{ $group: { _id: "$review_receiver_id", count: { $sum: 1 } } },
68+
{ $sort: { count: -1 } },
69+
{ $limit: 5 },
70+
]);
71+
72+
const mostDespairReviewsReceivedUsers = await fetchUsers(
73+
mostDespairReviewsReceived.map(user => user._id)
74+
);
75+
76+
const mostDespairReviewsGiven = await ReviewFeedback.aggregate([
77+
{ $match: { rating: RatingScale.DESPAIR } },
78+
{ $group: { _id: "$review_giver_id", count: { $sum: 1 } } },
79+
{ $sort: { count: -1 } },
80+
{ $limit: 5 },
81+
]);
82+
83+
const mostDespairReviewsGivenUsers = await fetchUsers(
84+
mostDespairReviewsGiven.map(user => user._id)
85+
);
86+
87+
res.status(200).json({
88+
mostReviewsReceived: mostReviewsReceivedUsers.map((user, index) => ({
89+
...user.toObject(),
90+
count: mostReviewsReceived[index]?.count || 0,
91+
})),
92+
mostReviewsGiven: mostReviewsGivenUsers.map((user, index) => ({
93+
...user.toObject(),
94+
count: mostReviewsGiven[index]?.count || 0,
95+
})),
96+
mostTrustworthyReviewsReceived: mostTrustworthyReviewsReceivedUsers.map((user, index) => ({
97+
...user.toObject(),
98+
count: mostTrustworthyReviewsReceived[index]?.count || 0,
99+
})),
100+
mostTrustworthyReviewsGiven: mostTrustworthyReviewsGivenUsers.map((user, index) => ({
101+
...user.toObject(),
102+
count: mostTrustworthyReviewsGiven[index]?.count || 0,
103+
})),
104+
mostDespairReviewsReceived: mostDespairReviewsReceivedUsers.map((user, index) => ({
105+
...user.toObject(),
106+
count: mostDespairReviewsReceived[index]?.count || 0,
107+
})),
108+
mostDespairReviewsGiven: mostDespairReviewsGivenUsers.map((user, index) => ({
109+
...user.toObject(),
110+
count: mostDespairReviewsGiven[index]?.count || 0,
111+
})),
112+
});
113+
} catch (error) {
114+
res.status(500).json({ message: "Failed to fetch user statistics", error });
115+
}
116+
};

0 commit comments

Comments
 (0)