diff --git a/src/pages/api/stats/[id]/export.tsx b/src/pages/api/stats/[id]/export.tsx index 607801dd..a9a08b28 100644 --- a/src/pages/api/stats/[id]/export.tsx +++ b/src/pages/api/stats/[id]/export.tsx @@ -6,6 +6,10 @@ import { getDoc, deleteDoc, updateDoc, + getDocs, + query, + collection, + where, } from "firebase/firestore"; import { withIronSessionApiRoute } from "iron-session/next"; import { sessionOptions } from "@/lib/session"; @@ -20,7 +24,7 @@ import { import blobStream from "blob-stream"; import { Stat } from "@/interfaces/user"; import { User } from "@/interfaces/user"; - +import { Module } from "@/interfaces"; const db = getFirestore(app); export default withIronSessionApiRoute(handler, sessionOptions); @@ -30,71 +34,110 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { } export const streamToBuffer = async ( - stream: NodeJS.ReadableStream, - ): Promise => { - return new Promise((resolve, reject) => { + stream: NodeJS.ReadableStream +): Promise => { + return new Promise((resolve, reject) => { const chunks: Buffer[] = []; - stream.on('data', (data) => { + stream.on("data", (data) => { chunks.push(data); }); - stream.on('end', () => { + stream.on("end", () => { resolve(Buffer.concat(chunks)); }); - stream.on('error', reject); - }); - }; + stream.on("error", reject); + }); +}; + +interface ModuleScore { + score: number; + total: number; + module: Module; +} async function post(req: NextApiRequest, res: NextApiResponse) { // debugger; + debugger; if (req.session.user) { const { id } = req.query as { id: string }; + // const codeCheckerRef = await getDocs( + // query(collection(db, "codes"), where("checkout", "==", checkout)) + // ); - const docRef = doc(db, "stats", id); - const docSnap = await getDoc(docRef); + // const docRef = doc(db, "stats", id).where; + // const docSnap = await getDoc(docRef); - if (docSnap.exists()) { - const stat = docSnap.data() as Stat; + const docsSnap = await getDocs( + query( + collection(db, "stats"), + where("session", "==", id), + where("user", "==", req.session.user.id) + ) + ); - 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( - - ); - - 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; - } + if (docsSnap.empty) { + res.status(404).end(); + return; } - res.status(500).json({ ok: false }); - return; + const docUser = await getDoc(doc(db, "users", req.session.user.id)); + + if (docUser.exists()) { + const user = docUser.data() as User; + + const stats = docsSnap.docs.map((d) => d.data()); + const results = stats.reduce((accm: ModuleScore[], { module, score }) => { + if (accm.find((e: ModuleScore) => e.module === module)) { + return accm.map((e: ModuleScore) => { + if (e.module === module) { + return { + ...e, + score: e.score + score.correct, + total: e.total + score.total, + }; + } + + return e; + }); + } + + return [ + ...accm, + { + module, + score: score.correct, + total: score.total, + }, + ]; + }, []); + + const [stat] = stats as Stat[]; + + const fileName = `${Date.now().toString()}.pdf`; + const fileRef = ref(storage, `exam_report/${fileName}`); + const pdfStream = await ReactPDF.renderToStream( + + ); + + 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, + }); + }); + res.status(200).end(snapshot.ref.fullPath); + return; + } } - res.status(401).json(undefined); + res.status(500).json({ ok: false }); + return; }