refactor(email): remove frontend invite email; be-crm sends it now

Per AppShell, email delivery lives in the domain API. Delete the frontend
/api/email/invite route + invite-email template, and the team-management email
wiring. be-crm now emails invitees on create/resend. Copy link stays as a
fallback (invite token still returned in the pending-invite list).
This commit is contained in:
tanweer919
2026-07-14 15:38:53 +05:30
parent 1a2043eaae
commit 9eb234935d
4 changed files with 11 additions and 175 deletions
+4 -26
View File
@@ -47,20 +47,6 @@ export function TeamManagement() {
}, [members]);
const maxDeals = useMemo(() => Math.max(1, ...members.map((m) => m.deals)), [members]);
// Email the invite link via the serverless route (Twilio). No token (mock mode) → skip.
const emailInvite = async (email: string, token: string | undefined, roleIds: string[]): Promise<boolean> => {
if (!token) return false;
const roleNames = roleIds.map((id) => roleById[id]?.name).filter((n): n is string => !!n);
try {
const res = await fetch("/api/email/invite", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ to: email, token, roleNames }),
});
return res.ok;
} catch { return false; }
};
const filtered = useMemo(() => {
const q = query.trim().toLowerCase();
return members.filter((m) => {
@@ -323,11 +309,8 @@ export function TeamManagement() {
}}>Copy link</Btn>
)}
<Btn variant="soft" size="sm" icon="refresh" onClick={async () => {
try {
const { token } = await team.resendInvite(inv.id);
const emailed = await emailInvite(inv.email, token, inv.roleIds);
toast.push({ tone: "success", title: emailed ? "Invite re-emailed" : "Invite resent", desc: emailed ? `A fresh link was emailed to ${inv.email}.` : `A fresh link was generated for ${inv.email}.` });
} catch (e) { toast.push({ tone: "error", title: "Couldn't resend", desc: (e as Error).message }); }
try { await team.resendInvite(inv.id); toast.push({ tone: "success", title: "Invite resent", desc: `A fresh link was emailed to ${inv.email}.` }); }
catch (e) { toast.push({ tone: "error", title: "Couldn't resend", desc: (e as Error).message }); }
}}>Resend</Btn>
<Btn variant="ghost" size="sm" icon="x" onClick={async () => {
try { await team.revokeInvite(inv.id); toast.push({ tone: "info", title: "Invite revoked" }); }
@@ -348,14 +331,9 @@ export function TeamManagement() {
onInvite={async (email, roleIds) => {
setInviteOpen(false);
try {
const { token } = await team.invite(email, roleIds);
await team.invite(email, roleIds);
setTab("invites");
const emailed = await emailInvite(email, token, roleIds);
toast.push({
tone: "success",
title: emailed ? "Invitation emailed" : "Invitation created",
desc: emailed ? `We emailed the invite to ${email}.` : `Invite ready — use “Copy link” to share it with ${email}.`,
});
toast.push({ tone: "success", title: "Invitation sent", desc: `We emailed an invite to ${email}. You can also copy the link.` });
} catch (e) { toast.push({ tone: "error", title: "Couldn't send invite", desc: (e as Error).message }); }
}}
/>