"use server"; import { createClient } from "@/lib/supabase/server"; import { revalidatePath } from "next/cache"; export type InviteStatus = { success?: boolean; error?: string; message?: string; }; export async function inviteUser(prevState: InviteStatus | null, formData: FormData): Promise { const email = formData.get("email") as string; if (!email) { return { error: "Email is required" }; } try { const supabase = await createClient(); const { data: userData, error: userError } = await supabase.auth.getUser(); if (userError || !userData.user) { return { error: "Unauthorized" }; } const { data: profile } = await supabase .from("profiles") .select("organization_id, role") .eq("id", userData.user.id) .single(); if (!profile || profile.role !== "owner" || !profile.organization_id) { return { error: "Only organization owners can invite new members" }; } // Check if user is already a member const { data: existingMember } = await supabase .from("profiles") .select("id") .eq("email", email) .eq("organization_id", profile.organization_id) .maybeSingle(); if (existingMember) { return { error: "User is already a member of this organization" }; } // Check if there's already a pending invitation const { data: existingInvitation } = await supabase .from("invitations") .select("id") .eq("email", email) .eq("organization_id", profile.organization_id) .eq("status", "pending") .gt("expires_at", new Date().toISOString()) .maybeSingle(); if (existingInvitation) { return { error: "An invitation is already pending for this email address" }; } const { error: inviteError } = await supabase .from("invitations") .insert([ { email, organization_id: profile.organization_id, invited_by: userData.user.id, }, ]); if (inviteError) { console.error("Error creating invitation:", inviteError); return { error: "Failed to create invitation" }; } revalidatePath("/dashboard/settings/team"); return { success: true, message: "Invitation sent successfully" }; } catch (error) { console.error("Unexpected error inviting user:", error); return { error: "An unexpected error occurred" }; } } export async function revokeInvitation(formData: FormData) { const id = formData.get("id") as string; if (!id) { throw new Error("Invitation ID is required"); } const supabase = await createClient(); const { data: userData, error: userError } = await supabase.auth.getUser(); if (userError || !userData.user) { throw new Error("Unauthorized"); } const { data: profile } = await supabase .from("profiles") .select("organization_id, role") .eq("id", userData.user.id) .single(); if (!profile || profile.role !== "owner" || !profile.organization_id) { throw new Error("Only organization owners can revoke invitations"); } const { error: deleteError } = await supabase .from("invitations") .delete() .match({ id, organization_id: profile.organization_id }); if (deleteError) { console.error("Error revoking invitation:", deleteError); throw new Error("Failed to revoke invitation"); } revalidatePath("/dashboard/settings/team"); }