Added integration with backend to fetch skills feedback
This commit is contained in:
@@ -22,6 +22,10 @@ import { ModuleScore } from "@/interfaces/module.scores";
|
||||
import qrcode from "qrcode";
|
||||
import { SkillExamDetails } from "@/exams/pdf/details/skill.exam";
|
||||
import { LevelExamDetails } from "@/exams/pdf/details/level.exam";
|
||||
import { calculateBandScore } from "@/utils/score";
|
||||
import axios from "axios";
|
||||
import { moduleLabels } from "@/utils/moduleUtils";
|
||||
|
||||
const db = getFirestore(app);
|
||||
|
||||
export default withIronSessionApiRoute(handler, sessionOptions);
|
||||
@@ -115,6 +119,36 @@ const getFeedback = (module: Module) => {
|
||||
}
|
||||
};
|
||||
|
||||
interface SkillsFeedbackRequest {
|
||||
code: Module;
|
||||
name: string;
|
||||
grade: number;
|
||||
}
|
||||
|
||||
interface SkillsFeedbackResponse extends SkillsFeedbackRequest {
|
||||
evaluation: string;
|
||||
suggestions: string;
|
||||
}
|
||||
|
||||
const getSkillsFeedback = async (sections: SkillsFeedbackRequest[]) => {
|
||||
try {
|
||||
const backendRequest = await axios.post(
|
||||
`${process.env.BACKEND_URL}/grading_summary`,
|
||||
{ sections },
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.BACKEND_JWT}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return backendRequest.data?.sections;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const generateQRCode = async (link: string) => {
|
||||
try {
|
||||
const qrCodeDataURL = await qrcode.toDataURL(link);
|
||||
@@ -125,14 +159,18 @@ const generateQRCode = async (link: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
type RADIAL_PROGRESS_COLOR = 'laranja' | 'azul';
|
||||
type RADIAL_PROGRESS_COLOR = "laranja" | "azul";
|
||||
|
||||
const getRadialProgressPNG = (color: RADIAL_PROGRESS_COLOR, score: number, total: number) => {
|
||||
const getRadialProgressPNG = (
|
||||
color: RADIAL_PROGRESS_COLOR,
|
||||
score: number,
|
||||
total: number
|
||||
) => {
|
||||
const percent = (score / total) * 100;
|
||||
const remainder = percent % 10;
|
||||
const roundedPercent = percent - remainder;
|
||||
return `public/radial_progress/${color}_${roundedPercent}.png`;
|
||||
}
|
||||
};
|
||||
|
||||
async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.session.user) {
|
||||
@@ -163,37 +201,72 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = docUser.data() as User;
|
||||
|
||||
const stats = docsSnap.docs.map((d) => d.data());
|
||||
const results = (stats.reduce((accm: ModuleScore[], { module, score }) => {
|
||||
const fixedModuleStr = module[0].toUpperCase() + module.substring(1);
|
||||
if (accm.find((e: ModuleScore) => e.module === fixedModuleStr)) {
|
||||
return accm.map((e: ModuleScore) => {
|
||||
if (e.module === fixedModuleStr) {
|
||||
return {
|
||||
...e,
|
||||
score: e.score + score.correct,
|
||||
total: e.total + score.total,
|
||||
};
|
||||
}
|
||||
const results = (
|
||||
stats.reduce((accm: ModuleScore[], { module, score }) => {
|
||||
const fixedModuleStr = module[0].toUpperCase() + module.substring(1);
|
||||
if (accm.find((e: ModuleScore) => e.module === fixedModuleStr)) {
|
||||
return accm.map((e: ModuleScore) => {
|
||||
if (e.module === fixedModuleStr) {
|
||||
return {
|
||||
...e,
|
||||
score: e.score + score.correct,
|
||||
total: e.total + score.total,
|
||||
};
|
||||
}
|
||||
|
||||
return e;
|
||||
});
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
...accm,
|
||||
{
|
||||
module: fixedModuleStr,
|
||||
score: score.correct,
|
||||
total: score.total,
|
||||
feedback: getFeedback(module),
|
||||
},
|
||||
];
|
||||
}, []) as ModuleScore[]).map((moduleScore) => {
|
||||
return [
|
||||
...accm,
|
||||
{
|
||||
module: fixedModuleStr,
|
||||
score: score.correct,
|
||||
total: score.total,
|
||||
feedback: getFeedback(module),
|
||||
code: module,
|
||||
},
|
||||
];
|
||||
}, []) as ModuleScore[]
|
||||
).map((moduleScore) => {
|
||||
const { score, total } = moduleScore;
|
||||
const bandScore = calculateBandScore(
|
||||
score,
|
||||
total,
|
||||
moduleScore.code as Module,
|
||||
user.focus
|
||||
);
|
||||
|
||||
return {
|
||||
...moduleScore,
|
||||
png: getRadialProgressPNG('azul', score, total),
|
||||
png: getRadialProgressPNG("azul", score, total),
|
||||
bandScore,
|
||||
};
|
||||
});
|
||||
|
||||
const skillsFeedback =
|
||||
(await getSkillsFeedback(
|
||||
results.map(({ code, bandScore }) => ({
|
||||
code,
|
||||
name: moduleLabels[code],
|
||||
grade: bandScore,
|
||||
}))
|
||||
)) || ([] as SkillsFeedbackResponse[]);
|
||||
|
||||
const finalResults = results.map((result) => {
|
||||
const feedback = skillsFeedback.find(
|
||||
(f: SkillsFeedbackResponse) => f.code === result.module
|
||||
);
|
||||
|
||||
if (feedback) {
|
||||
return {
|
||||
...result,
|
||||
feedback: feedback?.evaluation + " " + feedback?.suggestions,
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
const [stat] = stats as Stat[];
|
||||
@@ -211,9 +284,9 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
module: "Overall",
|
||||
score: overallScore,
|
||||
total: overallTotal,
|
||||
png: getRadialProgressPNG('laranja', overallScore, overallTotal),
|
||||
png: getRadialProgressPNG("laranja", overallScore, overallTotal),
|
||||
} as ModuleScore;
|
||||
const testDetails = [overallDetail, ...results];
|
||||
const testDetails = [overallDetail, ...finalResults];
|
||||
const renderDetails = () => {
|
||||
if (stats[0].module === "level") {
|
||||
return <LevelExamDetails detail={overallDetail} />;
|
||||
|
||||
Reference in New Issue
Block a user