diff --git a/src/contexts/AuthContext.jsx b/src/contexts/AuthContext.jsx
index b15b766..9c5353f 100644
--- a/src/contexts/AuthContext.jsx
+++ b/src/contexts/AuthContext.jsx
@@ -31,36 +31,33 @@ export const AuthProvider = ({ children }) => {
// Функция для загрузки профиля пользователя
const loadUserProfile = async (userId) => {
+ if (!userId) {
+ console.log('AuthProvider: Нет userId для загрузки профиля');
+ setLoading(false);
+ return;
+ }
+
try {
console.log('AuthProvider: Загрузка профиля пользователя:', userId);
- const { data: profile, error: profileError } = await supabase
- .from('users')
- .select('*')
- .eq('id', userId)
- .single();
+ const profile = await getUserProfile(userId);
+
+ if (!profile) {
+ console.log('AuthProvider: Профиль не найден, создаем новый');
+ const { data: newProfile, error: createError } = await supabase
+ .from('users')
+ .insert([
+ {
+ id: userId,
+ username: `user_${userId.slice(0, 8)}`,
+ role: 'user'
+ }
+ ])
+ .select()
+ .single();
- if (profileError) {
- if (profileError.code === 'PGRST116') {
- // Если профиль не найден, создаем новый
- console.log('AuthProvider: Профиль не найден, создаем новый');
- const { data: newProfile, error: createError } = await supabase
- .from('users')
- .insert([
- {
- id: userId,
- username: `user_${userId.slice(0, 8)}`,
- role: 'user'
- }
- ])
- .select()
- .single();
-
- if (createError) throw createError;
- console.log('AuthProvider: Новый профиль создан:', newProfile);
- setUserProfile(newProfile);
- } else {
- throw profileError;
- }
+ if (createError) throw createError;
+ console.log('AuthProvider: Новый профиль создан:', newProfile);
+ setUserProfile(newProfile);
} else {
console.log('AuthProvider: Профиль загружен:', profile);
setUserProfile(profile);
@@ -68,6 +65,10 @@ export const AuthProvider = ({ children }) => {
} catch (error) {
console.error('AuthProvider: Ошибка загрузки профиля:', error);
setError(error.message);
+ setCurrentUser(null);
+ setUserProfile(null);
+ } finally {
+ setLoading(false);
}
};
@@ -78,7 +79,14 @@ export const AuthProvider = ({ children }) => {
const { data: { session }, error: sessionError } = await supabase.auth.getSession();
console.log('AuthProvider: Результат проверки сессии:', { session, error: sessionError });
- if (sessionError) throw sessionError;
+ if (sessionError) {
+ console.error('AuthProvider: Ошибка получения сессии:', sessionError);
+ await supabase.auth.signOut();
+ setCurrentUser(null);
+ setUserProfile(null);
+ setLoading(false);
+ return;
+ }
if (session?.user) {
console.log('AuthProvider: Пользователь найден в сессии');
@@ -88,41 +96,59 @@ export const AuthProvider = ({ children }) => {
console.log('AuthProvider: Пользователь не найден в сессии');
setCurrentUser(null);
setUserProfile(null);
+ setLoading(false);
}
} catch (error) {
console.error('AuthProvider: Ошибка проверки сессии:', error);
setError(error.message);
+ await supabase.auth.signOut();
setCurrentUser(null);
setUserProfile(null);
- } finally {
- console.log('AuthProvider: Завершение проверки сессии');
setLoading(false);
}
};
useEffect(() => {
+ let mounted = true;
console.log('AuthProvider: Инициализация...');
- checkSession();
+
+ const initialize = async () => {
+ try {
+ await checkSession();
+ } catch (error) {
+ console.error('AuthProvider: Ошибка инициализации:', error);
+ setError(error.message);
+ setLoading(false);
+ }
+ };
+
+ initialize();
const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, session) => {
+ if (!mounted) return;
+
console.log('AuthProvider: Изменение состояния авторизации:', { event, session });
- setLoading(true);
+
+ if (event === 'INITIAL_SESSION') {
+ setLoading(false);
+ return;
+ }
if (event === 'SIGNED_IN') {
console.log('AuthProvider: Пользователь вошел в систему');
setCurrentUser(session.user);
await loadUserProfile(session.user.id);
- } else if (event === 'SIGNED_OUT') {
+ } else if (event === 'SIGNED_OUT' || event === 'USER_DELETED') {
console.log('AuthProvider: Пользователь вышел из системы');
setCurrentUser(null);
setUserProfile(null);
+ setLoading(false);
}
-
- setLoading(false);
});
return () => {
console.log('AuthProvider: Отписка от изменений состояния авторизации');
+ mounted = false;
subscription.unsubscribe();
};
}, []);
@@ -189,7 +215,7 @@ export const AuthProvider = ({ children }) => {
console.log('AuthProvider: Текущее состояние:', value);
- if (loading || (currentUser && !userProfile)) {
+ if (loading && !currentUser) {
console.log('AuthProvider: Отображение состояния загрузки');
return (
diff --git a/src/services/supabase.js b/src/services/supabase.js
index 2400a40..8a237e4 100644
--- a/src/services/supabase.js
+++ b/src/services/supabase.js
@@ -80,64 +80,90 @@ export const getCurrentUser = async () => {
};
// User functions
-export const getUserProfile = async (username) => {
- const { data, error } = await supabase
- .from('users')
- .select('*')
- .eq('username', username)
- .single();
-
- if (error) throw error;
- return data;
+export const getUserProfile = async (userId) => {
+ try {
+ const { data, error } = await supabase
+ .from('users')
+ .select('*')
+ .eq('id', userId)
+ .single();
+
+ if (error) {
+ if (error.code === 'PGRST116') {
+ // Если профиль не найден, создаем новый
+ const { data: newProfile, error: createError } = await supabase
+ .from('users')
+ .insert([
+ {
+ id: userId,
+ username: `user_${userId.slice(0, 8)}`,
+ role: 'user'
+ }
+ ])
+ .select()
+ .single();
+
+ if (createError) throw createError;
+ return newProfile;
+ }
+ throw error;
+ }
+
+ return data;
+ } catch (error) {
+ console.error('Error getting user profile:', error);
+ throw error;
+ }
+};
+
+export const updateUserProfile = async (userId, profileData) => {
+ try {
+ const { data, error } = await supabase
+ .from('users')
+ .update(profileData)
+ .eq('id', userId)
+ .select()
+ .single();
+
+ if (error) throw error;
+ return data;
+ } catch (error) {
+ console.error('Error updating user profile:', error);
+ throw error;
+ }
};
// Media functions
export const createMedia = async (mediaData) => {
try {
- const { data: { user } } = await supabase.auth.getUser();
- if (!user) {
- throw new Error('Пользователь не авторизован');
- }
-
const { data, error } = await supabase
.from('media')
- .insert({
- ...mediaData,
- created_by: user.id,
- created_at: new Date().toISOString(),
- is_published: false
- })
+ .insert([mediaData])
.select()
.single();
-
- if (error) {
- console.error('Error creating media:', error);
- throw error;
- }
-
+
+ if (error) throw error;
return data;
} catch (error) {
- console.error('Failed to create media:', error);
+ console.error('Error creating media:', error);
throw error;
}
};
export const getMediaById = async (id) => {
- const { data, error } = await supabase
- .from('media')
- .select(`
- *,
- created_by:users(username),
- reviews(
- *,
- user:users(username, profile_picture, is_critic)
- )
- `)
- .eq('id', id)
- .single();
-
- if (error) throw error;
- return data;
+ try {
+ const { data, error } = await supabase
+ .from('media')
+ .select('*')
+ .eq('id', id)
+ .single();
+
+ if (error) throw error;
+ return data;
+ } catch (error) {
+ console.error('Error getting media:', error);
+ throw error;
+ }
};
export const listMedia = async (type = null, page = 1, limit = 20) => {
@@ -159,40 +185,81 @@ export const listMedia = async (type = null, page = 1, limit = 20) => {
return {
data,
count,
- error: null
+ totalPages: Math.ceil(count / limit)
};
} catch (error) {
- console.error('Error in listMedia:', error);
- return {
- data: [],
- count: 0,
- error: error.message
- };
+ console.error('Error listing media:', error);
+ throw error;
+ }
+};
+
+export const updateMedia = async (id, mediaData) => {
+ try {
+ const { data, error } = await supabase
+ .from('media')
+ .update(mediaData)
+ .eq('id', id)
+ .select()
+ .single();
+
+ if (error) throw error;
+ return data;
+ } catch (error) {
+ console.error('Error updating media:', error);
+ throw error;
+ }
+};
+
+export const deleteMedia = async (id) => {
+ try {
+ const { error } = await supabase
+ .from('media')
+ .delete()
+ .eq('id', id);
+
+ if (error) throw error;
+ } catch (error) {
+ console.error('Error deleting media:', error);
+ throw error;
}
};
// Review functions
export const createReview = async (reviewData) => {
- const { data, error } = await supabase
- .from('reviews')
- .insert(reviewData)
- .select()
- .single();
-
- if (error) throw error;
- return data;
+ try {
+ const { data, error } = await supabase
+ .from('reviews')
+ .insert([reviewData])
+ .select()
+ .single();
+
+ if (error) throw error;
+ return data;
+ } catch (error) {
+ console.error('Error creating review:', error);
+ throw error;
+ }
};
-export const getUserReviews = async (userId) => {
- const { data, error } = await supabase
- .from('reviews')
- .select(`
- *,
- media(title, type, poster_url)
- `)
- .eq('user_id', userId)
- .order('created_at', { ascending: false });
-
- if (error) throw error;
- return data;
+export const getReviewsByMediaId = async (mediaId) => {
+ try {
+ const { data, error } = await supabase
+ .from('reviews')
+ .select(`
+ *,
+ users (
+ id,
+ username,
+ profile_picture
+ )
+ `)
+ .eq('media_id', mediaId)
+ .order('created_at', { ascending: false });
+
+ if (error) throw error;
+ return data;
+ } catch (error) {
+ console.error('Error getting reviews:', error);
+ throw error;
+ }
};
\ No newline at end of file