diff --git a/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx index 80f477001..9ac68f771 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx @@ -116,6 +116,7 @@ import type { } from "@/contracts/types/roles.types"; import { invitesApiService } from "@/lib/apis/invites-api.service"; import { rolesApiService } from "@/lib/apis/roles-api.service"; +import { trackSearchSpaceInviteSent } from "@/lib/posthog/events"; import { cacheKeys } from "@/lib/query-client/cache-keys"; import { cn } from "@/lib/utils"; @@ -1088,10 +1089,12 @@ function InvitesTab({ function CreateInviteDialog({ roles, onCreateInvite, + searchSpaceId, className, }: { roles: Role[]; onCreateInvite: (data: CreateInviteRequest["data"]) => Promise; + searchSpaceId: number; className?: string; }) { const [open, setOpen] = useState(false); @@ -1114,6 +1117,17 @@ function CreateInviteDialog({ const invite = await onCreateInvite(data); setCreatedInvite(invite); + + // Track invite sent event + const roleName = + roleId && roleId !== "default" + ? roles.find((r) => r.id.toString() === roleId)?.name + : undefined; + trackSearchSpaceInviteSent(searchSpaceId, { + roleName, + hasExpiry: !!expiresAt, + hasMaxUses: !!maxUses, + }); } catch (error) { console.error("Failed to create invite:", error); } finally { diff --git a/surfsense_web/app/invite/[invite_code]/page.tsx b/surfsense_web/app/invite/[invite_code]/page.tsx index 30e93c022..617cc9028 100644 --- a/surfsense_web/app/invite/[invite_code]/page.tsx +++ b/surfsense_web/app/invite/[invite_code]/page.tsx @@ -33,6 +33,11 @@ import { import type { AcceptInviteResponse } from "@/contracts/types/invites.types"; import { invitesApiService } from "@/lib/apis/invites-api.service"; import { getBearerToken } from "@/lib/auth-utils"; +import { + trackSearchSpaceInviteAccepted, + trackSearchSpaceInviteDeclined, + trackSearchSpaceUserAdded, +} from "@/lib/posthog/events"; import { cacheKeys } from "@/lib/query-client/cache-keys"; export default function InviteAcceptPage() { @@ -91,6 +96,18 @@ export default function InviteAcceptPage() { if (result) { setAccepted(true); setAcceptedData(result); + + // Track invite accepted and user added events + trackSearchSpaceInviteAccepted( + result.search_space_id, + result.search_space_name, + result.role_name + ); + trackSearchSpaceUserAdded( + result.search_space_id, + result.search_space_name, + result.role_name + ); } } catch (err: any) { setError(err.message || "Failed to accept invite"); @@ -99,6 +116,12 @@ export default function InviteAcceptPage() { } }; + const handleDecline = () => { + // Track invite declined event + trackSearchSpaceInviteDeclined(inviteInfo?.search_space_name); + router.push("/dashboard"); + }; + const handleLoginRedirect = () => { // Store the invite code to redirect back after login localStorage.setItem("pending_invite_code", inviteCode); @@ -324,11 +347,7 @@ export default function InviteAcceptPage() { )} -