import { useTheme } from "@emotion/react"; import TabPanel from "@mui/lab/TabPanel"; import { Box, ButtonGroup, Divider, IconButton, Modal, Stack, TextField, Typography, } from "@mui/material"; import ButtonSpinner from "../../ButtonSpinner"; import Button from "../../Button"; import { useEffect, useState } from "react"; import EditSvg from "../../../assets/icons/edit.svg?react"; import Field from "../../Inputs/Field"; import { credentials } from "../../../Validation/validation"; import axiosInstance from "../../../Utils/axiosConfig"; import { createToast } from "../../../Utils/toastUtils"; import { useSelector } from "react-redux"; import BasicTable from "../../BasicTable"; import Remove from "../../../assets/icons/trash-bin.svg?react"; import Select from "../../Inputs/Select"; /** * 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 { authToken, user } = useSelector((state) => state.auth); //TODO const [orgStates, setOrgStates] = useState({ name: "Bluewave Labs", isEdit: false, }); const [toInvite, setToInvite] = useState({ email: "", role: ["0"], }); const [tableData, setTableData] = useState({}); const [members, setMembers] = useState([]); const [filter, setFilter] = useState("all"); const [errors, setErrors] = useState({}); useEffect(() => { const fetchTeam = async () => { try { const response = await axiosInstance.get("/auth/users", { headers: { Authorization: `Bearer ${authToken}` }, }); setMembers(response.data.data); } catch (error) { createToast({ body: error.message || "Error fetching team members.", }); } }; fetchTeam(); }, [user]); useEffect(() => { let team = members; if (filter !== "all") team = members.filter((member) => member.role.includes(filter)); const data = { cols: [ { id: 1, name: "NAME" }, { id: 2, name: "EMAIL" }, { id: 3, name: "ROLE" }, { id: 4, name: "ACTION" }, ], rows: team?.map((member, idx) => { return { id: member._id, data: [ { id: idx, data: ( {member.firstName + " " + member.lastName} Created {new Date(member.createdAt).toLocaleDateString()} ), }, { id: idx + 1, data: member.email }, { // TODO - Add select dropdown id: idx + 2, data: member.role.includes("admin") ? "Administrator" : "Member", }, { // TODO - Add delete onClick id: idx + 3, data: ( ), }, ], }; }), }; setTableData(data); }, [members, filter]); // RENAME ORGANIZATION const toggleEdit = () => { setOrgStates((prev) => ({ ...prev, isEdit: !prev.isEdit })); }; const handleRename = () => {}; //TODO - implement save team function const handleSaveTeam = () => {}; // INVITE MEMBER const [isOpen, setIsOpen] = useState(false); const handleChange = (event) => { const { value } = event.target; setToInvite((prev) => ({ ...prev, email: value, })); const validation = credentials.validate( { email: value }, { abortEarly: false } ); setErrors((prev) => { const updatedErrors = { ...prev }; if (validation.error) { updatedErrors.email = validation.error.details[0].message; } else { delete updatedErrors.email; } return updatedErrors; }); }; const handleInviteMember = async () => { if (!toInvite.role.includes("user") || !toInvite.role.includes("admin")) setToInvite((prev) => ({ ...prev, role: ["user"] })); const { error } = credentials.validate( { email: toInvite.email }, { abortEarly: false, } ); if (error) { setErrors((prev) => ({ ...prev, email: error.details[0].message })); } else try { await axiosInstance.post( "/auth/invite", { email: toInvite.email, role: toInvite.role, }, { headers: { Authorization: `Bearer ${authToken}` } } ); 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.", }); } }; const closeInviteModal = () => { setIsOpen(false); setToInvite({ email: "", role: ["0"] }); setErrors({}); }; return (
Organization name setOrgStates((prev) => ({ ...prev, name: event.target.value, })) } disabled={!orgStates.isEdit} sx={{ color: theme.palette.otherColors.bluishGray, "& .Mui-disabled": { WebkitTextFillColor: "initial !important", }, "& .Mui-disabled fieldset": { borderColor: "transparent !important", }, }} inputProps={{ sx: { textAlign: "end", padding: theme.gap.small }, }} />