import { useTheme } from "@emotion/react"; import TabPanel from "@mui/lab/TabPanel"; import { Button, ButtonGroup, Stack, Typography } from "@mui/material"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import TextInput from "../../Inputs/TextInput"; import { newOrChangedCredentials } from "../../../Validation/validation"; import { networkService } from "../../../main"; import { createToast } from "../../../Utils/toastUtils"; import Select from "../../Inputs/Select"; import { GenericDialog } from "../../Dialog/genericDialog"; import DataTable from "../../Table/"; import { useGetInviteToken } from "../../../Hooks/inviteHooks"; /** * TeamPanel component manages the organization and team members, * providing functionalities like renaming the organization, managing team members, * and inviting new members. * * @returns {JSX.Element} */ const TeamPanel = () => { const theme = useTheme(); const { t } = useTranslation(); const SPACING_GAP = theme.spacing(12); const [toInvite, setToInvite] = useState({ email: "", role: ["user"], }); const [data, setData] = useState([]); const [members, setMembers] = useState([]); const [filter, setFilter] = useState("all"); const [isDisabled, setIsDisabled] = useState(true); const [errors, setErrors] = useState({}); const [isSendingInvite, setIsSendingInvite] = useState(false); const [getInviteToken, clearToken, isLoading, error, token] = useGetInviteToken(); const headers = [ { id: "name", content: t("teamPanel.table.name"), render: (row) => { return ( {row.firstName + " " + row.lastName} {t("teamPanel.table.created")}{" "} {new Date(row.createdAt).toLocaleDateString()} ); }, }, { id: "email", content: t("teamPanel.table.email"), render: (row) => row.email }, { id: "role", content: t("teamPanel.table.role"), render: (row) => row.role, }, ]; useEffect(() => { const fetchTeam = async () => { try { const response = await networkService.getAllUsers(); setMembers(response.data.data); } catch (error) { createToast({ body: error.message || "Error fetching team members.", }); } }; fetchTeam(); }, []); useEffect(() => { const ROLE_MAP = { superadmin: t("roles.superAdmin"), admin: t("roles.admin"), user: t("roles.teamMember"), demo: t("roles.demoUser"), }; let team = members; if (filter !== "all") team = members.filter((member) => { if (filter === "admin") { return member.role.includes("admin") || member.role.includes("superadmin"); } return member.role.includes(filter); }); team = team.map((member) => ({ ...member, id: member._id, role: member.role.map((role) => ROLE_MAP[role]).join(","), })); setData(team); }, [members, filter, t]); useEffect(() => { setIsDisabled(Object.keys(errors).length !== 0 || toInvite.email === ""); }, [errors, toInvite.email]); const [isOpen, setIsOpen] = useState(false); const handleChange = (event) => { const { value } = event.target; const newEmail = value?.toLowerCase() || value; setToInvite((prev) => ({ ...prev, email: newEmail, })); const validation = newOrChangedCredentials.validate( { email: newEmail }, { abortEarly: false } ); setErrors((prev) => { const updatedErrors = { ...prev }; if (validation.error) { updatedErrors.email = validation.error.details[0].message; } else { delete updatedErrors.email; } return updatedErrors; }); }; const handleGetToken = async () => { await getInviteToken({ email: toInvite.email, role: toInvite.role }); }; const handleInviteMember = async () => { if (!toInvite.email) { setErrors((prev) => ({ ...prev, email: "Email is required." })); return; } setIsSendingInvite(true); if (!toInvite.role.includes("user") || !toInvite.role.includes("admin")) setToInvite((prev) => ({ ...prev, role: ["user"] })); const { error } = newOrChangedCredentials.validate( { email: toInvite.email }, { abortEarly: false, } ); if (error) { setErrors((prev) => ({ ...prev, email: error.details[0].message })); return; } try { await networkService.sendInvitationToken({ email: toInvite.email, role: toInvite.role, }); closeInviteModal(); createToast({ body: "Member invited. They will receive an email with details on how to create their account.", }); } catch (error) { createToast({ body: error.message || "Unknown error.", }); } finally { setIsSendingInvite(false); } }; const closeInviteModal = () => { setIsOpen(false); clearToken(); setToInvite({ email: "", role: ["0"] }); setErrors({}); }; return ( {t("teamPanel.teamMembers")}