Merge pull request #9 from Fayorg/dev

Results page
This commit is contained in:
Elie Baier 2023-12-20 10:22:44 +01:00 committed by GitHub
commit ff93a4c2d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 75 deletions

View File

@ -8,7 +8,6 @@ export async function getGrade(testId: number, userId: number) {
grade: true, grade: true,
id: true, id: true,
testId: true, testId: true,
note: true,
createdAt: true, createdAt: true,
}, },
where: { where: {
@ -24,7 +23,6 @@ export async function addGrade(testId: number, userId: number, grade: number, no
const newGrade = await prisma.grade.create({ const newGrade = await prisma.grade.create({
data: { data: {
grade: grade, grade: grade,
note: note,
testId: testId, testId: testId,
userId: userId, userId: userId,
} }

View File

@ -16,7 +16,6 @@ export async function getActiveTest(date: Date) {
select: { select: {
id: true, id: true,
isActive: true, isActive: true,
isPassed: true,
testOf: { testOf: {
select: { select: {
id: true, id: true,
@ -30,7 +29,6 @@ export async function getActiveTest(date: Date) {
}, },
where: { where: {
isActive: true, isActive: true,
isPassed: false,
testOn: new Date(date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + (date.getDate().toString().length === 1 ? '0' + date.getDate() : date.getDate())), testOn: new Date(date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + (date.getDate().toString().length === 1 ? '0' + date.getDate() : date.getDate())),
}, },
}); });
@ -41,7 +39,6 @@ export async function getActiveTestWithGrade(date: Date, userId: number) {
select: { select: {
id: true, id: true,
isActive: true, isActive: true,
isPassed: true,
testOf: { testOf: {
select: { select: {
id: true, id: true,
@ -54,7 +51,6 @@ export async function getActiveTestWithGrade(date: Date, userId: number) {
select: { select: {
id: true, id: true,
grade: true, grade: true,
note: true,
createdAt: true, createdAt: true,
}, },
take: 1, take: 1,
@ -67,7 +63,6 @@ export async function getActiveTestWithGrade(date: Date, userId: number) {
}, },
where: { where: {
isActive: true, isActive: true,
isPassed: false,
testOn: new Date(date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + (date.getDate().toString().length === 1 ? '0' + date.getDate() : date.getDate())), testOn: new Date(date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + (date.getDate().toString().length === 1 ? '0' + date.getDate() : date.getDate())),
}, },
}); });

33
actions/results.ts Normal file
View File

@ -0,0 +1,33 @@
"use server";
import prisma from "@/lib/prisma";
export interface Results {
name: string;
total: number;
}
export async function getResults(testId: number) {
const grades = await prisma.grade.findMany({ where: { testId: testId, user: { isTeacher: false } } });
const allGrades = ['1', '1.5', '2', '2.5', '3', '3.5', '4', '4.5', '5', '5.5', '6'];
let gradeOccurences = new Array(allGrades.length).fill(0);
const gradeList = grades.map((grade) => grade.grade);
for (let i = 0; i < gradeList.length; i++) {
gradeOccurences[allGrades.indexOf(gradeList[i].toString())]++;
}
let data: Results[] = [];
for (let i = 0; i < gradeOccurences.length; i++) {
data.push({
name: allGrades[i],
total: gradeOccurences[i],
});
}
return data;
}
export async function getTeacherResult(testId: number) {
return await prisma.grade.findFirst({ where: { testId: testId, user: { isTeacher: true } } });
}

View File

@ -1,18 +1,16 @@
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import ActiveCard from './ActiveCard'; import ActiveCard from './ActiveCard';
import { getAuthServerSession } from '@/lib/authenticate'; import { getAuthServerSession } from '@/lib/authenticate';
import { red } from 'next/dist/lib/picocolors';
import { redirect } from 'next/navigation'; import { redirect } from 'next/navigation';
export default async function Dashboard() { export default async function Dashboard() {
const authSession = await getAuthServerSession(); const authSession = await getAuthServerSession();
console.log(authSession); console.log(authSession);
if (!authSession || !authSession.user.isTeacher) return redirect('/'); if (!authSession) return redirect('/');
const tests = await prisma.test.findMany({ select: { isActive: true, isPassed: true, id: true, testOf: { select: { id: true, firstName: true, lastName: true, isTeacher: true } } } }); const tests = await prisma.test.findMany({ select: { isActive: true, id: true, testOf: { select: { id: true, firstName: true, lastName: true, isTeacher: true } } } });
const activeTests = tests.filter((test) => test.isActive); const activeTests = tests.filter((test) => test.isActive);
const passedTests = tests.filter((test) => test.isPassed);
return ( return (
<div> <div>

View File

@ -1,43 +1,43 @@
'use server'; 'use client';
import { Chart } from '@components/custom/chart'; import { Chart } from '@components/custom/chart';
import logo from '@images/logo.svg'; import logo from '@images/logo.svg';
import Image from 'next/image'; import Image from 'next/image';
import Prisma from '@lib/prisma'; import ginger from '@images/ginger.png';
import { getResults, getTeacherResult, Results } from '@/actions/results';
import { useEffect, useState } from 'react';
interface data { export default function Page({ params }: { params: { id: string } }) {
name: string; const testId = parseInt(params.id);
total: number;
}
export default async function Page({ params }: { params: { id: string } }) { const [teacherGrade, setTeacherGrade] = useState<number>(0);
const teacherGrade = await Prisma.grade.findFirst({ where: { testId: parseInt(params.id), user: { isTeacher: true } } }); const [data, setData] = useState<Results[]>([]);
const grades = await Prisma.grade.findMany({where: {testId: parseInt(params.id), user: {isTeacher: false}}}); function featchResults(testId: number) {
getTeacherResult(testId)
.then((res) => setTeacherGrade(res?.grade || 0))
.catch((err) => console.error(err));
const allGrades = ['1', '1.5', '2', '2.5', '3', '3.5', '4', '4.5', '5', '5.5', '6']; getResults(testId)
let gradeOccurences = new Array(allGrades.length).fill(0); .then((res) => setData(res))
const gradeList = grades.map((grade) => grade.grade); .catch((err) => console.error(err));
for (let i = 0; i < gradeList.length; i++) {
gradeOccurences[allGrades.indexOf(gradeList[i].toString())]++;
} }
let data: data[] = []; useEffect(() => {
for (let i = 0; i < gradeOccurences.length; i++) { featchResults(testId);
data.push({ setTimeout(() => {
name: allGrades[i], featchResults(testId);
total: gradeOccurences[i], }, 5000);
}); }, [testId]);
}
return ( return (
<div className={'p-4 md:p-12 w-full h-screen bg-black flex flex-col justify-between gap-y-4'}> <div className={'p-4 md:p-12 w-full h-screen bg-black flex flex-col justify-between gap-y-4'}>
<Image src={logo} alt={'Logo'} width={100} height={200} className={'mx-auto w-full md:w-[400px]'} /> <Image src={logo} alt={'Logo'} width={100} height={200} className={'mx-auto w-full md:w-[400px]'} />
{teacherGrade && ( {teacherGrade && (
<div className={'flex flex-col gap-y-2'}> <div className={'flex justify-center relative w-full'}>
<p className="text-white">Mme Tixhon :</p> <div className={'flex items-center text-center'}>
<h2 className={'text-4xl font-bold text-white'}>{teacherGrade.grade}</h2> <Image src={ginger} alt={'Logo'} width={120} height={120} className={'inline-flex'} />
<h2 className={'text-4xl font-bold text-white absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]'}>{teacherGrade}</h2>
</div>
</div> </div>
)} )}
<Chart data={data} /> <Chart data={data} />

View File

@ -1,32 +1,32 @@
"use client" 'use client';
import {Santa} from "@components/custom/santa"; import { Santa } from '@components/custom/santa';
interface ChartProps { interface ChartProps {
data: { data: {
name: string name: string;
total: number total: number;
}[] }[];
} }
export function Chart({...props}: ChartProps) { export function Chart({ ...props }: ChartProps) {
return ( return (
<div className={"text-[#F0F0F0] flex-1 flex items-end"}> <div className={'text-[#F0F0F0] flex-1 flex items-end'}>
<div className={"w-full"}> <div className={'w-full'}>
<div className={"flex flex-row justify-between w-full items-end"}> <div className={'flex flex-row justify-between w-full items-end'}>
{props.data.map((item, index) => ( {props.data.map((item, index) => (
<Santa height={item.total} key={index}/> <Santa height={item.total} key={index} />
))} ))}
</div> </div>
<div className={"flex flex-row justify-between w-full items-end mt-2"}> <div className={'flex flex-row justify-between w-full items-end mt-2'}>
{props.data.map((item, index) => ( {props.data.map((item, index) => (
<div className={"w-[100px] h-fit flex flex-col items-center"} key={index}> <div className={'w-[100px] h-fit flex flex-col items-center'} key={index}>
<div className={"h-[14px] w-[3pt] bg-white"}/> <div className={'h-[14px] w-[3pt] bg-white'} />
<span className={""}>{item.name}</span> <span className={''}>{item.name}</span>
</div> </div>
))} ))}
</div> </div>
</div> </div>
</div> </div>
) );
} }

View File

@ -8,7 +8,7 @@ import { Session } from 'next-auth';
import { addGrade } from '@/actions/grades'; import { addGrade } from '@/actions/grades';
export function GradingForm({ session, testId }: { session: Session; testId: number }) { export function GradingForm({ session, testId }: { session: Session; testId: number }) {
const [grade, setGrade] = useState<number>(0); const [grade, setGrade] = useState<number>(4);
const [hasVoted, setHasVoted] = useState<boolean>(false); const [hasVoted, setHasVoted] = useState<boolean>(false);
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) { async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
@ -39,7 +39,7 @@ export function GradingForm({ session, testId }: { session: Session; testId: num
<div className={'w-full md:w-[400px]'}> <div className={'w-full md:w-[400px]'}>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div> <div>
<input type="range" min="2" max="12" id="gradeSelector" className={'w-full h-4 bg-white range range:bg-white text-white'} onChange={(e) => setGrade(Number(e.target.value) / 2)} /> <input type="range" value={grade} step="0.5" min="1" max="6" id="gradeSelector" className={"w-full appearance-none bg-transparent [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-primary/75 accent-accent"} onChange={(e) => setGrade(Number(e.target.value))} />
</div> </div>
<div className={'flex flex-row justify-evenly'}> <div className={'flex flex-row justify-evenly'}>
<Image src={YourGrade} alt={YourGrade} width={100} /> <Image src={YourGrade} alt={YourGrade} width={100} />

BIN
images/ginger.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

View File

@ -14,6 +14,7 @@ model Users {
firstName String firstName String
lastName String lastName String
isTeacher Boolean @default(false) isTeacher Boolean @default(false)
isAdmin Boolean @default(false)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
grades Grade[] grades Grade[]
test Test? test Test?
@ -27,14 +28,11 @@ model Test {
testOf Users @relation(fields: [testOfId], references: [id]) testOf Users @relation(fields: [testOfId], references: [id])
grades Grade[] grades Grade[]
isActive Boolean @default(false) isActive Boolean @default(false)
isPassed Boolean @default(false)
teacherGrade Float?
} }
model Grade { model Grade {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
userId Int userId Int
note String?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
grade Float grade Float
testId Int testId Int