/* eslint-disable @next/next/no-img-element */ import Tooltip from "@/components/Low/Tooltip"; import { useEntityPermission } from "@/hooks/useEntityPermissions"; import { useListSearch } from "@/hooks/useListSearch"; import usePagination from "@/hooks/usePagination"; import { EntityWithRoles } from "@/interfaces/entity"; import { GroupWithUsers, User } from "@/interfaces/user"; import { sessionOptions } from "@/lib/session"; import { USER_TYPE_LABELS } from "@/resources/user"; import { filterBy, mapBy, redirect, serialize } from "@/utils"; import { requestUser } from "@/utils/api"; import { getEntityWithRoles } from "@/utils/entities.be"; import { convertToUsers, getGroup } from "@/utils/groups.be"; import { shouldRedirectHome } from "@/utils/navigation.disabled"; import { doesEntityAllow } from "@/utils/permissions"; import { getUserName, isAdmin } from "@/utils/users"; import { getEntityUsers, getSpecificUsers } from "@/utils/users.be"; import axios from "axios"; import clsx from "clsx"; import { withIronSessionSsr } from "iron-session/next"; import { capitalize, last } from "lodash"; import moment from "moment"; import Head from "next/head"; import Link from "next/link"; import { useRouter } from "next/router"; import { Divider } from "primereact/divider"; import { useEffect, useMemo, useState } from "react"; import { BsBuilding, BsChevronLeft, BsClockFill, BsEnvelopeFill, BsFillPersonVcardFill, BsPlus, BsStopwatchFill, BsTag, BsTrash, BsX, } from "react-icons/bs"; import { toast, ToastContainer } from "react-toastify"; export const getServerSideProps = withIronSessionSsr( async ({ req, res, params }) => { const user = await requestUser(req, res); if (!user) return redirect("/login"); if (shouldRedirectHome(user)) return redirect("/"); const { id } = params as { id: string }; const group = await getGroup(id); if (!group || !group.entity) return redirect("/classrooms"); const entity = await getEntityWithRoles(group.entity); if (!entity) return redirect("/classrooms"); const canView = doesEntityAllow(user, entity, "view_classrooms"); if (!canView) return redirect("/"); const [linkedUsers, users] = await Promise.all([ getEntityUsers( entity.id, 0, {}, { _id: 0, id: 1, name: 1, email: 1, corporateInformation: 1, type: 1, profilePicture: 1, subscriptionExpirationDate: 1, lastLogin: 1, } ), getSpecificUsers([...group.participants, group.admin], { _id: 0, id: 1, name: 1, email: 1, corporateInformation: 1, type: 1, profilePicture: 1, subscriptionExpirationDate: 1, lastLogin: 1, }), ]); const groupWithUser = convertToUsers(group, users); return { props: serialize({ user, group: groupWithUser, users: linkedUsers.filter((x) => (isAdmin(user) ? true : !isAdmin(x))), entity, }), }; }, sessionOptions ); interface Props { user: User; group: GroupWithUsers; users: User[]; entity: EntityWithRoles; } export default function Home({ user, group, users, entity }: Props) { const [isAdding, setIsAdding] = useState(false); const [isLoading, setIsLoading] = useState(false); const [selectedUsers, setSelectedUsers] = useState([]); const canAddParticipants = useEntityPermission( user, entity, "add_to_classroom" ); const canRemoveParticipants = useEntityPermission( user, entity, "remove_from_classroom" ); const canRenameClassroom = useEntityPermission( user, entity, "rename_classrooms" ); const canDeleteClassroom = useEntityPermission( user, entity, "delete_classroom" ); const nonParticipantUsers = useMemo( () => users.filter( (x) => ![ ...group.participants.map((g) => g.id), group.admin.id, user.id, ].includes(x.id) ), [users, group.participants, group.admin.id, user.id] ); const { rows, renderSearch } = useListSearch( [["name"], ["corporateInformation", "companyInformation", "name"]], isAdding ? nonParticipantUsers : group.participants ); const { items, renderMinimal } = usePagination(rows, 20); const router = useRouter(); const toggleUser = (u: User) => setSelectedUsers((prev) => prev.includes(u.id) ? prev.filter((p) => p !== u.id) : [...prev, u.id] ); const removeParticipants = () => { if (selectedUsers.length === 0) return; if (!canRemoveParticipants) return; if ( !confirm( `Are you sure you want to remove ${selectedUsers.length} participant${ selectedUsers.length === 1 ? "" : "s" } from this group?` ) ) return; setIsLoading(true); axios .patch(`/api/groups/${group.id}`, { participants: group.participants .map((x) => x.id) .filter((x) => !selectedUsers.includes(x)), }) .then(() => { toast.success("The group has been updated successfully!"); router.replace(router.asPath); }) .catch((e) => { console.error(e); toast.error("Something went wrong!"); }) .finally(() => setIsLoading(false)); }; const addParticipants = () => { if (selectedUsers.length === 0) return; if (!canAddParticipants || !isAdding) return; if ( !confirm( `Are you sure you want to add ${selectedUsers.length} participant${ selectedUsers.length === 1 ? "" : "s" } to this group?` ) ) return; setIsLoading(true); axios .patch(`/api/groups/${group.id}`, { participants: [ ...group.participants.map((x) => x.id), ...selectedUsers, ], }) .then(() => { toast.success("The group has been updated successfully!"); router.replace(router.asPath); }) .catch((e) => { console.error(e); toast.error("Something went wrong!"); }) .finally(() => setIsLoading(false)); }; const renameGroup = () => { if (!canRenameClassroom) return; const name = prompt("Rename this classroom:", group.name); if (!name) return; setIsLoading(true); axios .patch(`/api/groups/${group.id}`, { name }) .then(() => { toast.success("The classroom has been updated successfully!"); router.replace(router.asPath); }) .catch((e) => { console.error(e); toast.error("Something went wrong!"); }) .finally(() => setIsLoading(false)); }; const deleteGroup = () => { if (!canDeleteClassroom) return; if (!confirm("Are you sure you want to delete this classroom?")) return; setIsLoading(true); axios .delete(`/api/groups/${group.id}`) .then(() => { toast.success("This classroom has been successfully deleted!"); router.replace("/classrooms"); }) .catch((e) => { console.error(e); toast.error("Something went wrong!"); }) .finally(() => setIsLoading(false)); }; useEffect(() => setSelectedUsers([]), [isAdding]); return ( <> {group.name} | EnCoach {user && ( <>

{group.name}

{!isAdding && (
)}
{entity.label} {" "} {getUserName(group.admin)}
Participants {!isAdding && (
)} {isAdding && (
)}
{renderSearch()} {renderMinimal()}
{["student", "teacher", "corporate"].map((type) => ( ))}
{items.map((u) => ( ))}
)} ); }