Files
encoach_frontend/src/utils/stats.ts
2024-11-26 15:04:24 +00:00

145 lines
4.8 KiB
TypeScript

import { Stat } from "@/interfaces/user";
import { capitalize, groupBy } from "lodash";
import { convertCamelCaseToReadable } from "@/utils/string";
import { UserSolution } from "@/interfaces/exam";
import { Module } from "@/interfaces";
import { MODULES } from "@/constants/ielts";
import moment from "moment";
export const timestampToMoment = (stat: Stat): moment.Moment => {
return moment.unix(stat.date > Math.pow(10, 11) ? stat.date / 1000 : stat.date);
};
export const totalExams = (stats: Stat[]): number => {
const moduleStats = formatModuleTotalStats(stats);
return moduleStats.reduce((previous, current) => previous + current.value, 0);
};
export const averageScore = (stats: Stat[]): number => {
const { correct, total } = stats.reduce(
(acc, current) => ({ correct: acc.correct + current.score.correct, total: acc.total + current.score.total }),
{ correct: 0, total: 0 },
);
return parseFloat(((correct / total) * 100).toFixed(2));
};
export const formatModuleTotalStats = (stats: Stat[]): { label: string; value: number }[] => {
const moduleSessions: { [key: string]: string[] } = {};
stats.forEach((stat) => {
if (stat.module in moduleSessions) {
if (!moduleSessions[stat.module].includes(stat.session)) {
moduleSessions[stat.module] = [...moduleSessions[stat.module], stat.session];
}
} else {
moduleSessions[stat.module] = [stat.session];
}
});
return ["reading", "listening", "writing", "speaking"].map((module) => ({
label: capitalize(module),
value: moduleSessions[module]?.length || 0,
}));
};
export const totalExamsByModule = (stats: Stat[], module: Module): number => {
const moduleSessions: { [key: string]: string[] } = {};
stats.forEach((stat) => {
if (stat.module in moduleSessions) {
if (!moduleSessions[stat.module].includes(stat.session)) {
moduleSessions[stat.module] = [...moduleSessions[stat.module], stat.session];
}
} else {
moduleSessions[stat.module] = [stat.session];
}
});
return moduleSessions[module]?.length || 0;
};
export const calculateModuleAverageScoreStats = (stats: Stat[]): { module: Module; value: number }[] => {
const moduleScores: { [key: string]: { correct: number; total: number } } = {};
stats.forEach((stat) => {
if (stat.module in moduleScores) {
moduleScores[stat.module] = {
correct: moduleScores[stat.module].correct + stat.score.correct,
total: moduleScores[stat.module].total + stat.score.total,
};
} else {
moduleScores[stat.module] = stat.score;
}
});
return MODULES.map((x) => {
const score = moduleScores[x as keyof typeof moduleScores];
return {
module: x,
value: score ? parseFloat(((score.correct / score.total) * 100).toFixed(2)) : 0,
};
});
};
export const formatModuleAverageScoreStats = (stats: Stat[]): { label: string; value: number }[] => {
return calculateModuleAverageScoreStats(stats).map((x) => ({ label: capitalize(x.module), value: x.value }));
};
export const formatExerciseTotalStats = (stats: Stat[]): { label: string; value: number }[] => {
const totalExercises = stats.map((stat) => ({
label: convertCamelCaseToReadable(stat.type),
value: stats.filter((x) => x.type === stat.type).length,
}));
return totalExercises.filter((ex, index) => totalExercises.findIndex((x) => x.label === ex.label) === index);
};
export const formatExerciseAverageScoreStats = (stats: Stat[]): { label: string; value: number }[] => {
const typeScores: { [key: string]: { correct: number; total: number } } = {};
stats.forEach((stat) => {
if (stat.type in typeScores) {
typeScores[stat.type] = {
correct: typeScores[stat.type].correct + stat.score.correct,
total: typeScores[stat.type].total + stat.score.total,
};
} else {
typeScores[stat.type] = stat.score;
}
});
return Object.keys(typeScores).map((x) => {
const { correct, total } = typeScores[x as keyof typeof typeScores];
return {
label: convertCamelCaseToReadable(x),
value: parseFloat(((correct / total) * 100).toFixed(2)),
};
});
};
export const getExamsBySession = (stats: Stat[], session: string) => {
const grouped = groupBySession(stats);
return grouped[session].map((exam) => exam.exam);
};
export const groupBySession = (stats: Stat[]) => groupBy(stats, "session");
export const groupByDate = (stats: Stat[]) => groupBy(stats, "date");
export const groupByExam = (stats: Stat[]) => groupBy(stats, "exam");
export const groupByModule = (stats: Stat[]) => groupBy(stats, "module");
export const groupByUser = (stats: Stat[]) => groupBy(stats, "user");
export const convertToUserSolutions = (stats: Stat[]): UserSolution[] => {
return stats.map((stat) => ({
exercise: stat.exercise,
exam: stat.exam,
score: stat.score,
solutions: stat.solutions,
type: stat.type,
module: stat.module,
shuffleMaps: stat.shuffleMaps,
isPractice: stat.isPractice
}));
};