Initial version of PDF export

This commit is contained in:
Joao Ramos
2023-12-28 23:41:21 +00:00
parent 5447c89da4
commit 0b6a66b12d
6 changed files with 670 additions and 6 deletions

View File

@@ -0,0 +1,100 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { app, storage } from "@/firebase";
import {
getFirestore,
doc,
getDoc,
deleteDoc,
updateDoc,
} from "firebase/firestore";
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session";
import ReactPDF from "@react-pdf/renderer";
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";
const db = getFirestore(app);
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") return post(req, res);
}
export const streamToBuffer = async (
stream: NodeJS.ReadableStream,
): Promise<Buffer> => {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
stream.on('data', (data) => {
chunks.push(data);
});
stream.on('end', () => {
resolve(Buffer.concat(chunks));
});
stream.on('error', reject);
});
};
async function post(req: NextApiRequest, res: NextApiResponse) {
// debugger;
if (req.session.user) {
const { id } = req.query as { id: string };
const docRef = doc(db, "stats", id);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
const stat = docSnap.data() as Stat;
if (stat.user !== req.session.user.id) {
res.status(401).json(undefined);
return;
}
// if (stat.pdf) {
// res.status(200).end(docSnap.pdf);
// return;
// }
const docUser = await getDoc(doc(db, "users", stat.user));
if (docUser.exists()) {
const user = docUser.data() as User;
const fileName = `${Date.now().toString()}.pdf`;
const fileRef = ref(storage, `exam_report/${fileName}`);
const pdfStream = await ReactPDF.renderToStream(
<PDFReport
date={new Date(stat.date).toString()}
name={user.name}
email={user.email}
id={user.id}
gender={user.demographicInformation?.gender}
/>
);
const pdfBuffer = await streamToBuffer(pdfStream);
const snapshot = await uploadBytes(fileRef, pdfBuffer, {
contentType: 'application/pdf',
});
await updateDoc(docRef, {
pdf: snapshot.ref.fullPath,
});
res.status(200).end(snapshot.ref.fullPath);
return;
}
}
res.status(500).json({ ok: false });
return;
}
res.status(401).json(undefined);
}

View File

@@ -0,0 +1,29 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase";
import {getFirestore, collection, getDocs, query, where, doc, setDoc, addDoc} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
const db = getFirestore(app);
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) {
res.status(401).json({ok: false});
return;
}
const {id: user} = req.query;
const q = query(collection(db, "stats"), where("user", "==", user));
const snapshot = await getDocs(q);
res.status(200).json(
snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})),
);
}