commit
ff93a4c2d3
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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 } } });
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -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>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 170 KiB |
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue