'use server' import { createClient } from '@/lib/supabase/server' export type Collaborator = { id: string user_id: string role: 'owner' | 'editor' | 'viewer' invited_at: string accepted_at: string | null display_name: string | null email: string | null } export async function getCollaborators( projectId: string ): Promise<{ success: boolean; data?: Collaborator[]; error?: string }> { const supabase = await createClient() const { data: { user }, } = await supabase.auth.getUser() if (!user) { return { success: false, error: 'Not authenticated' } } // Verify user owns the project const { data: project } = await supabase .from('projects') .select('id, user_id') .eq('id', projectId) .single() if (!project) { return { success: false, error: 'Project not found' } } const isOwner = project.user_id === user.id // Check if user is a collaborator if (!isOwner) { const { data: collab } = await supabase .from('project_collaborators') .select('id') .eq('project_id', projectId) .eq('user_id', user.id) .single() if (!collab) { return { success: false, error: 'Access denied' } } } // Fetch collaborators with profile info const { data: collaborators, error } = await supabase .from('project_collaborators') .select('id, user_id, role, invited_at, accepted_at, profiles(display_name, email)') .eq('project_id', projectId) if (error) { return { success: false, error: error.message } } const result: Collaborator[] = (collaborators || []).map((c) => { const profile = c.profiles as unknown as { display_name: string | null; email: string | null } | null return { id: c.id, user_id: c.user_id, role: c.role as 'owner' | 'editor' | 'viewer', invited_at: c.invited_at, accepted_at: c.accepted_at, display_name: profile?.display_name || null, email: profile?.email || null, } }) return { success: true, data: result } } export async function inviteCollaborator( projectId: string, email: string, role: 'editor' | 'viewer' ): Promise<{ success: boolean; error?: string }> { const supabase = await createClient() const { data: { user }, } = await supabase.auth.getUser() if (!user) { return { success: false, error: 'Not authenticated' } } // Verify user owns the project const { data: project } = await supabase .from('projects') .select('id, user_id') .eq('id', projectId) .eq('user_id', user.id) .single() if (!project) { return { success: false, error: 'Only the project owner can invite collaborators' } } // Find the user by email in profiles const { data: targetProfile } = await supabase .from('profiles') .select('id, email') .eq('email', email) .single() if (!targetProfile) { return { success: false, error: 'No user found with that email address' } } // Cannot invite yourself if (targetProfile.id === user.id) { return { success: false, error: 'You cannot invite yourself' } } // Check if already a collaborator const { data: existing } = await supabase .from('project_collaborators') .select('id') .eq('project_id', projectId) .eq('user_id', targetProfile.id) .single() if (existing) { return { success: false, error: 'This user is already a collaborator' } } // Insert collaborator const { error: insertError } = await supabase .from('project_collaborators') .insert({ project_id: projectId, user_id: targetProfile.id, role, invited_at: new Date().toISOString(), accepted_at: new Date().toISOString(), // Auto-accept for now }) if (insertError) { return { success: false, error: insertError.message } } return { success: true } } export async function updateCollaboratorRole( projectId: string, collaboratorId: string, role: 'editor' | 'viewer' ): Promise<{ success: boolean; error?: string }> { const supabase = await createClient() const { data: { user }, } = await supabase.auth.getUser() if (!user) { return { success: false, error: 'Not authenticated' } } // Verify user owns the project const { data: project } = await supabase .from('projects') .select('id, user_id') .eq('id', projectId) .eq('user_id', user.id) .single() if (!project) { return { success: false, error: 'Only the project owner can change roles' } } const { error } = await supabase .from('project_collaborators') .update({ role }) .eq('id', collaboratorId) .eq('project_id', projectId) if (error) { return { success: false, error: error.message } } return { success: true } } export async function removeCollaborator( projectId: string, collaboratorId: string ): Promise<{ success: boolean; error?: string }> { const supabase = await createClient() const { data: { user }, } = await supabase.auth.getUser() if (!user) { return { success: false, error: 'Not authenticated' } } // Verify user owns the project const { data: project } = await supabase .from('projects') .select('id, user_id') .eq('id', projectId) .eq('user_id', user.id) .single() if (!project) { return { success: false, error: 'Only the project owner can remove collaborators' } } const { error } = await supabase .from('project_collaborators') .delete() .eq('id', collaboratorId) .eq('project_id', projectId) if (error) { return { success: false, error: error.message } } return { success: true } }