Hidden the level score when not released
This commit is contained in:
@@ -2,7 +2,7 @@ import React from "react";
|
|||||||
import {BsClock, BsXCircle} from "react-icons/bs";
|
import {BsClock, BsXCircle} from "react-icons/bs";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {Stat, User} from "@/interfaces/user";
|
import {Stat, User} from "@/interfaces/user";
|
||||||
import {Module} from "@/interfaces";
|
import {Module, Step} from "@/interfaces";
|
||||||
import ai_usage from "@/utils/ai.detection";
|
import ai_usage from "@/utils/ai.detection";
|
||||||
import {calculateBandScore} from "@/utils/score";
|
import {calculateBandScore} from "@/utils/score";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
@@ -77,6 +77,7 @@ interface StatsGridItemProps {
|
|||||||
assignments: Assignment[];
|
assignments: Assignment[];
|
||||||
users: User[];
|
users: User[];
|
||||||
training?: boolean;
|
training?: boolean;
|
||||||
|
gradingSystem?: Step[];
|
||||||
selectedTrainingExams?: string[];
|
selectedTrainingExams?: string[];
|
||||||
maxTrainingExams?: number;
|
maxTrainingExams?: number;
|
||||||
setSelectedTrainingExams?: React.Dispatch<React.SetStateAction<string[]>>;
|
setSelectedTrainingExams?: React.Dispatch<React.SetStateAction<string[]>>;
|
||||||
@@ -97,6 +98,7 @@ const StatsGridItem: React.FC<StatsGridItemProps> = ({
|
|||||||
users,
|
users,
|
||||||
training,
|
training,
|
||||||
selectedTrainingExams,
|
selectedTrainingExams,
|
||||||
|
gradingSystem,
|
||||||
setSelectedTrainingExams,
|
setSelectedTrainingExams,
|
||||||
setExams,
|
setExams,
|
||||||
setShowSolutions,
|
setShowSolutions,
|
||||||
@@ -214,10 +216,14 @@ const StatsGridItem: React.FC<StatsGridItemProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex flex-row gap-2">
|
<div className="flex flex-row gap-2">
|
||||||
<span className={textColor}>
|
{!!assignment && (assignment.released || assignment.released === undefined) && (
|
||||||
Level{" "}
|
<span className={textColor}>
|
||||||
{(aggregatedLevels.reduce((accumulator, current) => accumulator + current.level, 0) / aggregatedLevels.length).toFixed(1)}
|
Level{" "}
|
||||||
</span>
|
{(
|
||||||
|
aggregatedLevels.reduce((accumulator, current) => accumulator + current.level, 0) / aggregatedLevels.length
|
||||||
|
).toFixed(1)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
{shouldRenderPDFIcon() && renderPdfIcon(session, textColor, textColor)}
|
{shouldRenderPDFIcon() && renderPdfIcon(session, textColor, textColor)}
|
||||||
</div>
|
</div>
|
||||||
{examNumber === undefined ? (
|
{examNumber === undefined ? (
|
||||||
@@ -242,9 +248,9 @@ const StatsGridItem: React.FC<StatsGridItemProps> = ({
|
|||||||
|
|
||||||
<div className="w-full flex flex-col gap-1">
|
<div className="w-full flex flex-col gap-1">
|
||||||
<div className={clsx("grid grid-cols-4 gap-2 place-items-start w-full -md:mt-2", examNumber !== undefined && "pr-10")}>
|
<div className={clsx("grid grid-cols-4 gap-2 place-items-start w-full -md:mt-2", examNumber !== undefined && "pr-10")}>
|
||||||
{aggregatedLevels.map(({module, level}) => (
|
{!!assignment &&
|
||||||
<ModuleBadge key={module} module={module} level={level} />
|
(assignment.released || assignment.released === undefined) &&
|
||||||
))}
|
aggregatedLevels.map(({module, level}) => <ModuleBadge key={module} module={module} level={level} />)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{assignment && (
|
{assignment && (
|
||||||
|
|||||||
@@ -1,24 +1,28 @@
|
|||||||
|
import {Step} from "@/interfaces";
|
||||||
|
import {getGradingLabel, getLevelLabel} from "@/utils/score";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen } from "react-icons/bs";
|
import {BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
|
||||||
|
|
||||||
const ModuleBadge: React.FC<{ module: string; level?: number }> = ({ module, level }) => (
|
const ModuleBadge: React.FC<{module: string; level?: number; gradingSystem?: Step[]}> = ({module, level, gradingSystem}) => (
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"flex gap-2 items-center w-fit text-white -md:px-4 xl:px-4 md:px-2 py-2 rounded-xl",
|
"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 === "reading" && "bg-ielts-reading",
|
||||||
module === "listening" && "bg-ielts-listening",
|
module === "listening" && "bg-ielts-listening",
|
||||||
module === "writing" && "bg-ielts-writing",
|
module === "writing" && "bg-ielts-writing",
|
||||||
module === "speaking" && "bg-ielts-speaking",
|
module === "speaking" && "bg-ielts-speaking",
|
||||||
module === "level" && "bg-ielts-level",
|
module === "level" && "bg-ielts-level",
|
||||||
)}>
|
)}>
|
||||||
{module === "reading" && <BsBook className="w-4 h-4" />}
|
{module === "reading" && <BsBook className="w-4 h-4" />}
|
||||||
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
|
{module === "listening" && <BsHeadphones className="w-4 h-4" />}
|
||||||
{module === "writing" && <BsPen className="w-4 h-4" />}
|
{module === "writing" && <BsPen className="w-4 h-4" />}
|
||||||
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
|
{module === "speaking" && <BsMegaphone className="w-4 h-4" />}
|
||||||
{module === "level" && <BsClipboard className="w-4 h-4" />}
|
{module === "level" && <BsClipboard className="w-4 h-4" />}
|
||||||
{/* do not switch to level && it will convert the 0.0 to 0*/}
|
{/* do not switch to level && it will convert the 0.0 to 0*/}
|
||||||
{level !== undefined && (<span className="text-sm">{level.toFixed(1)}</span>)}
|
{level !== undefined && (
|
||||||
</div>
|
<span className="text-sm">{module === "level" && gradingSystem ? getGradingLabel(level, gradingSystem) : level.toFixed(1)}</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default ModuleBadge;
|
export default ModuleBadge;
|
||||||
@@ -25,14 +25,16 @@ import useExams from "@/hooks/useExams";
|
|||||||
interface Props {
|
interface Props {
|
||||||
isCreating: boolean;
|
isCreating: boolean;
|
||||||
users: User[];
|
users: User[];
|
||||||
|
user: User;
|
||||||
groups: Group[];
|
groups: Group[];
|
||||||
assignment?: Assignment;
|
assignment?: Assignment;
|
||||||
cancelCreation: () => void;
|
cancelCreation: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AssignmentCreator({isCreating, assignment, groups, users, cancelCreation}: Props) {
|
export default function AssignmentCreator({isCreating, assignment, user, groups, users, cancelCreation}: Props) {
|
||||||
const [selectedModules, setSelectedModules] = useState<Module[]>(assignment?.exams.map((e) => e.module) || []);
|
const [selectedModules, setSelectedModules] = useState<Module[]>(assignment?.exams.map((e) => e.module) || []);
|
||||||
const [assignees, setAssignees] = useState<string[]>(assignment?.assignees || []);
|
const [assignees, setAssignees] = useState<string[]>(assignment?.assignees || []);
|
||||||
|
const [teachers, setTeachers] = useState<string[]>(!!assignment ? assignment.teachers || [] : [...(user.type === "teacher" ? [user.id] : [])]);
|
||||||
const [name, setName] = useState(
|
const [name, setName] = useState(
|
||||||
assignment?.name ||
|
assignment?.name ||
|
||||||
generate({
|
generate({
|
||||||
@@ -84,6 +86,7 @@ export default function AssignmentCreator({isCreating, assignment, groups, users
|
|||||||
endDate,
|
endDate,
|
||||||
selectedModules,
|
selectedModules,
|
||||||
generateMultiple,
|
generateMultiple,
|
||||||
|
teachers,
|
||||||
variant,
|
variant,
|
||||||
instructorGender,
|
instructorGender,
|
||||||
released,
|
released,
|
||||||
|
|||||||
@@ -524,6 +524,7 @@ export default function CorporateDashboard({user, linkedCorporate}: Props) {
|
|||||||
{router.asPath === "/#assignments" && (
|
{router.asPath === "/#assignments" && (
|
||||||
<AssignmentsPage
|
<AssignmentsPage
|
||||||
assignments={assignments}
|
assignments={assignments}
|
||||||
|
user={user}
|
||||||
groups={assignmentsGroups}
|
groups={assignmentsGroups}
|
||||||
users={assignmentsUsers}
|
users={assignmentsUsers}
|
||||||
reloadAssignments={reloadAssignments}
|
reloadAssignments={reloadAssignments}
|
||||||
|
|||||||
@@ -713,6 +713,7 @@ export default function MasterCorporateDashboard({user}: Props) {
|
|||||||
assignments={assignments}
|
assignments={assignments}
|
||||||
corporateAssignments={corporateAssignments}
|
corporateAssignments={corporateAssignments}
|
||||||
groups={assignmentsGroups}
|
groups={assignmentsGroups}
|
||||||
|
user={user}
|
||||||
users={assignmentsUsers}
|
users={assignmentsUsers}
|
||||||
reloadAssignments={reloadAssignments}
|
reloadAssignments={reloadAssignments}
|
||||||
isLoading={isAssignmentsLoading}
|
isLoading={isAssignmentsLoading}
|
||||||
|
|||||||
@@ -301,6 +301,7 @@ export default function TeacherDashboard({user, linkedCorporate}: Props) {
|
|||||||
assignments={assignments}
|
assignments={assignments}
|
||||||
groups={assignmentsGroups}
|
groups={assignmentsGroups}
|
||||||
users={assignmentsUsers}
|
users={assignmentsUsers}
|
||||||
|
user={user}
|
||||||
reloadAssignments={reloadAssignments}
|
reloadAssignments={reloadAssignments}
|
||||||
isLoading={isAssignmentsLoading}
|
isLoading={isAssignmentsLoading}
|
||||||
onBack={() => router.push("/")}
|
onBack={() => router.push("/")}
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ interface Props {
|
|||||||
groups: Group[];
|
groups: Group[];
|
||||||
users: User[];
|
users: User[];
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
|
user: User;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
reloadAssignments: () => void;
|
reloadAssignments: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AssignmentsPage({assignments, corporateAssignments, groups, users, isLoading, onBack, reloadAssignments}: Props) {
|
export default function AssignmentsPage({assignments, corporateAssignments, user, groups, users, isLoading, onBack, reloadAssignments}: Props) {
|
||||||
const [selectedAssignment, setSelectedAssignment] = useState<Assignment>();
|
const [selectedAssignment, setSelectedAssignment] = useState<Assignment>();
|
||||||
const [isCreatingAssignment, setIsCreatingAssignment] = useState(false);
|
const [isCreatingAssignment, setIsCreatingAssignment] = useState(false);
|
||||||
|
|
||||||
@@ -39,6 +40,7 @@ export default function AssignmentsPage({assignments, corporateAssignments, grou
|
|||||||
assignment={selectedAssignment}
|
assignment={selectedAssignment}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
users={users}
|
users={users}
|
||||||
|
user={user}
|
||||||
isCreating={isCreatingAssignment}
|
isCreating={isCreatingAssignment}
|
||||||
cancelCreation={() => {
|
cancelCreation={() => {
|
||||||
setIsCreatingAssignment(false);
|
setIsCreatingAssignment(false);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export interface Assignment {
|
|||||||
instructorGender?: InstructorGender;
|
instructorGender?: InstructorGender;
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
endDate: Date;
|
endDate: Date;
|
||||||
|
teachers?: string[];
|
||||||
archived?: boolean;
|
archived?: boolean;
|
||||||
released?: boolean;
|
released?: boolean;
|
||||||
// unless start is active, the assignment is not visible to the assignees
|
// unless start is active, the assignment is not visible to the assignees
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import useTrainingContentStore from "@/stores/trainingContentStore";
|
|||||||
import {Assignment} from "@/interfaces/results";
|
import {Assignment} from "@/interfaces/results";
|
||||||
import {getUsers} from "@/utils/users.be";
|
import {getUsers} from "@/utils/users.be";
|
||||||
import {getAssignments, getAssignmentsByAssigner} from "@/utils/assignments.be";
|
import {getAssignments, getAssignmentsByAssigner} from "@/utils/assignments.be";
|
||||||
|
import useGradingSystem from "@/hooks/useGrading";
|
||||||
|
|
||||||
export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
|
export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
|
||||||
const user = req.session.user;
|
const user = req.session.user;
|
||||||
@@ -76,6 +77,7 @@ export default function History({user, users, assignments}: Props) {
|
|||||||
const [filter, setFilter] = useState<Filter>();
|
const [filter, setFilter] = useState<Filter>();
|
||||||
|
|
||||||
const {data: stats, isLoading: isStatsLoading} = useFilterRecordsByUser<Stat[]>(statsUserId || user?.id);
|
const {data: stats, isLoading: isStatsLoading} = useFilterRecordsByUser<Stat[]>(statsUserId || user?.id);
|
||||||
|
const {gradingSystem} = useGradingSystem();
|
||||||
|
|
||||||
const setExams = useExamStore((state) => state.setExams);
|
const setExams = useExamStore((state) => state.setExams);
|
||||||
const setShowSolutions = useExamStore((state) => state.setShowSolutions);
|
const setShowSolutions = useExamStore((state) => state.setShowSolutions);
|
||||||
@@ -185,6 +187,7 @@ export default function History({user, users, assignments}: Props) {
|
|||||||
setSelectedTrainingExams={setSelectedTrainingExams}
|
setSelectedTrainingExams={setSelectedTrainingExams}
|
||||||
maxTrainingExams={MAX_TRAINING_EXAMS}
|
maxTrainingExams={MAX_TRAINING_EXAMS}
|
||||||
setExams={setExams}
|
setExams={setExams}
|
||||||
|
gradingSystem={gradingSystem?.steps}
|
||||||
setShowSolutions={setShowSolutions}
|
setShowSolutions={setShowSolutions}
|
||||||
setUserSolutions={setUserSolutions}
|
setUserSolutions={setUserSolutions}
|
||||||
setSelectedModules={setSelectedModules}
|
setSelectedModules={setSelectedModules}
|
||||||
|
|||||||
Reference in New Issue
Block a user