Added QRCode for PDF
This commit is contained in:
@@ -54,6 +54,10 @@ const styles = StyleSheet.create({
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
alignRightRow: {
|
||||
display: "flex",
|
||||
flexDirection: "row-reverse",
|
||||
}
|
||||
});
|
||||
|
||||
interface Props {
|
||||
@@ -65,6 +69,7 @@ interface Props {
|
||||
testDetails: ModuleScore[];
|
||||
summary: string;
|
||||
logo: string;
|
||||
qrcode: string;
|
||||
}
|
||||
|
||||
const PDFReport = ({
|
||||
@@ -76,6 +81,7 @@ const PDFReport = ({
|
||||
testDetails,
|
||||
summary,
|
||||
logo,
|
||||
qrcode,
|
||||
}: Props) => {
|
||||
const defaultTextStyle = [styles.textFont, { fontSize: 8 }];
|
||||
const defaultSkillsTextStyle = [styles.textFont, { fontSize: 8 }];
|
||||
@@ -89,10 +95,7 @@ const PDFReport = ({
|
||||
<Document>
|
||||
<Page style={styles.body}>
|
||||
<View
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row-reverse",
|
||||
}}
|
||||
style={styles.alignRightRow}
|
||||
>
|
||||
<Image
|
||||
src={logo}
|
||||
@@ -209,6 +212,12 @@ const PDFReport = ({
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
<View style={styles.alignRightRow}>
|
||||
<Image src={qrcode} style={{
|
||||
width: '80px',
|
||||
height: '80px',
|
||||
}}/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={[{ paddingTop: 30 }, styles.separator]}>
|
||||
<View>
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
getFirestore,
|
||||
doc,
|
||||
getDoc,
|
||||
deleteDoc,
|
||||
updateDoc,
|
||||
getDocs,
|
||||
query,
|
||||
@@ -18,21 +17,19 @@ import PDFReport from "@/exams/pdf";
|
||||
import {
|
||||
ref,
|
||||
uploadBytes,
|
||||
deleteObject,
|
||||
getDownloadURL,
|
||||
} from "firebase/storage";
|
||||
import blobStream from "blob-stream";
|
||||
import { Stat } from "@/interfaces/user";
|
||||
import { User } from "@/interfaces/user";
|
||||
import { Module } from "@/interfaces";
|
||||
import { ModuleScore } from "@/interfaces/module.scores";
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import qrcode from 'qrcode';
|
||||
|
||||
const db = getFirestore(app);
|
||||
|
||||
export default withIronSessionApiRoute(handler, sessionOptions);
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === "GET") return get(req, res);
|
||||
if (req.method === "POST") return post(req, res);
|
||||
}
|
||||
|
||||
@@ -119,6 +116,17 @@ const getFeedback = (module: Module) => {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
const generateQRCode = async (link: string) => {
|
||||
try {
|
||||
const qrCodeDataURL = await qrcode.toDataURL(link);
|
||||
return qrCodeDataURL;
|
||||
} catch (error) {
|
||||
console.error('Error generating QR code:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.session.user) {
|
||||
const { id } = req.query as { id: string };
|
||||
@@ -183,41 +191,68 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
const overallTotal = results.reduce((accm, { total }) => accm + total, 0);
|
||||
const overallResult = overallScore / overallTotal;
|
||||
const performanceSummary = getPerformanceSummary("level", overallResult);
|
||||
// const logo = fs.readFileSync(path.resolve(__dirname, './logo_title.png'));
|
||||
const pdfStream = await ReactPDF.renderToStream(
|
||||
<PDFReport
|
||||
date={new Date(stat.date).toLocaleString()}
|
||||
name={user.name}
|
||||
email={user.email}
|
||||
id={user.id}
|
||||
gender={user.demographicInformation?.gender}
|
||||
summary={performanceSummary}
|
||||
testDetails={[
|
||||
{
|
||||
module: "Overall",
|
||||
score: overallScore,
|
||||
total: overallTotal,
|
||||
},
|
||||
...results,
|
||||
]}
|
||||
logo={"public/logo_title.png"}
|
||||
/>
|
||||
);
|
||||
|
||||
const pdfBuffer = await streamToBuffer(pdfStream);
|
||||
const snapshot = await uploadBytes(fileRef, pdfBuffer, {
|
||||
contentType: "application/pdf",
|
||||
});
|
||||
docsSnap.docs.forEach(async (doc) => {
|
||||
await updateDoc(doc.ref, {
|
||||
pdf: snapshot.ref.fullPath,
|
||||
const qrcode = await generateQRCode((req.headers.origin || '') + req.url);
|
||||
|
||||
if(qrcode) {
|
||||
const pdfStream = await ReactPDF.renderToStream(
|
||||
<PDFReport
|
||||
date={new Date(stat.date).toLocaleString()}
|
||||
name={user.name}
|
||||
email={user.email}
|
||||
id={user.id}
|
||||
gender={user.demographicInformation?.gender}
|
||||
summary={performanceSummary}
|
||||
testDetails={[
|
||||
{
|
||||
module: "Overall",
|
||||
score: overallScore,
|
||||
total: overallTotal,
|
||||
},
|
||||
...results,
|
||||
]}
|
||||
logo={"public/logo_title.png"}
|
||||
qrcode={qrcode}
|
||||
/>
|
||||
);
|
||||
|
||||
const pdfBuffer = await streamToBuffer(pdfStream);
|
||||
const snapshot = await uploadBytes(fileRef, pdfBuffer, {
|
||||
contentType: "application/pdf",
|
||||
});
|
||||
});
|
||||
res.status(200).end(snapshot.ref.fullPath);
|
||||
return;
|
||||
docsSnap.docs.forEach(async (doc) => {
|
||||
await updateDoc(doc.ref, {
|
||||
pdf: snapshot.ref.fullPath,
|
||||
});
|
||||
});
|
||||
res.status(200).end(snapshot.ref.fullPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.status(500).json({ ok: false });
|
||||
return;
|
||||
}
|
||||
|
||||
async function get(req: NextApiRequest, res: NextApiResponse) {
|
||||
const { id } = req.query as { id: string };
|
||||
const docsSnap = await getDocs(
|
||||
query(collection(db, "stats"), where("session", "==", id))
|
||||
);
|
||||
|
||||
if (docsSnap.empty) {
|
||||
res.status(404).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const stats = docsSnap.docs.map((d) => d.data());
|
||||
|
||||
const pdfUrl = stats.find((s) => s.pdf);
|
||||
|
||||
if (pdfUrl) {
|
||||
return res.end(pdfUrl);
|
||||
}
|
||||
|
||||
res.status(500).end();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user