1import { createClient } from “@supabase/supabase-js”2import { cookies } from “next/headers”34const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!5const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!67if (!supabaseUrl || !supabaseServiceKey) {8throw new Error(“Missing Supabase server environment variables”)9}1011// Server-side Supabase client with service role key12export async function createServerSupabaseClient() {13const cookieStore = await cookies()1415return createClient(supabaseUrl, supabaseServiceKey, {16auth: {17autoRefreshToken: false,18persistSession: false,19},20global: {21headers: {22Authorization: `Bearer ${supabaseServiceKey}`,23},24},25})26}2728// Alternative client for user authentication29export async function createServerSupabaseClientForAuth() {30const cookieStore = await cookies()31const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!3233return createClient(supabaseUrl, supabaseAnonKey, {34auth: {35autoRefreshToken: false,36persistSession: false,37},38global: {39headers: {40Cookie: cookieStore.toString(),41},42},43})44}
1import { supabase } from “./supabase”23export interface AuthUser {4id: string5email: string6role: “flipper” | “contractor”7profile: {8firstName: string9lastName: string10companyName?: string11phone?: string12}13}1415export async function signUpWithEmail(userData: {16email: string17password: string18role: “flipper” | “contractor”19firstName: string20lastName: string21companyName?: string22phone?: string23}) {24try {25console.log(“Creating new user account:”, userData.email, “as”, userData.role)26// Validate input data27if (!userData.email || !userData.password || !userData.role || !userData.firstName) {28 return { success: false, error: "Please fill in all required fields." }29}3031if (userData.password.length < 8) {32 return { success: false, error: "Password must be at least 8 characters long." }33}3435if (!userData.email.includes("@")) {36 return { success: false, error: "Please enter a valid email address." }37}3839// First, sign up the user40const { data, error } = await supabase.auth.signUp({41 email: userData.email.trim().toLowerCase(),42 password: userData.password,43 options: {44 data: {45 role: userData.role,46 first_name: userData.firstName.trim(),47 last_name: userData.lastName.trim(),48 company_name: userData.companyName?.trim() || "",49 phone: userData.phone?.trim() || "",50 },51 },52})5354if (error) {55 console.error("Supabase signup error:", error)5657 // Provide user-friendly error messages58 if (error.message.includes("already registered") || error.message.includes("already been registered")) {59 return { success: false, error: "An account with this email already exists. Please sign in instead." }60 }61 if (error.message.includes("Password should be")) {62 return { success: false, error: "Password must be at least 8 characters long." }63 }64 if (error.message.includes("Invalid email")) {65 return { success: false, error: "Please enter a valid email address." }66 }67 if (error.message.includes("signup is disabled")) {68 return { success: false, error: "Account creation is currently disabled. Please contact support." }69 }7071 return { success: false, error: `Account creation failed: ${error.message}` }72}7374if (data.user) {75 console.log("User account created successfully:", data.user.id)7677 // Check if we have a session (user is automatically signed in)78 if (data.session) {79 console.log("User automatically signed in after signup")80 const authUser: AuthUser = {81 id: data.user.id,82 email: data.user.email!,83 role: userData.role,84 profile: {85 firstName: userData.firstName,86 lastName: userData.lastName,87 companyName: userData.companyName,88 phone: userData.phone,89 },90 }9192 return { success: true, user: authUser }93 }9495 // If no session but user exists, try to sign them in immediately96 if (!data.session && data.user.email_confirmed_at) {97 console.log("User created but not signed in, attempting automatic sign in...")9899 const signInResult = await supabase.auth.signInWithPassword({100 email: userData.email.trim().toLowerCase(),101 password: userData.password,102 })103104 if (signInResult.data.session && signInResult.data.user) {105 console.log("User successfully signed in after signup")106 const authUser: AuthUser = {107 id: signInResult.data.user.id,108 email: signInResult.data.user.email!,109 role: userData.role,110 profile: {111 firstName: userData.firstName,112 lastName: userData.lastName,113 companyName: userData.companyName,114 phone: userData.phone,115 },116 }117118 return { success: true, user: authUser }119 }120 }121122 // If email confirmation is required123 if (!data.user.email_confirmed_at) {124 console.log("Email confirmation required")125 return {126 success: true,127 user: null,128 message: "Please check your email and click the confirmation link to activate your account.",129 requiresConfirmation: true,130 }131 }132133 return { success: false, error: "Account created but sign-in failed. Please try signing in manually." }134}135136return { success: false, error: "Account creation failed. Please try again." }137138139} catch (error: any) {140console.error(“Signup error:”, error)141return { success: false, error: `An unexpected error occurred: ${error.message || "Please try again."}` }142}143}144145export async function signInWithEmail(email: string, password: string) {146try {147console.log(“Signing in user:”, email)148149150if (!email || !password) {151 return { success: false, error: "Please enter both email and password." }152}153154const { data, error } = await supabase.auth.signInWithPassword({155 email: email.trim().toLowerCase(),156 password: password,157})158159if (error) {160 console.error("Supabase signin error:", error)161162 // Provide user-friendly error messages163 if (error.message.includes("Invalid login credentials")) {164 return { success: false, error: "Invalid email or password. Please check your credentials." }165 }166 if (error.message.includes("Email not confirmed")) {167 return { success: false, error: "Please check your email and confirm your account before signing in." }168 }169 if (error.message.includes("Too many requests")) {170 return { success: false, error: "Too many login attempts. Please wait a moment and try again." }171 }172173 return { success: false, error: `Sign in failed: ${error.message}` }174}175176if (data.user && data.session) {177 console.log("User signed in successfully:", data.user.id)178179 // Get user data from metadata first180 const role = data.user.user_metadata?.role || "flipper"181 const firstName = data.user.user_metadata?.first_name || "User"182 const lastName = data.user.user_metadata?.last_name || ""183 const companyName = data.user.user_metadata?.company_name184 const phone = data.user.user_metadata?.phone185186 const authUser: AuthUser = {187 id: data.user.id,188 email: data.user.email!,189 role: role as "flipper" | "contractor",190 profile: {191 firstName,192 lastName,193 companyName,194 phone,195 },196 }197198 return { success: true, user: authUser }199}200201return { success: false, error: "Sign in failed. Please try again." }202} catch (error: any) {203console.error(“Signin error:”, error)204return { success: false, error: `An unexpected error occurred: ${error.message || "Please try again."}` }205}206}207208export async function signOut() {209try {210console.log(“Signing out user”)211const { error } = await supabase.auth.signOut()212if (error) {213throw error214}215console.log(“User signed out successfully”)216} catch (error: any) {217console.error(“Sign out error:”, error)218throw error219}220}221222export function onAuthStateChange(callback: (user: AuthUser | null) => void) {223console.log(“Setting up auth state listener”)224225return supabase.auth.onAuthStateChange(async (event, session) => {226console.log(“Auth state changed:”, event, session ? “with session” : “no session”)227228if (session?.user) {229 try {230 const role = session.user.user_metadata?.role || "flipper"231 const firstName = session.user.user_metadata?.first_name || "User"232 const lastName = session.user.user_metadata?.last_name || ""233 const companyName = session.user.user_metadata?.company_name234 const phone = session.user.user_metadata?.phone235236 const authUser: AuthUser = {237 id: session.user.id,238 email: session.user.email!,239 role: role as "flipper" | "contractor",240 profile: {241 firstName,242 lastName,243 companyName,244 phone,245 },246 }247248 console.log("Auth user created:", authUser)249 callback(authUser)250 } catch (error) {251 console.error("Error processing auth state change:", error)252 callback(null)253 }254} else {255 console.log("No session, setting user to null")256 callback(null)257}258}).data.subscription.unsubscribe259}260261export async function getCurrentUser(): Promise<AuthUser | null> {262try {263const {264data: { session },265} = await supabase.auth.getSession()266267if (!session?.user) {268 return null269}270271const role = session.user.user_metadata?.role || "flipper"272const firstName = session.user.user_metadata?.first_name || "User"273const lastName = session.user.user_metadata?.last_name || ""274const companyName = session.user.user_metadata?.company_name275const phone = session.user.user_metadata?.phone276277return {278 id: session.user.id,279 email: session.user.email!,280 role: role as "flipper" | "contractor",281 profile: {282 firstName,283 lastName,284 companyName,285 phone,286 },287}288289} catch (error) {290console.error(“Error getting current user:”, error)291return null292}293}