From 23b8e53d0c028aa9a410d72064815cf38b5b5005 Mon Sep 17 00:00:00 2001 From: kaamil2 Date: Sat, 7 Oct 2023 00:37:51 -0400 Subject: [PATCH] unfinished errrors in users.ts --- lib/CompoundTypes.ts | 7 + .../20231006165619_init/migration.sql | 128 ++++++++++++++++++ prisma/schema.prisma | 10 +- src/models/users.ts | 32 +++++ src/pages/api/subModules/[id]/index.ts | 10 ++ src/pages/api/subModules/[id]/quizzes.ts | 67 +++++++++ src/pages/api/subModules/[id]/submissions.ts | 79 +++++++++++ 7 files changed, 329 insertions(+), 4 deletions(-) create mode 100644 prisma/migrations/20231006165619_init/migration.sql create mode 100644 src/pages/api/subModules/[id]/index.ts create mode 100644 src/pages/api/subModules/[id]/quizzes.ts create mode 100644 src/pages/api/subModules/[id]/submissions.ts diff --git a/lib/CompoundTypes.ts b/lib/CompoundTypes.ts index 4f57590..f5de5ac 100644 --- a/lib/CompoundTypes.ts +++ b/lib/CompoundTypes.ts @@ -16,6 +16,13 @@ export type UserReturnType = { isAdmin?: string; }; +export type QuizAnswersType = string[] | null; + +export type QuizSubmission = { + subModuleQuizId: number; + score: number; +} + export type Message = { message: string; }; diff --git a/prisma/migrations/20231006165619_init/migration.sql b/prisma/migrations/20231006165619_init/migration.sql new file mode 100644 index 0000000..0d4e78a --- /dev/null +++ b/prisma/migrations/20231006165619_init/migration.sql @@ -0,0 +1,128 @@ +/* + Warnings: + + - You are about to drop the column `curriculumId` on the `Module` table. All the data in the column will be lost. + - You are about to drop the column `createdAt` on the `ModuleExam` table. All the data in the column will be lost. + - You are about to drop the column `updatedAt` on the `ModuleExam` table. All the data in the column will be lost. + - You are about to drop the column `date` on the `Progress` table. All the data in the column will be lost. + - You are about to drop the column `age` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `createdAt` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `education` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `emailVerified` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `employmentStatus` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `ethnicity` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `gender` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `languages` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `livingStatus` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `maritalStatus` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `password` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `registrationDate` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `updatedAt` on the `User` table. All the data in the column will be lost. + - You are about to drop the column `verified` on the `User` table. All the data in the column will be lost. + - You are about to drop the `Account` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `Advisor` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `Badge` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `Consultation` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `Curriculum` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `Session` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `UserBadge` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `VerificationRequest` table. If the table is not empty, all the data it contains will be lost. + - A unique constraint covering the columns `[moduleId]` on the table `ModuleExam` will be added. If there are existing duplicate values, this will fail. + - A unique constraint covering the columns `[subModuleId]` on the table `SubModuleQuiz` will be added. If there are existing duplicate values, this will fail. + - Added the required column `order` to the `Lesson` table without a default value. This is not possible if the table is not empty. + - Added the required column `moduleId` to the `Progress` table without a default value. This is not possible if the table is not empty. + - Added the required column `subModuleId` to the `Progress` table without a default value. This is not possible if the table is not empty. + - Added the required column `moduleExamScores` to the `User` table without a default value. This is not possible if the table is not empty. + - Added the required column `subModuleQuizScores` to the `User` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropForeignKey +ALTER TABLE "Account" DROP CONSTRAINT "Account_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "Consultation" DROP CONSTRAINT "Consultation_advisorId_fkey"; + +-- DropForeignKey +ALTER TABLE "Consultation" DROP CONSTRAINT "Consultation_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "Module" DROP CONSTRAINT "Module_curriculumId_fkey"; + +-- DropForeignKey +ALTER TABLE "Progress" DROP CONSTRAINT "Progress_lessonId_fkey"; + +-- DropForeignKey +ALTER TABLE "Session" DROP CONSTRAINT "Session_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "UserBadge" DROP CONSTRAINT "UserBadge_badgeId_fkey"; + +-- DropForeignKey +ALTER TABLE "UserBadge" DROP CONSTRAINT "UserBadge_userId_fkey"; + +-- AlterTable +ALTER TABLE "Lesson" ADD COLUMN "order" INTEGER NOT NULL; + +-- AlterTable +ALTER TABLE "Module" DROP COLUMN "curriculumId"; + +-- AlterTable +ALTER TABLE "ModuleExam" DROP COLUMN "createdAt", +DROP COLUMN "updatedAt", +ADD COLUMN "answers" TEXT[]; + +-- AlterTable +ALTER TABLE "Progress" DROP COLUMN "date", +ADD COLUMN "moduleId" INTEGER NOT NULL, +ADD COLUMN "subModuleId" INTEGER NOT NULL; + +-- AlterTable +ALTER TABLE "User" DROP COLUMN "age", +DROP COLUMN "createdAt", +DROP COLUMN "education", +DROP COLUMN "emailVerified", +DROP COLUMN "employmentStatus", +DROP COLUMN "ethnicity", +DROP COLUMN "gender", +DROP COLUMN "languages", +DROP COLUMN "livingStatus", +DROP COLUMN "maritalStatus", +DROP COLUMN "password", +DROP COLUMN "registrationDate", +DROP COLUMN "updatedAt", +DROP COLUMN "verified", +ADD COLUMN "lessonsCompleted" INTEGER[], +ADD COLUMN "moduleExamScores" JSONB NOT NULL, +ADD COLUMN "preferences" TEXT[], +ADD COLUMN "registered" BOOLEAN NOT NULL DEFAULT false, +ADD COLUMN "subModuleQuizScores" JSONB NOT NULL; + +-- DropTable +DROP TABLE "Account"; + +-- DropTable +DROP TABLE "Advisor"; + +-- DropTable +DROP TABLE "Badge"; + +-- DropTable +DROP TABLE "Consultation"; + +-- DropTable +DROP TABLE "Curriculum"; + +-- DropTable +DROP TABLE "Session"; + +-- DropTable +DROP TABLE "UserBadge"; + +-- DropTable +DROP TABLE "VerificationRequest"; + +-- CreateIndex +CREATE UNIQUE INDEX "ModuleExam_moduleId_key" ON "ModuleExam"("moduleId"); + +-- CreateIndex +CREATE UNIQUE INDEX "SubModuleQuiz_subModuleId_key" ON "SubModuleQuiz"("subModuleId"); \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 558d55b..6034b2c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -85,8 +85,9 @@ model ModuleExam { moduleId Int @unique module Module @relation(fields: [moduleId], references: [id]) questions String[] - passed Boolean - score Int + //passed Boolean + //score Int + answers String[] } @@ -95,8 +96,9 @@ model SubModuleQuiz { subModuleId Int @unique subModule SubModule @relation(fields: [subModuleId], references: [id]) questions String[] // Similar as above - passed Boolean - score Int + //passed Boolean + //score Int + answers String[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } diff --git a/src/models/users.ts b/src/models/users.ts index 2468212..a5ef8b8 100644 --- a/src/models/users.ts +++ b/src/models/users.ts @@ -31,6 +31,34 @@ export default class Users { } } + + public async updateUserSubModuleQuiz(userId: number, id: number, subModuleQuizId: number, results: boolean[], score: number) { + let user: User; + + try { + const user = await this.usersDB.findUnique({ + where: { + id: userId + }, + }); + if (!user) { + throw "User Not Found" + } + + user.subModuleQuizScores[id] = {"id": subModuleQuizId, "results":results, "score": score} + console.log(user.subModuleQuizScores) + await this.usersDB.update({ + where: { id: userId }, + data: { + subModuleQuizScores: user?.subModuleQuizScores, + }, + }); + + } catch (Error) { + throw "User Not Found" + } + + // Get Insensitive User Information By ID public async getUserById(id: number) { try { @@ -130,4 +158,8 @@ export default class Users { return userExists instanceof Users } + + + + } \ No newline at end of file diff --git a/src/pages/api/subModules/[id]/index.ts b/src/pages/api/subModules/[id]/index.ts new file mode 100644 index 0000000..fa92bdf --- /dev/null +++ b/src/pages/api/subModules/[id]/index.ts @@ -0,0 +1,10 @@ +import type { NextApiRequest, NextApiResponse } from "next"; +import { Message } from "../../../../../lib/CompoundTypes"; + + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + return res.status(404).send({ message: "Not Implemented" }); +} \ No newline at end of file diff --git a/src/pages/api/subModules/[id]/quizzes.ts b/src/pages/api/subModules/[id]/quizzes.ts new file mode 100644 index 0000000..a857c18 --- /dev/null +++ b/src/pages/api/subModules/[id]/quizzes.ts @@ -0,0 +1,67 @@ +import type { NextApiRequest, NextApiResponse } from "next"; +import { getServerSession } from "next-auth"; +import { authOptions } from "../../auth/[...nextauth]"; +import { PrismaClient, ModuleExam,SubModuleQuiz } from "@prisma/client"; +const prisma = new PrismaClient(); +import { Message } from "../../../../../lib/CompoundTypes"; + + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + const session = await getServerSession(req, res, authOptions); + const supportedRequestMethods: { [key: string]: Function } = { + GET: getQuizzes, + }; + + if (req.method) { + return supportedRequestMethods[req.method](req, res, session); + } + return res.status(405).send({ message: "request method not supported" }); +} + +async function getQuizzes ( + req: NextApiRequest, + res: NextApiResponse +) { + let id = Number(req.query.id); + + try { + const subModuleQuiz = await prisma.subModuleQuiz.findUnique({ + where: { + id + } + }); + if (!subModuleQuiz || Object.keys(subModuleQuiz).length == 0) { + return res.status(404).send({message: "SubModule Quiz not found"}) + } + return res.status(200).send(subModuleQuiz); + } catch (error) { + return res.status(403).send({ message: "please input an Integer"}); + } + +} + + +async function getExam( + req: NextApiRequest, + res: NextApiResponse +) { + let id = Number(req.query.id); + + try { + const moduleExam = await prisma.moduleExam.findUnique({ + where: { + id + } + }); + if (!moduleExam || Object.keys(moduleExam).length == 0) { + return res.status(404).send({message: "Module Exam not found"}) + } + return res.status(200).send(moduleExam); + + } catch (error) { + return res.status(403).send({ message: "Please input an Integer" }); + } +} \ No newline at end of file diff --git a/src/pages/api/subModules/[id]/submissions.ts b/src/pages/api/subModules/[id]/submissions.ts new file mode 100644 index 0000000..522157c --- /dev/null +++ b/src/pages/api/subModules/[id]/submissions.ts @@ -0,0 +1,79 @@ +// GET, PUT, DELETE operations for a specific user by ID +import type { NextApiRequest, NextApiResponse } from "next"; +import { getServerSession } from "next-auth"; +import { authOptions } from "../../auth/[...nextauth]"; +import { PrismaClient, SubModuleQuiz, ModuleExam } from "@prisma/client"; +import { Message } from "../../../../../lib/CompoundTypes"; +import { QuizAnswersType } from "../../../../../lib/CompoundTypes"; +import persistentUserInstance from "../../../../../lib/persistentUserInstance"; +import { QuizSubmission } from "../../../../../lib/CompoundTypes"; +const prisma = new PrismaClient(); + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + const session = await getServerSession(req, res, authOptions); + const supportedRequestMethods: { [key: string]: Function } = { + POST: postQuizSubmission, + }; + + if (req.method) { + return supportedRequestMethods[req.method](req, res, session); + } + return res.status(405).send({ message: "request method not supported" }); +} + + +async function postQuizSubmission( + req: NextApiRequest, + res: NextApiResponse +) { + const id = Number(req.query.id); + const quizsubmission : QuizAnswersType = req?.body?.submission + const userId = Number (req?.body?.userId) + + try { + const subModuleQuiz = await prisma.subModuleQuiz.findUnique({ + where: { + id + }, + }); + const correctAnswers = subModuleQuiz?.answers + const subModuleQuizId = subModuleQuiz?.id + + if(!subModuleQuizId || !correctAnswers || correctAnswers.length == 0) { + return res.status(404).send({ message: "Sub Module Quiz not found" }) + } + + + if (correctAnswers?.length != quizsubmission?.length) { + return res.status(400).send({ message: "Different amount of questions and answers" }) + } + + let result:boolean[] = [] + let score = 0 + for(let i=0; i< correctAnswers.length; i++) { + if (correctAnswers[i] == quizsubmission[i]) { + result.push(true) + score += 1 + } else { + result.push(false) + } + } + score = (score / result.length) * 100 + try { + await persistentUserInstance.updateUserSubModuleQuiz(userId, id, subModuleQuizId, result, score); + } catch (Error) { + return res.status(403).send({message: "User Not Found"}) + } + + return res.status(200).send({"subModuleQuizId": id, "score": score}); + + } catch (error) { + return res.status(403).send({ message: "Please input an Integer" }); + } + + + + } \ No newline at end of file