import React, { useEffect, useRef, useState } from "react"; import { ArrowLeftIcon, PlusIcon, TrashIcon } from "@heroicons/react/outline"; import ErrorAlert from "@components/ui/alerts/Error"; import { UsernameInput } from "@components/ui/UsernameInput"; import MemberList from "./MemberList"; import Avatar from "@components/ui/Avatar"; import ImageUploader from "@components/ImageUploader"; import { Dialog, DialogTrigger } from "@components/Dialog"; import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogContent"; import Modal from "@components/Modal"; import MemberInvitationModal from "@components/team/MemberInvitationModal"; import Button from "@components/ui/Button"; import { Member } from "@lib/member"; import { Team } from "@lib/team"; export default function EditTeam(props: { team: Team | undefined | null; onCloseEdit: () => void }) { const [members, setMembers] = useState([]); const nameRef = useRef() as React.MutableRefObject; const teamUrlRef = useRef() as React.MutableRefObject; const descriptionRef = useRef() as React.MutableRefObject; const hideBrandingRef = useRef() as React.MutableRefObject; const logoRef = useRef() as React.MutableRefObject; const [hasErrors, setHasErrors] = useState(false); const [successModalOpen, setSuccessModalOpen] = useState(false); const [showMemberInvitationModal, setShowMemberInvitationModal] = useState(false); const [inviteModalTeam, setInviteModalTeam] = useState(); const [errorMessage, setErrorMessage] = useState(""); const [imageSrc, setImageSrc] = useState(""); const loadMembers = () => fetch("/api/teams/" + props.team?.id + "/membership") .then((res) => res.json()) .then((data) => setMembers(data.members)); useEffect(() => { loadMembers(); }, []); const deleteTeam = () => { return fetch("/api/teams/" + props.team?.id, { method: "DELETE", }).then(props.onCloseEdit()); }; const onRemoveMember = (member: Member) => { return fetch("/api/teams/" + props.team?.id + "/membership", { method: "DELETE", body: JSON.stringify({ userId: member.id }), headers: { "Content-Type": "application/json", }, }).then(loadMembers); }; const onInviteMember = (team: Team | null | undefined) => { setShowMemberInvitationModal(true); setInviteModalTeam(team); }; const handleError = async (resp: Response) => { if (!resp.ok) { const error = await resp.json(); throw new Error(error.message); } }; async function updateTeamHandler(event) { event.preventDefault(); const enteredUsername = teamUrlRef?.current?.value.toLowerCase(); const enteredName = nameRef?.current?.value; const enteredDescription = descriptionRef?.current?.value; const enteredLogo = logoRef?.current?.value; const enteredHideBranding = hideBrandingRef?.current?.checked; // TODO: Add validation await fetch("/api/teams/" + props.team?.id + "/profile", { method: "PATCH", body: JSON.stringify({ username: enteredUsername, name: enteredName, description: enteredDescription, logo: enteredLogo, hideBranding: enteredHideBranding, }), headers: { "Content-Type": "application/json", }, }) .then(handleError) .then(() => { setSuccessModalOpen(true); setHasErrors(false); // dismiss any open errors }) .catch((err) => { setHasErrors(true); setErrorMessage(err.message); }); } const onMemberInvitationModalExit = () => { loadMembers(); setShowMemberInvitationModal(false); }; const closeSuccessModal = () => { setSuccessModalOpen(false); }; const handleLogoChange = (newLogo: string) => { logoRef.current.value = newLogo; const nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement?.prototype, "value").set; nativeInputValueSetter?.call(logoRef.current, newLogo); const ev2 = new Event("input", { bubbles: true }); logoRef?.current?.dispatchEvent(ev2); updateTeamHandler(ev2); setImageSrc(newLogo); }; return (

{props.team?.name}

Manage your team


Profile

{hasErrors && }

A few sentences about your team. This will appear on your team's URL page.


Members

{!!members.length && ( )}

Hide all Cal.com branding from your public pages.


Danger Zone

{ e.stopPropagation(); }} className="btn-sm btn-white"> Disband Team deleteTeam()}> Are you sure you want to disband this team? Anyone who you've shared this team link with will no longer be able to book using it.

{showMemberInvitationModal && ( )}
); }