Refactor components to remove Layout wrapper and pass it in the App component , implemented a skeleton feedback while loading page and improved API calls related to Dashboard/User Profile
141 lines
2.8 KiB
TypeScript
141 lines
2.8 KiB
TypeScript
import { Stat } from "@/interfaces/user";
|
|
import client from "@/lib/mongodb";
|
|
|
|
const db = client.db(process.env.MONGODB_DB);
|
|
|
|
export const getStatsByUser = async (id: string) => await db.collection("stats").find<Stat>({ user: id }).toArray();
|
|
|
|
export const getStatsByUsers = async (ids: string[]) =>
|
|
await db
|
|
.collection("stats")
|
|
.find<Stat>({ user: { $in: ids } })
|
|
.toArray();
|
|
|
|
export const getDetailedStatsByUser = async (id: string, query?: string) => {
|
|
let aggregateArray: any[] = [
|
|
{ $match: { user: id } },
|
|
{ $sort: { "date": 1 } },
|
|
]
|
|
switch (query) {
|
|
case "stats":
|
|
{
|
|
aggregateArray = aggregateArray.concat([{
|
|
$group: {
|
|
_id: "$session",
|
|
modules: { $addToSet: "$module" },
|
|
documents: { $push: "$$ROOT" },
|
|
totalCorrect: { $sum: "$score.correct" },
|
|
totalQuestions: { $sum: "$score.total" }
|
|
}
|
|
},
|
|
{
|
|
$project: {
|
|
_id: 0,
|
|
hasAllModules: {
|
|
$eq: [
|
|
{ $size: { $setIntersection: ["$modules", ["reading", "listening", "writing", "speaking"]] } },
|
|
4
|
|
]
|
|
},
|
|
uniqueModulesCount: { $size: "$modules" },
|
|
averageScore: {
|
|
$cond: [
|
|
{ $gt: ["$totalQuestions", 0] },
|
|
{ $multiply: [{ $divide: ["$totalCorrect", "$totalQuestions"] }, 100] },
|
|
0
|
|
]
|
|
},
|
|
documents: 1
|
|
}
|
|
},
|
|
{
|
|
$group: {
|
|
_id: null,
|
|
fullExams: { $sum: { $cond: ["$hasAllModules", 1, 0] } },
|
|
uniqueModules: { $sum: "$uniqueModulesCount" },
|
|
averageScore: {
|
|
$avg: "$averageScore"
|
|
},
|
|
allStats: { $push: "$documents" }
|
|
}
|
|
},
|
|
{
|
|
$project: {
|
|
_id: 0,
|
|
fullExams: 1,
|
|
uniqueModules: 1,
|
|
averageScore: 1,
|
|
allStats: {
|
|
$reduce: {
|
|
input: "$allStats",
|
|
initialValue: [],
|
|
in: { $concatArrays: ["$$value", "$$this"] }
|
|
}
|
|
}
|
|
}
|
|
}])
|
|
}
|
|
break;
|
|
case "byModule": {
|
|
aggregateArray = aggregateArray.concat([{
|
|
$facet: {
|
|
moduleCounts: [
|
|
{
|
|
$group: {
|
|
_id: {
|
|
module: "$module",
|
|
session: "$session"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
$group: {
|
|
_id: "$_id.module",
|
|
count: {
|
|
$count: {}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
$project: {
|
|
_id: 0,
|
|
module: "$_id",
|
|
count: "$count"
|
|
}
|
|
}
|
|
],
|
|
allDocuments: [
|
|
{
|
|
$project: {
|
|
_id: 0
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
$project: {
|
|
moduleCount: {
|
|
$arrayToObject: {
|
|
$map: {
|
|
input: "$moduleCounts",
|
|
as: "module",
|
|
in: {
|
|
k: "$$module.module",
|
|
v: "$$module.count"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
allDocs: "$allDocuments"
|
|
}
|
|
}])
|
|
|
|
}
|
|
default:
|
|
}
|
|
|
|
return await db.collection("stats").aggregate(aggregateArray).toArray().then((result) => query ? result[0] : result
|
|
);
|
|
}
|