diff --git a/src/pages/ProfileSettings.tsx b/src/pages/ProfileSettings.tsx index ed39ca04..eb6150bd 100644 --- a/src/pages/ProfileSettings.tsx +++ b/src/pages/ProfileSettings.tsx @@ -80,8 +80,9 @@ export default function ProfileSettings() { const updateProfile = async () => { setLoading(true); try { - const updateData = { - username: profile.username, + const profileData = { + id: user?.id, + username: profile.username || '', full_name: profile.full_name, bio: profile.bio, phone_number: profile.phone_number, @@ -92,17 +93,20 @@ export default function ProfileSettings() { updated_at: new Date().toISOString() }; - console.log('💾 SAVING PROFILE DATA:', updateData); + console.log('💾 UPSERTING PROFILE DATA:', profileData); console.log('👤 User ID:', user?.id); + // Use upsert to create row if it doesn't exist, or update if it does const { data, error } = await supabase .from('profiles') - .update(updateData) - .eq('id', user?.id) + .upsert(profileData, { + onConflict: 'id', + ignoreDuplicates: false + }) .select(); - console.log('✅ Save response data:', data); - console.log('❌ Save error:', error); + console.log('✅ Upsert response data:', data); + console.log('❌ Upsert error:', error); if (error) throw error; @@ -110,6 +114,9 @@ export default function ProfileSettings() { title: 'Success', description: 'Profile updated successfully', }); + + // Reload profile to ensure state is in sync + await loadProfile(); } catch (error) { console.error('❌ Profile update failed:', error); toast({ diff --git a/supabase/migrations/003_fix_profile_creation.sql b/supabase/migrations/003_fix_profile_creation.sql new file mode 100644 index 00000000..2ad9cf37 --- /dev/null +++ b/supabase/migrations/003_fix_profile_creation.sql @@ -0,0 +1,82 @@ +-- ======================================== +-- Fix Profile Creation Issue +-- ======================================== +-- Adds INSERT policy and function to handle profile creation + +-- Add INSERT policy for profiles +DROP POLICY IF EXISTS "Users can insert their own profile" ON public.profiles; + +CREATE POLICY "Users can insert their own profile" + ON public.profiles FOR INSERT + WITH CHECK (auth.uid() = id); + +-- Make username nullable and add default +ALTER TABLE public.profiles + ALTER COLUMN username DROP NOT NULL; + +ALTER TABLE public.profiles + ALTER COLUMN username SET DEFAULT ''; + +-- Create function to handle profile upsert +CREATE OR REPLACE FUNCTION public.upsert_profile( + p_user_id UUID, + p_username TEXT DEFAULT '', + p_full_name TEXT DEFAULT '', + p_bio TEXT DEFAULT '', + p_phone_number TEXT DEFAULT '', + p_location TEXT DEFAULT '', + p_website TEXT DEFAULT '', + p_language TEXT DEFAULT 'en', + p_theme TEXT DEFAULT 'dark' +) +RETURNS SETOF public.profiles AS $$ +BEGIN + RETURN QUERY + INSERT INTO public.profiles ( + id, + username, + full_name, + bio, + phone_number, + location, + website, + language, + theme, + updated_at + ) + VALUES ( + p_user_id, + p_username, + p_full_name, + p_bio, + p_phone_number, + p_location, + p_website, + p_language, + p_theme, + NOW() + ) + ON CONFLICT (id) + DO UPDATE SET + username = COALESCE(NULLIF(EXCLUDED.username, ''), public.profiles.username), + full_name = EXCLUDED.full_name, + bio = EXCLUDED.bio, + phone_number = EXCLUDED.phone_number, + location = EXCLUDED.location, + website = EXCLUDED.website, + language = EXCLUDED.language, + theme = EXCLUDED.theme, + updated_at = NOW() + RETURNING *; +END; +$$ LANGUAGE plpgsql SECURITY DEFINER; + +-- Grant execute permission to authenticated users +GRANT EXECUTE ON FUNCTION public.upsert_profile TO authenticated; + +-- Success message +DO $$ +BEGIN + RAISE NOTICE 'Profile creation fix applied successfully!'; + RAISE NOTICE 'Users can now create and update their profiles.'; +END $$;