"use server"; import { createAdminClient } from "@/lib/supabase/server"; import { auth } from "@clerk/nextjs/server"; import { sendEmail } from "@/lib/email"; async function getOrgAndUserId(): Promise<{ orgId: string; userId: string }> { const { userId } = await auth(); if (!userId) throw new Error("Unauthenticated"); const supabase = await createAdminClient(); const { data } = await supabase .from("organisation_members") .select("organisation_id, role") .eq("user_id", userId) .single(); if (!data) throw new Error("No org found"); return { orgId: data.organisation_id, userId }; } export async function fetchContractsForEmployee(employeeId: string): Promise { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data } = await supabase .from("contracts") .select("*") .eq("organisation_id", orgId) .eq("employee_id", employeeId) .order("created_at", { ascending: false }); return data || []; } export async function createContract(input: { employee_id: string; title: string; template_url?: string; }): Promise<{ success: boolean; id?: string; error?: string }> { const { orgId, userId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { data, error } = await supabase .from("contracts") .insert({ ...input, organisation_id: orgId, created_by: userId, status: "draft", }) .select("id") .single(); if (error) return { success: false, error: error.message }; return { success: true, id: data.id }; } export async function uploadContractFile(file: File): Promise<{ success: boolean; url?: string; error?: string }> { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const ext = file.name.split(".").pop(); const path = `${orgId}/${Date.now()}-contract.${ext}`; const { error } = await supabase.storage.from("contracts").upload(path, file); if (error) return { success: false, error: error.message }; const { data } = await supabase.storage.from("contracts").createSignedUrl(path, 86400 * 365); return { success: true, url: data?.signedUrl }; } export async function sendContractForSignature(id: string): Promise<{ success: boolean; error?: string }> { const supabase = await createAdminClient(); const { data: contract } = await supabase .from("contracts") .select("*, employee:employees(first_name, last_name, email)") .eq("id", id) .single(); if (!contract) return { success: false, error: "Contract not found" }; const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000"; const signUrl = `${baseUrl}/sign/${id}`; // Send email try { await sendEmail({ to: [contract.employee.email], subject: `Please sign your contract: ${contract.title}`, html: `

Hi ${contract.employee.first_name},

Please review and sign your contract: Sign Contract

Contract: ${contract.title}

`, }); } catch { // Email failed but continue } const { error } = await supabase .from("contracts") .update({ status: "sent", sent_at: new Date().toISOString() }) .eq("id", id); if (error) return { success: false, error: error.message }; return { success: true }; } export async function fetchContractById(id: string): Promise { const supabase = await createAdminClient(); const { data } = await supabase .from("contracts") .select("*, employee:employees(first_name, last_name, email), org:organisations(name)") .eq("id", id) .single(); return data; } export async function signContract(id: string, signatureData: string): Promise<{ success: boolean; error?: string }> { const supabase = await createAdminClient(); const { data: contract } = await supabase .from("contracts") .select("*, employee:employees(first_name, last_name, email)") .eq("id", id) .single(); if (!contract) return { success: false, error: "Contract not found" }; const { error } = await supabase .from("contracts") .update({ status: "signed", signed_at: new Date().toISOString(), signature_data: signatureData, }) .eq("id", id); if (error) return { success: false, error: error.message }; // Send confirmation try { await sendEmail({ to: [contract.employee.email], subject: "Contract signed successfully", html: `

Hi ${contract.employee.first_name},

Your contract "${contract.title}" has been signed successfully.

`, }); } catch {} return { success: true }; } export async function deleteContract(id: string): Promise<{ success: boolean; error?: string }> { const { orgId } = await getOrgAndUserId(); const supabase = await createAdminClient(); const { error } = await supabase .from("contracts") .delete() .eq("id", id) .eq("organisation_id", orgId); if (error) return { success: false, error: error.message }; return { success: true }; }