Skip to content

Commit

Permalink
added course progress
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielWTE committed Jul 5, 2024
1 parent e8f6212 commit 3c9c27a
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 3 deletions.
149 changes: 149 additions & 0 deletions app/api/courses/progress/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
const courseId = req.nextUrl.searchParams.get("cid");
const courseSession = req.nextUrl.searchParams.get("cs");
if (!courseId) {
return NextResponse.json(
{ message: "Please provide a course id", error: true },
{ status: 400 }
);
}

try {
const session = await getKindeServerSession(req);
if (!session.isAuthenticated) {
return NextResponse.json(
{ message: "You are not authenticated", error: true },
{ status: 401 }
);
}

const user = await session.getUser();
if (!user) {
return NextResponse.json(
{ message: "User not found", error: true },
{ status: 404 }
);
}

const course = await prisma.courses.findUnique({
where: {
course_id: Number(courseId),
},
});

if (!course) {
return NextResponse.json(
{ message: "Course not found", error: true },
{ status: 404 }
);
}

const data = await prisma.categories.findMany({
where: {
course_id: course.course_id,
},
include: {
questions: true,
},
});

const questions = data.flatMap((category) =>
category.questions.map((question) => ({
...question,
category: category.name,
}))
);

if (questions.length === 0) {
return NextResponse.json(
{ message: "No questions found for this course", error: true },
{ status: 404 }
);
}

let totalQuestions = questions.length;
let answeredQuestions = 0;
let correctAnswers = 0;
let incorrectAnswers = 0;

// get state ids for "correct" and "incorrect"
const correctState = await prisma.course_progress_states.findFirst({
where: {
name: "correct",
},
});

if (!correctState) {
return NextResponse.json(
{ message: "State not found", error: true },
{ status: 404 }
);
}

const incorrectState = await prisma.course_progress_states.findFirst({
where: {
name: "incorrect",
},
});

if (!incorrectState) {
return NextResponse.json(
{ message: "State not found", error: true },
{ status: 404 }
);
}

if (courseSession) {
const courseSessionData = await prisma.course_sessions.findUnique({
where: {
session: courseSession,
user_id: user.id,
},
});

if (courseSessionData) {
const answeredQuestionsData = await prisma.course_progresses.findMany({
where: {
session_id: courseSessionData.course_session_id,
},
});

answeredQuestions = answeredQuestionsData.length;

answeredQuestionsData.forEach((answeredQuestion) => {
if (
answeredQuestion.state_id === correctState.course_progress_state_id
) {
correctAnswers++;
} else if (
answeredQuestion.state_id ===
incorrectState.course_progress_state_id
) {
incorrectAnswers++;
}
});
}
}

return NextResponse.json({
message: "Course progress fetched",
data: {
totalQuestions: totalQuestions,
answeredQuestions: answeredQuestions,
correctAnswers: correctAnswers,
incorrectAnswers: incorrectAnswers,
},
});
} catch (error) {
console.error("Error:", error);
return NextResponse.json(
{ message: "An error occurred", error: true },
{ status: 500 }
);
}
}
24 changes: 21 additions & 3 deletions components/course/CourseHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { SimpleButtonWithLoader } from "../elements/Buttons";
import { mutate } from "swr";
import { useSearchParams } from "next/navigation";
import toast from "react-hot-toast";
import { useGetCourseProgress } from "@/hooks/data/getCourseProgress";

export default function CourseHandlerComponent({
courseId,
Expand All @@ -19,17 +20,26 @@ export default function CourseHandlerComponent({
const session = urlParams.get("session") as string;
const { getQuestionData, getQuestionIsLoading, getQuestionError } =
useGetQuestion({ courseId, session });
const { getCourseProgressData, getCourseProgressIsLoading, getCourseProgressError } =
useGetCourseProgress({ courseId, session });
const [questionData, setQuestionData] = useState([]) as any;
const [answer, setAnswer] = useState("");
const [correctAnswer, setCorrectAnswer] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
const [courseProgress, setCourseProgress] = useState([]) as any;

useEffect(() => {
if (!getQuestionIsLoading && getQuestionData?.data) {
setQuestionData(getQuestionData?.data);
}
}, [getQuestionData]);

useEffect(() => {
if (!getCourseProgressIsLoading && getCourseProgressData?.data) {
setCourseProgress(getCourseProgressData?.data);
}
}, [getCourseProgressData]);

// call submitAnswer when enter and control is pressed
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
Expand Down Expand Up @@ -92,8 +102,9 @@ export default function CourseHandlerComponent({
setAnswer("");
setIsSubmitting(false);
mutate(`/api/questions/get?cid=${courseId}&cs=${session}`);
mutate(`/api/courses/progress?cid=${courseId}&cs=${session}`);
} else {
toast.error("Leider falsch.");
toast.error("Falsch!");
setCorrectAnswer(checkAnswerResponse.correctAnswer);
setIsSubmitting(false);
}
Expand All @@ -103,16 +114,23 @@ export default function CourseHandlerComponent({
setCorrectAnswer("");
setAnswer("");
mutate(`/api/questions/get?cid=${courseId}&cs=${session}`);
mutate(`/api/courses/progress?cid=${courseId}&cs=${session}`);
};

return (
<div className="flex flex-col min-h-full justify-center items-center">
<div className="border-b border-gray-200 bg-white p-6 rounded-lg shadow-sm md:w-[120vw] max-w-lg w-full">
{getQuestionIsLoading && !questionData ? (
{getQuestionIsLoading && !questionData && !courseProgress && getCourseProgressIsLoading ? (
<div>Loading...</div>
) : (
<div key={questionData.question_id}>
<div className="text-gray-500 text-sm">{questionData.category}</div>
<div className="flex justify-between">
<div className="text-gray-500 text-sm">{questionData.category}</div>
<div className="text-gray-500 text-sm">
{parseInt(courseProgress?.answeredQuestions) + 1} /{" "}
{parseInt(courseProgress?.totalQuestions)} Fragen
</div>
</div>
<div className="text-lg font-semibold mt-2 max-w-lg">
{questionData.question}
</div>
Expand Down
28 changes: 28 additions & 0 deletions hooks/data/getCourseProgress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import useSWR from "swr";
import swrGetFetcher from "../swrGetFetcher";

const sampleData = {};

export const useGetCourseProgress = ({ courseId, session }: { courseId: number; session: string }) => {
let fetchedData, error;

const swrOptions = {
revalidateOnFocus: true,
};

if (process.env.NEXT_PUBLIC_DEV_MODE !== "true") {
({ data: fetchedData, error } = useSWR(
`/api/courses/progress?cid=${courseId}&cs=${session}`,
swrGetFetcher,
swrOptions,
));
} else {
fetchedData = sampleData;
}

return {
getCourseProgressData: fetchedData,
getCourseProgressIsLoading: !fetchedData && !error,
getCourseProgressError: error,
};
};

0 comments on commit 3c9c27a

Please sign in to comment.