Files
encoach_frontend/src/exams/pdf/group.test.report.tsx
2024-04-02 22:19:32 +01:00

307 lines
8.6 KiB
TypeScript

/* eslint-disable jsx-a11y/alt-text */
import React from "react";
import {
Document,
Page,
View,
Text,
Image,
StyleSheet,
Font,
} from "@react-pdf/renderer";
import { styles } from "./styles";
import TestReportFooter from "./test.report.footer";
import { StudentData } from "@/interfaces/module.scores";
import ProgressBar from "./progress.bar";
Font.registerHyphenationCallback((word) => [word]);
interface Props {
date: string;
name: string;
email: string;
id: string;
gender?: string;
summary: string;
logo: string;
qrcode: string;
renderDetails: React.ReactNode;
title: string;
numberOfStudents: number;
institution: string;
studentsData: StudentData[];
showLevel: boolean;
summaryPNG: string;
summaryScore: string;
groupScoreSummary: any[];
passportId: string;
}
const customStyles = StyleSheet.create({
tableCellHighlight: {
backgroundColor: "#4f4969",
color: "#bc9970",
},
table: {
display: "flex",
flexDirection: "column",
// maxWidth: "600px",
// margin: "0 auto",
// borderCollapse: 'collapse',
},
tableRow: {
display: "flex",
flexDirection: "row",
},
tableHeader: {
fontWeight: "bold",
backgroundColor: "#f2f2f2",
},
tableCell: {
flex: 1,
padding: "8px",
textAlign: "left",
wordBreak: "break-all",
},
});
const GroupTestReport = ({
title,
date,
name,
email,
id,
gender,
summary,
logo,
qrcode,
renderDetails,
numberOfStudents,
institution,
studentsData,
showLevel,
summaryPNG,
summaryScore,
groupScoreSummary,
passportId,
}: Props) => {
const defaultTextStyle = [styles.textFont, { fontSize: 8 }];
return (
<Document>
<Page style={styles.body}>
<View style={styles.alignRightRow}>
<Image src={logo} fixed style={styles.image64} />
</View>
<View style={styles.titleView}>
<Text
style={[
styles.textFont,
styles.textBold,
styles.textColor,
styles.textUnderline,
styles.title,
{ fontSize: 14 },
]}
>
{title}
</Text>
</View>
<View style={styles.textMargin}>
<Text style={defaultTextStyle}>Date of Test: {date}</Text>
</View>
<Text style={[styles.textFont, styles.textBold, { fontSize: 11 }]}>
Candidate Information:
</Text>
<View style={styles.textMargin}>
<Text style={defaultTextStyle}>
Total Number of Students: {numberOfStudents}
</Text>
<Text style={defaultTextStyle}>Institution: {institution}</Text>
</View>
<View style={{ flex: 1 }}>
<Text
style={[
styles.textFont,
styles.textBold,
styles.textColor,
{ fontSize: 12 },
]}
>
Group Test Details:
</Text>
<View>{renderDetails}</View>
</View>
<View>
<Text
style={[
styles.textFont,
styles.textBold,
styles.textColor,
{ fontSize: 12 },
]}
>
Group Overall Performance Summary
</Text>
<View style={{ display: "flex", flexDirection: "row", gap: 16 }}>
<View style={{ flex: 1 }}>
<Text style={[styles.textFont, { fontSize: 8 }]}>{summary}</Text>
</View>
<View style={[styles.textFont, styles.radialContainer]}>
<Image src={summaryPNG} style={styles.image64}></Image>
<View style={[styles.textColor, styles.radialResultContainer]}>
<Text style={styles.textBold}>{summaryScore}</Text>
</View>
</View>
</View>
</View>
<View style={[{ paddingTop: 30 }, styles.separator]}></View>
<View>
<Text
style={[
styles.textFont,
styles.textBold,
styles.textColor,
styles.textUnderline,
{ fontSize: 12, paddingTop: 10 },
]}
>
Group Score Summary
</Text>
<View
style={{
paddingTop: 10,
gap: 8,
}}
>
<View
style={[
customStyles.table,
styles.textFont,
{ width: "100%", fontSize: "8px" },
]}
>
{groupScoreSummary.map(({ label, percent, description }) => (
<View
style={[
customStyles.tableRow,
{
width: "100%",
alignItems: "center",
justifyContent: "center",
},
]}
key={label}
>
<Text style={customStyles.tableCell}>{label}</Text>
<View style={[customStyles.tableCell, { flex: 2 }]}>
<ProgressBar
width={200}
height={18}
backgroundColor="#fab7b0"
progressColor="#cc5b55"
percentage={percent}
/>
</View>
<Text style={[customStyles.tableCell, { maxWidth: "48px" }]}>
{percent}%
</Text>
<Text style={customStyles.tableCell}>{description}</Text>
</View>
))}
</View>
</View>
<View style={styles.alignRightRow}>
<Image src={qrcode} style={styles.qrcode} />
</View>
</View>
<View style={[{ paddingBottom: 30 }, styles.separator]}></View>
<View style={{ flexGrow: 1 }}></View>
<TestReportFooter userId={id} />
</Page>
<Page style={styles.body}>
<View
style={[
customStyles.table,
styles.textFont,
{ border: "1px solid #ccc", width: "100%", fontSize: "8px" },
]}
>
<View
style={[
customStyles.tableRow,
customStyles.tableHeader,
customStyles.tableCellHighlight,
{ borderBottom: "1px solid #ccc" },
]}
>
<Text style={[customStyles.tableCell, { maxWidth: "24px" }]}>
Sr
</Text>
<Text style={customStyles.tableCell}>Candidate Name</Text>
<Text style={customStyles.tableCell}>
Passport ID
</Text>
<Text style={customStyles.tableCell}>Email ID</Text>
<Text style={[customStyles.tableCell, { maxWidth: "64px" }]}>
Date of test
</Text>
<Text style={[customStyles.tableCell, { maxWidth: "48px" }]}>
Result
</Text>
{showLevel && <Text style={customStyles.tableCell}>Level</Text>}
</View>
{studentsData.map(
(
{
id,
name,
email,
gender,
date,
result,
level,
passportId: studentPassportId,
},
index
) => (
<View
style={[
customStyles.tableRow,
{ borderBottom: "1px solid #ccc" },
]}
key={id}
>
<Text
style={[
customStyles.tableCell,
customStyles.tableCellHighlight,
{ maxWidth: "24px" },
]}
>
{index + 1}
</Text>
<Text style={customStyles.tableCell}>{name}</Text>
<Text style={customStyles.tableCell}>{studentPassportId}</Text>
<Text style={customStyles.tableCell}>{email}</Text>
<Text style={[customStyles.tableCell, { maxWidth: "64px" }]}>
{date}
</Text>
<Text style={[customStyles.tableCell, { maxWidth: "48px" }]}>
{result}
</Text>
{showLevel && (
<Text style={customStyles.tableCell}>{level}</Text>
)}
</View>
)
)}
</View>
<View style={{ flexGrow: 1 }}></View>
<TestReportFooter userId={id} />
</Page>
</Document>
);
};
export default GroupTestReport;