Updated the groups section for the teachers and admins

This commit is contained in:
Tiago Ribeiro
2023-10-30 15:27:48 +00:00
parent bd6892dcf1
commit ba3588e97d
4 changed files with 52 additions and 17 deletions

View File

@@ -15,6 +15,7 @@ import {
BsGlobeCentralSouthAsia, BsGlobeCentralSouthAsia,
BsPaperclip, BsPaperclip,
BsPerson, BsPerson,
BsPersonAdd,
BsPersonFill, BsPersonFill,
BsPersonFillGear, BsPersonFillGear,
BsPersonGear, BsPersonGear,
@@ -27,6 +28,7 @@ import {MODULE_ARRAY} from "@/utils/moduleUtils";
import {Module} from "@/interfaces"; import {Module} from "@/interfaces";
import {groupByExam} from "@/utils/stats"; import {groupByExam} from "@/utils/stats";
import IconCard from "./IconCard"; import IconCard from "./IconCard";
import GroupList from "@/pages/(admin)/Lists/GroupList";
interface Props { interface Props {
user: User; user: User;
@@ -116,6 +118,26 @@ export default function CorporateDashboard({user}: Props) {
); );
}; };
const GroupsList = () => {
const filter = (x: Group) => x.admin === user.id || x.participants.includes(user.id);
return (
<>
<div className="flex flex-col gap-4">
<div
onClick={() => setPage("")}
className="flex gap-2 items-center text-mti-purple-light cursor-pointer hover:text-mti-purple-dark transition ease-in-out duration-300">
<BsArrowLeft className="text-xl" />
<span>Back</span>
</div>
<h2 className="text-2xl font-semibold">Groups ({groups.filter(filter).length})</h2>
</div>
<GroupList user={user} />
</>
);
};
const averageLevelCalculator = (studentStats: Stat[]) => { const averageLevelCalculator = (studentStats: Stat[]) => {
const formattedStats = studentStats const formattedStats = studentStats
.map((s) => ({focus: users.find((u) => u.id === s.user)?.focus, score: s.score, module: s.module})) .map((s) => ({focus: users.find((u) => u.id === s.user)?.focus, score: s.score, module: s.module}))
@@ -132,8 +154,8 @@ export default function CorporateDashboard({user}: Props) {
}; };
const DefaultDashboard = () => ( const DefaultDashboard = () => (
<div className="flex -xl:flex-col gap-4"> <>
<section className="flex -lg:flex-wrap xl:flex-col gap-4 items-center -lg:justify-center lg:justify-between text-center"> <section className="flex flex-wrap gap-2 items-center -lg:justify-center lg:justify-between text-center">
<IconCard <IconCard
onClick={() => setPage("students")} onClick={() => setPage("students")}
Icon={BsPersonFill} Icon={BsPersonFill}
@@ -160,6 +182,7 @@ export default function CorporateDashboard({user}: Props) {
value={averageLevelCalculator(stats.filter((s) => groups.flatMap((g) => g.participants).includes(s.user))).toFixed(1)} value={averageLevelCalculator(stats.filter((s) => groups.flatMap((g) => g.participants).includes(s.user))).toFixed(1)}
color="purple" color="purple"
/> />
<IconCard onClick={() => setPage("groups")} Icon={BsPersonAdd} label="Groups" value={groups.length} color="purple" />
<IconCard <IconCard
Icon={BsClock} Icon={BsClock}
label="Expiration Date" label="Expiration Date"
@@ -217,7 +240,7 @@ export default function CorporateDashboard({user}: Props) {
</div> </div>
</div> </div>
</section> </section>
</div> </>
); );
return ( return (
@@ -243,6 +266,7 @@ export default function CorporateDashboard({user}: Props) {
</Modal> </Modal>
{page === "students" && <StudentsList />} {page === "students" && <StudentsList />}
{page === "teachers" && <TeachersList />} {page === "teachers" && <TeachersList />}
{page === "groups" && <GroupsList />}
{page === "" && <DefaultDashboard />} {page === "" && <DefaultDashboard />}
</> </>
); );

View File

@@ -91,7 +91,7 @@ export default function TeacherDashboard({user}: Props) {
}; };
const GroupsList = () => { const GroupsList = () => {
const filter = (x: Group) => x.admin === user.id; const filter = (x: Group) => x.admin === user.id || x.participants.includes(user.id);
return ( return (
<> <>
@@ -126,7 +126,7 @@ export default function TeacherDashboard({user}: Props) {
}; };
const DefaultDashboard = () => ( const DefaultDashboard = () => (
<div className="flex flex-col gap-4"> <>
<section className="flex -lg:flex-wrap gap-4 items-center -lg:justify-center lg:justify-start text-center"> <section className="flex -lg:flex-wrap gap-4 items-center -lg:justify-center lg:justify-start text-center">
<IconCard <IconCard
onClick={() => setPage("students")} onClick={() => setPage("students")}
@@ -188,7 +188,7 @@ export default function TeacherDashboard({user}: Props) {
</div> </div>
</div> </div>
</section> </section>
</div> </>
); );
return ( return (

View File

@@ -10,8 +10,13 @@ export default function useGroups(admin?: string) {
const getData = () => { const getData = () => {
setIsLoading(true); setIsLoading(true);
axios axios
.get<Group[]>(!admin ? "/api/groups" : `/api/groups?admin=${admin}`) .get<Group[]>("/api/groups")
.then((response) => setGroups(response.data)) .then((response) => {
const filter = (g: Group) => g.admin === admin || g.participants.includes(admin || "");
const filteredGroups = admin ? response.data.filter(filter) : response.data;
return setGroups(admin ? filteredGroups.map((g) => ({...g, disableEditing: g.disableEditing || g.admin !== admin})) : filteredGroups);
})
.finally(() => setIsLoading(false)); .finally(() => setIsLoading(false));
}; };

View File

@@ -122,13 +122,15 @@ const CreatePanel = ({user, users, group, onCreate}: CreateDialogProps) => {
); );
}; };
const filterTypes = ["corporate", "teacher"];
export default function GroupList({user}: {user: User}) { export default function GroupList({user}: {user: User}) {
const [editingID, setEditingID] = useState<string>(); const [editingID, setEditingID] = useState<string>();
const [showDisclosure, setShowDisclosure] = useState(false); const [showDisclosure, setShowDisclosure] = useState(false);
const [filterByUser, setFilterByUser] = useState(false); const [filterByUser, setFilterByUser] = useState(false);
const {users} = useUsers(); const {users} = useUsers();
const {groups, reload} = useGroups(filterByUser ? user.id : undefined); const {groups, reload} = useGroups(user && filterTypes.includes(user?.type) ? user.id : undefined);
useEffect(() => { useEffect(() => {
if (editingID) setShowDisclosure(true); if (editingID) setShowDisclosure(true);
@@ -214,7 +216,7 @@ export default function GroupList({user}: {user: User}) {
cell: ({row}: {row: {original: Group}}) => { cell: ({row}: {row: {original: Group}}) => {
return ( return (
<> <>
{(user.type === "developer" || user.type === "owner" || user.id === row.original.admin) && ( {(user?.type === "developer" || user?.type === "owner" || user.id === row.original.admin) && (
<div className="flex gap-2"> <div className="flex gap-2">
{editingID !== row.original.id && ( {editingID !== row.original.id && (
<div data-tip="Edit" className="cursor-pointer tooltip" onClick={() => setEditingID(row.original.id)}> <div data-tip="Edit" className="cursor-pointer tooltip" onClick={() => setEditingID(row.original.id)}>
@@ -290,13 +292,17 @@ export default function GroupList({user}: {user: User}) {
<CreatePanel <CreatePanel
group={editingID ? groups.find((x) => x.id === editingID) : undefined} group={editingID ? groups.find((x) => x.id === editingID) : undefined}
user={user} user={user}
users={users.filter( users={
(u) => user?.type === "corporate" || user?.type === "teacher"
groups ? users.filter(
.filter((g) => g.admin === user.id) (u) =>
.flatMap((g) => g.participants) groups
.includes(u.id) || groups.flatMap((g) => g.participants).includes(u.id), .filter((g) => g.admin === user.id)
)} .flatMap((g) => g.participants)
.includes(u.id) || groups.flatMap((g) => g.participants).includes(u.id),
)
: users
}
onCreate={(group) => { onCreate={(group) => {
(!editingID ? createGroup : updateGroup)(group).then((result) => { (!editingID ? createGroup : updateGroup)(group).then((result) => {
if (result) { if (result) {