diff --git a/src/exams/pdf/level.test.report.tsx b/src/exams/pdf/level.test.report.tsx
index 59c6ca1f..c09cba73 100644
--- a/src/exams/pdf/level.test.report.tsx
+++ b/src/exams/pdf/level.test.report.tsx
@@ -3,6 +3,7 @@ import React from "react";
import { Document, Page, View, Text, Image } from "@react-pdf/renderer";
import { ModuleScore } from "@/interfaces/module.scores";
import { styles } from "./styles";
+import TestReportFooter from "./test.report.footer";
import { StyleSheet } from "@react-pdf/renderer";
@@ -17,17 +18,16 @@ const customStyles = StyleSheet.create({
},
table: {
width: "100%",
- margin: "10px",
},
tableRow: {
flexDirection: "row",
},
- tableCol50: {
- width: "50%", // First column width (50%)
+ tableCol70: {
+ width: "70%", // First column width (50%)
borderStyle: "solid",
borderWidth: 1,
borderColor: "#000",
- padding: 5,
+ // padding: 5,
},
tableCol25: {
width: "16.67%", // Remaining four columns each get 1/6 of the total width (50% / 3 = 16.67%)
@@ -43,11 +43,20 @@ const customStyles = StyleSheet.create({
borderColor: "#000",
padding: 5,
},
+ tableCol10: {
+ width: "10%", // Width for each of the 5 sub-columns (50% / 5 = 20%)
+ borderStyle: "solid",
+ borderWidth: 1,
+ borderColor: "#000",
+ padding: 5,
+ },
tableCellHeader: {
- backgroundColor: "#d3d3d3",
- fontWeight: "bold",
+ fontSize: 12,
textAlign: "center",
},
+ tableCellHeaderColor: {
+ backgroundColor: "#d3d3d3",
+ },
tableCell: {
fontSize: 10,
textAlign: "center",
@@ -86,7 +95,7 @@ const LevelTestReport = ({
const defaultTextStyle = [styles.textFont, { fontSize: 8 }];
return (
-
+
Corporate Name: {corporateName}
@@ -111,56 +120,97 @@ const LevelTestReport = ({
{/* Header Row */}
-
- Test sections
+
+
+ Test sections
+
-
+
Time spent
-
+
Score
-
+
{uniqueExercises.map((exercise, index) => (
-
+
Part {index + 1}
))}
-
+
-
+
-
+
{uniqueExercises.map((exercise, index) => (
-
+
{exercise.name}
))}
-
+
-
+
-
+
{uniqueExercises.map((exercise, index) => (
-
+
{exercise.result}
@@ -168,14 +218,15 @@ const LevelTestReport = ({
))}
-
+
{timeSpent}
-
+
{score}
+
);
diff --git a/src/pages/api/stats/[id]/[export]/pdf.tsx b/src/pages/api/stats/[id]/[export]/pdf.tsx
index fdfbffc9..e04ffa39 100644
--- a/src/pages/api/stats/[id]/[export]/pdf.tsx
+++ b/src/pages/api/stats/[id]/[export]/pdf.tsx
@@ -34,7 +34,7 @@ import {
streamToBuffer,
} from "@/utils/pdf";
import moment from "moment-timezone";
-
+import { getCorporateNameForStudent } from "@/utils/groups.be";
const db = getFirestore(app);
export default withIronSessionApiRoute(handler, sessionOptions);
@@ -325,14 +325,14 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
}
const userId = stats[statIndex].user;
- // if (hasPDF) {
- // // if it does, return the pdf url
- // const fileRef = ref(storage, hasPDF.pdf!.path);
- // const url = await getDownloadURL(fileRef);
+ if (hasPDF) {
+ // if it does, return the pdf url
+ const fileRef = ref(storage, hasPDF.pdf!.path);
+ const url = await getDownloadURL(fileRef);
- // res.status(200).end(url);
- // return;
- // }
+ res.status(200).end(url);
+ return;
+ }
try {
// generate the pdf report
@@ -355,7 +355,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
stats.reduce((accm, s: Stat) => accm + (s.timeSpent || 0), 0) / 60
} minutes`;
const score = stats.reduce((accm, s) => accm + s.score.correct, 0);
-
+ const corporateName = await getCorporateNameForStudent(userId);
const pdfStream = await ReactPDF.renderToStream(
{
- const corporateRef = await getDoc(doc(db, "users", corporateID));
- const participantRef = await getDoc(doc(db, "users", participantID));
+export const updateExpiryDateOnGroup = async (
+ participantID: string,
+ corporateID: string
+) => {
+ const corporateRef = await getDoc(doc(db, "users", corporateID));
+ const participantRef = await getDoc(doc(db, "users", participantID));
- if (!corporateRef.exists() || !participantRef.exists()) return;
+ if (!corporateRef.exists() || !participantRef.exists()) return;
- const corporate = {
- ...corporateRef.data(),
- id: corporateRef.id,
- } as CorporateUser;
- const participant = {...participantRef.data(), id: participantRef.id} as StudentUser | TeacherUser;
+ const corporate = {
+ ...corporateRef.data(),
+ id: corporateRef.id,
+ } as CorporateUser;
+ const participant = { ...participantRef.data(), id: participantRef.id } as
+ | StudentUser
+ | TeacherUser;
- if (corporate.type !== "corporate" || (participant.type !== "student" && participant.type !== "teacher")) return;
+ if (
+ corporate.type !== "corporate" ||
+ (participant.type !== "student" && participant.type !== "teacher")
+ )
+ return;
- if (!corporate.subscriptionExpirationDate || !participant.subscriptionExpirationDate) {
- return await setDoc(doc(db, "users", participant.id), {subscriptionExpirationDate: null}, {merge: true});
- }
+ if (
+ !corporate.subscriptionExpirationDate ||
+ !participant.subscriptionExpirationDate
+ ) {
+ return await setDoc(
+ doc(db, "users", participant.id),
+ { subscriptionExpirationDate: null },
+ { merge: true }
+ );
+ }
- const corporateDate = moment(corporate.subscriptionExpirationDate);
- const participantDate = moment(participant.subscriptionExpirationDate);
+ const corporateDate = moment(corporate.subscriptionExpirationDate);
+ const participantDate = moment(participant.subscriptionExpirationDate);
- if (corporateDate.isAfter(participantDate))
- return await setDoc(doc(db, "users", participant.id), {subscriptionExpirationDate: corporateDate.toISOString()}, {merge: true});
+ if (corporateDate.isAfter(participantDate))
+ return await setDoc(
+ doc(db, "users", participant.id),
+ { subscriptionExpirationDate: corporateDate.toISOString() },
+ { merge: true }
+ );
- return;
+ return;
};
export const getGroups = async () => {
- const groupDocs = await getDocs(collection(db, "groups"));
- return groupDocs.docs.map((x) => ({...x.data(), id: x.id})) as Group[];
+ const groupDocs = await getDocs(collection(db, "groups"));
+ return groupDocs.docs.map((x) => ({ ...x.data(), id: x.id })) as Group[];
};
export const getUserGroups = async (id: string): Promise => {
- const groupDocs = await getDocs(query(collection(db, "groups"), where("admin", "==", id)));
- return groupDocs.docs.map((x) => ({...x.data(), id})) as Group[];
+ const groupDocs = await getDocs(
+ query(collection(db, "groups"), where("admin", "==", id))
+ );
+ return groupDocs.docs.map((x) => ({ ...x.data(), id })) as Group[];
};
-export const getAllAssignersByCorporate = async (corporateID: string): Promise => {
- const groups = await getUserGroups(corporateID);
- const groupUsers = (await Promise.all(groups.map(async (g) => await Promise.all(g.participants.map(getUser))))).flat();
- const teacherPromises = await Promise.all(
- groupUsers.map(async (u) =>
- u.type === "teacher" ? u.id : u.type === "corporate" ? [...(await getAllAssignersByCorporate(u.id)), u.id] : undefined,
- ),
- );
+export const getAllAssignersByCorporate = async (
+ corporateID: string
+): Promise => {
+ const groups = await getUserGroups(corporateID);
+ const groupUsers = (
+ await Promise.all(
+ groups.map(async (g) => await Promise.all(g.participants.map(getUser)))
+ )
+ ).flat();
+ const teacherPromises = await Promise.all(
+ groupUsers.map(async (u) =>
+ u.type === "teacher"
+ ? u.id
+ : u.type === "corporate"
+ ? [...(await getAllAssignersByCorporate(u.id)), u.id]
+ : undefined
+ )
+ );
- return teacherPromises.filter((x) => !!x).flat() as string[];
+ return teacherPromises.filter((x) => !!x).flat() as string[];
};
export const getGroupsForUser = async (admin: string, participant: string) => {
- try {
- const queryConstraints = [
- ...(admin ? [where("admin", "==", admin)] : []),
- ...(participant
- ? [where("participants", "array-contains", participant)]
- : []),
- ];
- const snapshot = await getDocs(
- queryConstraints.length > 0
- ? query(collection(db, "groups"), ...queryConstraints)
- : collection(db, "groups")
- );
- const groups = snapshot.docs.map((doc) => ({
- id: doc.id,
- ...doc.data(),
- })) as Group[];
-
- return groups;
- } catch (e) {
- console.error(e);
- return [];
- }
- };
+ try {
+ const queryConstraints = [
+ ...(admin ? [where("admin", "==", admin)] : []),
+ ...(participant
+ ? [where("participants", "array-contains", participant)]
+ : []),
+ ];
+ const snapshot = await getDocs(
+ queryConstraints.length > 0
+ ? query(collection(db, "groups"), ...queryConstraints)
+ : collection(db, "groups")
+ );
+ const groups = snapshot.docs.map((doc) => ({
+ id: doc.id,
+ ...doc.data(),
+ })) as Group[];
- export const getStudentGroupsForUsersWithoutAdmin = async (admin: string, participants: string[]) => {
- try {
- const queryConstraints = [
- ...(admin ? [where("admin", "!=", admin)] : []),
- ...(participants
- ? [where("participants", "array-contains-any", participants)]
- : []),
- where("name", "==", "Students"),
- ];
- const snapshot = await getDocs(
- queryConstraints.length > 0
- ? query(collection(db, "groups"), ...queryConstraints)
- : collection(db, "groups")
- );
- const groups = snapshot.docs.map((doc) => ({
- id: doc.id,
- ...doc.data(),
- })) as Group[];
-
- return groups;
- } catch (e) {
- console.error(e);
- return [];
- }
- };
\ No newline at end of file
+ return groups;
+ } catch (e) {
+ console.error(e);
+ return [];
+ }
+};
+
+export const getStudentGroupsForUsersWithoutAdmin = async (
+ admin: string,
+ participants: string[]
+) => {
+ try {
+ const queryConstraints = [
+ ...(admin ? [where("admin", "!=", admin)] : []),
+ ...(participants
+ ? [where("participants", "array-contains-any", participants)]
+ : []),
+ where("name", "==", "Students"),
+ ];
+ const snapshot = await getDocs(
+ queryConstraints.length > 0
+ ? query(collection(db, "groups"), ...queryConstraints)
+ : collection(db, "groups")
+ );
+ const groups = snapshot.docs.map((doc) => ({
+ id: doc.id,
+ ...doc.data(),
+ })) as Group[];
+
+ return groups;
+ } catch (e) {
+ console.error(e);
+ return [];
+ }
+};
+
+export const getCorporateNameForStudent = async (studentID: string) => {
+ const groups = await getStudentGroupsForUsersWithoutAdmin("", [studentID]);
+ if (groups.length === 0) return '';
+
+ const adminUserIds = [...new Set(groups.map((g) => g.admin))];
+ const adminUsersData = await getSpecificUsers(adminUserIds);
+
+ if(adminUsersData.length === 0) return '';
+ const admins = adminUsersData.filter((x) => x.type === 'corporate');
+
+ if(admins.length > 0) {
+ return (admins[0] as CorporateUser).corporateInformation.companyInformation.name;
+ }
+
+ return '';
+};