Enabled a way for students to do assigned tasks

This commit is contained in:
Tiago Ribeiro
2023-11-09 11:44:58 +00:00
parent c2acb39859
commit 536c1dfab3
7 changed files with 123 additions and 22 deletions

View File

@@ -41,6 +41,7 @@ export default function ExamPage({page}: Props) {
const [userSolutions, setUserSolutions] = useExamStore((state) => [state.userSolutions, state.setUserSolutions]);
const [showSolutions, setShowSolutions] = useExamStore((state) => [state.showSolutions, state.setShowSolutions]);
const [selectedModules, setSelectedModules] = useExamStore((state) => [state.selectedModules, state.setSelectedModules]);
const assignment = useExamStore((state) => state.assignment);
const {user} = useUser({redirectTo: "/login"});
const router = useRouter();
@@ -98,6 +99,7 @@ export default function ExamPage({page}: Props) {
module: solution.module!,
user: user?.id || "",
date: new Date().getTime(),
...(assignment ? {assignment: assignment.id} : {}),
}));
axios

View File

@@ -1,10 +1,12 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase";
import {getFirestore, collection, getDocs, query, where, doc, setDoc, addDoc} from "firebase/firestore";
import {getFirestore, collection, getDocs, query, where, doc, setDoc, addDoc, getDoc} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
import {Stat} from "@/interfaces/user";
import {Assignment} from "@/interfaces/results";
import {groupBy} from "lodash";
const db = getFirestore(app);
@@ -42,5 +44,29 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const stats = req.body as Stat[];
await stats.forEach(async (stat) => await addDoc(collection(db, "stats"), stat));
const groupedStatsByAssignment = groupBy(
stats.filter((x) => !!x.assignment),
"assignment",
);
if (Object.keys(groupedStatsByAssignment).length > 0) {
const assignments = Object.keys(groupedStatsByAssignment);
await assignments.forEach(async (assignmentId) => {
const assignmentStats = groupedStatsByAssignment[assignmentId] as Stat[];
const assignmentSnapshot = await getDoc(doc(db, "assignments", assignmentId));
await setDoc(
doc(db, "assignments", assignmentId),
{
results: [
...(assignmentSnapshot.data() as Assignment).results,
{user: req.session.user?.id, type: req.session.user?.focus, stats: assignmentStats},
],
},
{merge: true},
);
});
}
res.status(200).json({ok: true});
}

View File

@@ -22,6 +22,7 @@ import {BsBook, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
import Select from "react-select";
import useGroups from "@/hooks/useGroups";
import {shouldRedirectHome} from "@/utils/navigation.disabled";
import useAssignments from "@/hooks/useAssignments";
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user;
@@ -57,6 +58,7 @@ export default function History({user}: {user: User}) {
const [statsUserId, setStatsUserId] = useState<string | undefined>(user.id);
const [groupedStats, setGroupedStats] = useState<{[key: string]: Stat[]}>();
const [filter, setFilter] = useState<"months" | "weeks" | "days">();
const {assignments} = useAssignments({});
const {users} = useUsers();
const {stats, isLoading: isStatsLoading} = useStats(statsUserId);
@@ -147,6 +149,8 @@ export default function History({user}: {user: User}) {
const correct = dateStats.reduce((accumulator, current) => accumulator + current.score.correct, 0);
const total = dateStats.reduce((accumulator, current) => accumulator + current.score.total, 0);
const aggregatedScores = aggregateScoresByModule(dateStats).filter((x) => x.total > 0);
const assignmentID = dateStats.reduce((_, current) => current.assignment as any, "");
const assignment = assignments.find((a) => a.id === assignmentID);
const aggregatedLevels = aggregatedScores.map((x) => ({
module: x.module,
@@ -196,24 +200,33 @@ export default function History({user}: {user: User}) {
{(aggregatedLevels.reduce((accumulator, current) => accumulator + current.level, 0) / aggregatedLevels.length).toFixed(1)}
</span>
</div>
<div className="grid grid-cols-4 gap-2 place-items-start w-full -md:mt-2">
{aggregatedLevels.map(({module, level}) => (
<div
key={module}
className={clsx(
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl",
module === "reading" && "bg-ielts-reading",
module === "listening" && "bg-ielts-listening",
module === "writing" && "bg-ielts-writing",
module === "speaking" && "bg-ielts-speaking",
)}>
{module === "reading" && <BsBook className="w-4 h-4" />}
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
{module === "writing" && <BsPen className="w-4 h-4" />}
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
<span className="text-sm">{level.toFixed(1)}</span>
</div>
))}
<div className="w-full flex flex-col gap-1">
<div className="grid grid-cols-4 gap-2 place-items-start w-full -md:mt-2">
{aggregatedLevels.map(({module, level}) => (
<div
key={module}
className={clsx(
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl",
module === "reading" && "bg-ielts-reading",
module === "listening" && "bg-ielts-listening",
module === "writing" && "bg-ielts-writing",
module === "speaking" && "bg-ielts-speaking",
)}>
{module === "reading" && <BsBook className="w-4 h-4" />}
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
{module === "writing" && <BsPen className="w-4 h-4" />}
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
<span className="text-sm">{level.toFixed(1)}</span>
</div>
))}
</div>
{assignment && (
<span className="font-light text-sm">
Assignment: {assignment.name}, Teacher: {users.find((u) => u.id === assignment.assigner)?.name}
</span>
)}
</div>
</>
);