Initial version of PDF export
This commit is contained in:
100
src/pages/api/stats/[id]/export.tsx
Normal file
100
src/pages/api/stats/[id]/export.tsx
Normal 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);
|
||||
}
|
||||
29
src/pages/api/stats/[id]/index.ts
Normal file
29
src/pages/api/stats/[id]/index.ts
Normal 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(),
|
||||
})),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user