diff --git a/components/SupabaseConnectionTest.tsx b/components/SupabaseConnectionTest.tsx index 559c5a1..70485ee 100644 --- a/components/SupabaseConnectionTest.tsx +++ b/components/SupabaseConnectionTest.tsx @@ -1,7 +1,7 @@ 'use client' import { useEffect, useState } from 'react' -import { supabase } from '@/lib/supabase/client' +import { supabase, isSupabaseConfigured } from '@/lib/supabase/client' export function SupabaseConnectionTest() { const [connectionStatus, setConnectionStatus] = useState<'testing' | 'connected' | 'error'>('testing') @@ -9,9 +9,15 @@ export function SupabaseConnectionTest() { useEffect(() => { const testConnection = async () => { + if (!isSupabaseConfigured) { + setConnectionStatus('error') + setError('Supabase not configured') + return + } + try { console.log('🔗 Testing Supabase connection...') - + // Test basic connection const { data, error } = await supabase .from('profiles') diff --git a/contexts/AuthContext.tsx b/contexts/AuthContext.tsx index 5045e77..cde6284 100644 --- a/contexts/AuthContext.tsx +++ b/contexts/AuthContext.tsx @@ -2,6 +2,7 @@ import { createContext, useContext, useEffect, useState, ReactNode } from 'react' import { authService } from '@/lib/auth/auth.service' +import { isSupabaseConfigured } from '@/lib/supabase/client' import { AuthContextType, AuthUser, SignInCredentials, SignUpCredentials, UserProfile } from '@/lib/auth/auth.types' const AuthContext = createContext(undefined) @@ -19,11 +20,15 @@ export function AuthProvider({ children }: AuthProviderProps) { // Check for existing session on mount checkUser() - // Listen for auth state changes - const { data: { subscription } } = authService.onAuthStateChange((authUser) => { - setUser(authUser) - setLoading(false) - }) + // Listen for auth state changes when configured + let subscription: any + if (isSupabaseConfigured) { + const { data } = authService.onAuthStateChange((authUser) => { + setUser(authUser) + setLoading(false) + }) + subscription = data?.subscription + } return () => { subscription?.unsubscribe() diff --git a/lib/auth/auth.service.ts b/lib/auth/auth.service.ts index 81c1057..2de9343 100644 --- a/lib/auth/auth.service.ts +++ b/lib/auth/auth.service.ts @@ -1,4 +1,4 @@ -import { supabase } from '@/lib/supabase/client' +import { supabase, isSupabaseConfigured } from '@/lib/supabase/client' import { AuthUser, UserProfile, SignInCredentials, SignUpCredentials } from './auth.types' import { AuthError, User } from '@supabase/supabase-js' @@ -7,11 +7,15 @@ class AuthService { * Transform Supabase user to our AuthUser type */ private async transformUser(user: User): Promise { - const { data: profile } = await supabase - .from('profiles') - .select('*') - .eq('id', user.id) - .single() + let profile: any = null + if (isSupabaseConfigured) { + const { data } = await supabase + .from('profiles') + .select('*') + .eq('id', user.id) + .single() + profile = data + } return { id: user.id, @@ -33,6 +37,9 @@ class AuthService { * Get current user session */ async getCurrentUser(): Promise { + if (!isSupabaseConfigured) { + return null + } try { const { data: { user }, error } = await supabase.auth.getUser() @@ -51,6 +58,9 @@ class AuthService { * Sign in with email and password */ async signIn(credentials: SignInCredentials): Promise { + if (!isSupabaseConfigured) { + throw new Error('Supabase not configured') + } try { const { data, error } = await supabase.auth.signInWithPassword({ email: credentials.email, @@ -76,6 +86,9 @@ class AuthService { * Sign up with email and password */ async signUp(credentials: SignUpCredentials): Promise { + if (!isSupabaseConfigured) { + throw new Error('Supabase not configured') + } try { const { data, error } = await supabase.auth.signUp({ email: credentials.email, @@ -106,6 +119,9 @@ class AuthService { * Sign out current user */ async signOut(): Promise { + if (!isSupabaseConfigured) { + throw new Error('Supabase not configured') + } try { const { error } = await supabase.auth.signOut() @@ -122,6 +138,9 @@ class AuthService { * Reset password */ async resetPassword(email: string): Promise { + if (!isSupabaseConfigured) { + throw new Error('Supabase not configured') + } try { const { error } = await supabase.auth.resetPasswordForEmail(email, { redirectTo: `${window.location.origin}/auth/reset-password` @@ -140,6 +159,9 @@ class AuthService { * Update user profile */ async updateProfile(userId: string, updates: Partial): Promise { + if (!isSupabaseConfigured) { + throw new Error('Supabase not configured') + } try { const { data, error } = await supabase .from('profiles') @@ -199,6 +221,9 @@ class AuthService { * Listen to auth state changes */ onAuthStateChange(callback: (user: AuthUser | null) => void) { + if (!isSupabaseConfigured) { + return { data: null } + } return supabase.auth.onAuthStateChange(async (event, session) => { if (session?.user) { const authUser = await this.transformUser(session.user) diff --git a/lib/services/blog.service.ts b/lib/services/blog.service.ts index d44abfc..ab9ff3a 100644 --- a/lib/services/blog.service.ts +++ b/lib/services/blog.service.ts @@ -1,4 +1,4 @@ -import { supabase } from '@/lib/supabase/client' +import { supabase, isSupabaseConfigured } from '@/lib/supabase/client' import { BlogPost, BlogCategory, @@ -81,6 +81,10 @@ export class BlogService { // Get posts with filtering and pagination async getPosts(params: BlogSearchParams = {}): Promise { + if (!isSupabaseConfigured) { + console.warn('Supabase not configured: returning empty posts') + return { posts: [], total: 0, hasMore: false } + } const { status = 'published', category, @@ -163,6 +167,10 @@ export class BlogService { // Get single post by slug async getPostBySlug(slug: string): Promise { + if (!isSupabaseConfigured) { + console.warn('Supabase not configured: cannot fetch post') + return null + } const { data, error } = await supabase .from('blog_posts') .select(` @@ -193,6 +201,10 @@ export class BlogService { // Get all categories async getCategories(): Promise { + if (!isSupabaseConfigured) { + console.warn('Supabase not configured: returning empty categories') + return [] + } const { data, error } = await supabase .from('blog_categories') .select('*') @@ -208,6 +220,10 @@ export class BlogService { // Search posts async searchPosts(query: string, limit = 10): Promise { + if (!isSupabaseConfigured) { + console.warn('Supabase not configured: returning empty search results') + return [] + } const { data, error } = await supabase .from('blog_posts') .select(` @@ -254,6 +270,9 @@ export class BlogService { } async incrementViewCount(slug: string): Promise { + if (!isSupabaseConfigured) { + return + } const { error } = await supabase.rpc('increment_view_count', { post_slug: slug }) if (error) { diff --git a/lib/supabase/client.ts b/lib/supabase/client.ts index 3531385..f32331d 100644 --- a/lib/supabase/client.ts +++ b/lib/supabase/client.ts @@ -2,10 +2,16 @@ import { createClient } from '@supabase/supabase-js' import { createBrowserClient } from '@supabase/ssr' import { Database } from '@/lib/types/supabase.types' -const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL! -const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! +const supabaseUrl = + process.env.NEXT_PUBLIC_SUPABASE_URL || 'https://example.supabase.co' +const supabaseAnonKey = + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || 'public-anon-key' -// Client-side Supabase client +export const isSupabaseConfigured = + !!process.env.NEXT_PUBLIC_SUPABASE_URL && + !!process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY + +// Client-side Supabase client (uses placeholder when not configured) export const supabase = createBrowserClient( supabaseUrl, supabaseAnonKey @@ -13,5 +19,8 @@ export const supabase = createBrowserClient( // Server-side Supabase client (for API routes, etc.) export const createServerClient = () => { - return createClient(supabaseUrl, supabaseAnonKey) -} \ No newline at end of file + if (!isSupabaseConfigured) { + throw new Error('Supabase environment variables are not configured') + } + return createClient(supabaseUrl!, supabaseAnonKey!) +}