import { observer } from "mobx-react";
import { LinkIcon, CloseIcon } from "outline-icons";
import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import { Link } from "react-router-dom";
import styled from "styled-components";
import { Role } from "@shared/types";
import Button from "~/components/Button";
import CopyToClipboard from "~/components/CopyToClipboard";
import Flex from "~/components/Flex";
import HelpText from "~/components/HelpText";
import Input from "~/components/Input";
import InputSelectRole from "~/components/InputSelectRole";
import NudeButton from "~/components/NudeButton";
import Tooltip from "~/components/Tooltip";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useCurrentUser from "~/hooks/useCurrentUser";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
const MAX_INVITES = 20;
type Props = {
onSubmit: () => void;
};
type InviteRequest = {
email: string;
name: string;
role: Role;
};
function Invite({ onSubmit }: Props) {
const [isSaving, setIsSaving] = React.useState(false);
const [linkCopied, setLinkCopied] = React.useState(false);
const [invites, setInvites] = React.useState([
{
email: "",
name: "",
role: "member",
},
{
email: "",
name: "",
role: "member",
},
{
email: "",
name: "",
role: "member",
},
]);
const { users, policies } = useStores();
const { showToast } = useToasts();
const user = useCurrentUser();
const team = useCurrentTeam();
const { t } = useTranslation();
const predictedDomain = user.email.split("@")[1];
const can = policies.abilities(team.id);
const handleSubmit = React.useCallback(
async (ev: React.SyntheticEvent) => {
ev.preventDefault();
setIsSaving(true);
try {
await users.invite(invites);
onSubmit();
showToast(t("We sent out your invites!"), {
type: "success",
});
} catch (err) {
showToast(err.message, {
type: "error",
});
} finally {
setIsSaving(false);
}
},
[onSubmit, showToast, invites, t, users]
);
const handleChange = React.useCallback((ev, index) => {
setInvites((prevInvites) => {
const newInvites = [...prevInvites];
newInvites[index][ev.target.name] = ev.target.value;
return newInvites;
});
}, []);
const handleAdd = React.useCallback(() => {
if (invites.length >= MAX_INVITES) {
showToast(
t("Sorry, you can only send {{MAX_INVITES}} invites at a time", {
MAX_INVITES,
}),
{
type: "warning",
}
);
}
setInvites((prevInvites) => {
const newInvites = [...prevInvites];
newInvites.push({
email: "",
name: "",
role: "member",
});
return newInvites;
});
}, [showToast, invites, t]);
const handleRemove = React.useCallback(
(ev: React.SyntheticEvent, index: number) => {
ev.preventDefault();
setInvites((prevInvites) => {
const newInvites = [...prevInvites];
newInvites.splice(index, 1);
return newInvites;
});
},
[]
);
const handleCopy = React.useCallback(() => {
setLinkCopied(true);
showToast(t("Share link copied"), {
type: "success",
});
}, [showToast, t]);
const handleRoleChange = React.useCallback((role: Role, index: number) => {
setInvites((prevInvites) => {
const newInvites = [...prevInvites];
newInvites[index]["role"] = role;
return newInvites;
});
}, []);
return (
)}
{invites.map((invite, index) => (
handleChange(ev, index)}
placeholder={`example@${predictedDomain}`}
value={invite.email}
required={index === 0}
autoFocus={index === 0}
flex
/>
handleChange(ev, index)}
value={invite.name}
required={!!invite.email}
/>
handleRoleChange(role as Role, index)}
value={invite.role}
labelHidden={index !== 0}
short
/>
{index !== 0 && (
handleRemove(ev, index)}>
)}
))}
{invites.length <= MAX_INVITES ? (
) : (
)}
);
}
const CopyBlock = styled("div")`
margin: 2em 0;
font-size: 14px;
`;
const Remove = styled("div")`
margin-top: 6px;
position: absolute;
right: -32px;
`;
export default observer(Invite);