From f3057c675f69ac505fd8c0ccf18dfc7e8784aefc Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Fri, 13 Dec 2024 15:13:27 +0000 Subject: [PATCH] ENCOA-275 --- src/components/Low/Select.tsx | 28 ++++++++---- src/pages/(admin)/CorporateGradingSystem.tsx | 41 +++++++++++++++++ src/pages/api/grading/multiple.ts | 48 ++++++++++++++++++++ src/pages/dashboard/developer.tsx | 2 +- 4 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 src/pages/api/grading/multiple.ts diff --git a/src/components/Low/Select.tsx b/src/components/Low/Select.tsx index bdc9c68a..c666cbe8 100644 --- a/src/components/Low/Select.tsx +++ b/src/components/Low/Select.tsx @@ -1,6 +1,6 @@ import clsx from "clsx"; -import {ComponentProps, useEffect, useState} from "react"; -import ReactSelect, {GroupBase, StylesConfig} from "react-select"; +import { ComponentProps, useEffect, useState } from "react"; +import ReactSelect, { GroupBase, StylesConfig } from "react-select"; import Option from "@/interfaces/option"; interface Props { @@ -9,14 +9,23 @@ interface Props { options: Option[]; disabled?: boolean; placeholder?: string; - onChange: (value: Option | null) => void; isClearable?: boolean; styles?: StylesConfig>; className?: string; label?: string; } -export default function Select({value, defaultValue, options, placeholder, disabled, onChange, styles, isClearable, label, className}: Props) { +interface MultiProps { + isMulti: true + onChange: (value: Option[] | null) => void +} + +interface SingleProps { + isMulti?: false + onChange: (value: Option | null) => void +} + +export default function Select({ value, isMulti, defaultValue, options, placeholder, disabled, onChange, styles, isClearable, label, className }: Props & (MultiProps | SingleProps)) { const [target, setTarget] = useState(); useEffect(() => { @@ -27,14 +36,15 @@ export default function Select({value, defaultValue, options, placeholder, disab
{label && } ({...base, zIndex: 9999}), + menuPortal: (base) => ({ ...base, zIndex: 9999 }), control: (styles) => ({ ...styles, paddingLeft: "4px", diff --git a/src/pages/(admin)/CorporateGradingSystem.tsx b/src/pages/(admin)/CorporateGradingSystem.tsx index a3afe0bb..28c006b6 100644 --- a/src/pages/(admin)/CorporateGradingSystem.tsx +++ b/src/pages/(admin)/CorporateGradingSystem.tsx @@ -1,13 +1,16 @@ import Button from "@/components/Low/Button"; import Input from "@/components/Low/Input"; import Select from "@/components/Low/Select"; +import Separator from "@/components/Low/Separator"; import { Grading, Step } from "@/interfaces"; import { Entity } from "@/interfaces/entity"; import { User } from "@/interfaces/user"; import { CEFR_STEPS, GENERAL_STEPS, IELTS_STEPS, TOFEL_STEPS } from "@/resources/grading"; +import { mapBy } from "@/utils"; import { checkAccess } from "@/utils/permissions"; import axios from "axios"; import clsx from "clsx"; +import { Divider } from "primereact/divider"; import { useEffect, useState } from "react"; import { BsPlusCircle, BsTrash } from "react-icons/bs"; import { toast } from "react-toastify"; @@ -36,6 +39,7 @@ export default function CorporateGradingSystem({ user, entitiesGrading = [], ent const [entity, setEntity] = useState(entitiesGrading[0]?.entity || undefined) const [isLoading, setIsLoading] = useState(false); const [steps, setSteps] = useState([]); + const [otherEntities, setOtherEntities] = useState([]) useEffect(() => { if (entity) { @@ -63,6 +67,27 @@ export default function CorporateGradingSystem({ user, entitiesGrading = [], ent .finally(() => setIsLoading(false)); }; + const applyToOtherEntities = () => { + if (!steps.every((x) => x.min < x.max)) return toast.error("One of your steps has a minimum threshold inferior to its superior threshold."); + if (areStepsOverlapped(steps)) return toast.error("There seems to be an overlap in one of your steps."); + if ( + steps.reduce((acc, curr) => { + return acc - (curr.max - curr.min + 1); + }, 100) > 0 + ) + return toast.error("There seems to be an open interval in your steps."); + + if (otherEntities.length === 0) return toast.error("Select at least one entity") + + setIsLoading(true); + axios + .post("/api/grading/multiple", { user: user.id, entities: otherEntities, steps }) + .then(() => toast.success("Your grading system has been saved!")) + .then(mutate) + .catch(() => toast.error("Something went wrong, please try again later")) + .finally(() => setIsLoading(false)); + }; + return (
@@ -76,6 +101,22 @@ export default function CorporateGradingSystem({ user, entitiesGrading = [], ent />
+ {entities.length > 1 && ( + <> + + +