supabase init
Установка и настройка supabase
This commit is contained in:
parent
ee364b60e6
commit
e06bd3c1e6
@ -11,27 +11,39 @@ export const supabase = createClient(supabaseUrl, supabaseAnonKey);
|
||||
|
||||
// Auth functions
|
||||
export const signUp = async (email, password, username) => {
|
||||
const { data, error } = await supabase.auth.signUp({
|
||||
email,
|
||||
password,
|
||||
options: {
|
||||
data: { username }
|
||||
}
|
||||
});
|
||||
if (error) throw error;
|
||||
|
||||
// Создаем профиль в таблице users
|
||||
const { error: profileError } = await supabase
|
||||
.from('users')
|
||||
.upsert({
|
||||
id: data.user.id,
|
||||
try {
|
||||
// Регистрируем пользователя
|
||||
const { data, error } = await supabase.auth.signUp({
|
||||
email,
|
||||
username,
|
||||
role: 'user'
|
||||
password,
|
||||
options: {
|
||||
data: { username }
|
||||
}
|
||||
});
|
||||
|
||||
if (profileError) throw profileError;
|
||||
return data;
|
||||
if (error) throw error;
|
||||
|
||||
// Создаем профиль в таблице users
|
||||
const { error: profileError } = await supabase
|
||||
.from('users')
|
||||
.insert({
|
||||
id: data.user.id,
|
||||
email,
|
||||
username,
|
||||
role: 'user',
|
||||
created_at: new Date().toISOString()
|
||||
});
|
||||
|
||||
if (profileError) {
|
||||
// Если не удалось создать профиль, удаляем пользователя
|
||||
await supabase.auth.admin.deleteUser(data.user.id);
|
||||
throw profileError;
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const signIn = async (email, password) => {
|
||||
@ -57,7 +69,7 @@ export const getUserProfile = async (userId) => {
|
||||
.from('users')
|
||||
.select('*')
|
||||
.eq('id', userId)
|
||||
.single();
|
||||
.maybeSingle();
|
||||
|
||||
if (error) throw error;
|
||||
return data;
|
||||
@ -65,14 +77,33 @@ export const getUserProfile = async (userId) => {
|
||||
|
||||
// Media functions
|
||||
export const createMedia = async (mediaData) => {
|
||||
const { data, error } = await supabase
|
||||
.from('media')
|
||||
.insert(mediaData)
|
||||
.select()
|
||||
.single();
|
||||
try {
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
if (!user) {
|
||||
throw new Error('Пользователь не авторизован');
|
||||
}
|
||||
|
||||
if (error) throw error;
|
||||
return data;
|
||||
const { data, error } = await supabase
|
||||
.from('media')
|
||||
.insert({
|
||||
...mediaData,
|
||||
created_by: user.id,
|
||||
created_at: new Date().toISOString(),
|
||||
is_published: false
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
console.error('Error creating media:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Failed to create media:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getMediaById = async (id) => {
|
||||
@ -93,22 +124,35 @@ export const getMediaById = async (id) => {
|
||||
return data;
|
||||
};
|
||||
|
||||
export const listMedia = async (type = null, page = 1, limit = 10) => {
|
||||
let query = supabase
|
||||
.from('media')
|
||||
.select('*')
|
||||
.eq('is_published', true)
|
||||
.order('created_at', { ascending: false });
|
||||
export const listMedia = async (type = null, page = 1, limit = 20) => {
|
||||
try {
|
||||
let query = supabase
|
||||
.from('media')
|
||||
.select('*', { count: 'exact' })
|
||||
.order('created_at', { ascending: false });
|
||||
|
||||
if (type) query = query.eq('type', type);
|
||||
if (type) {
|
||||
query = query.eq('type', type);
|
||||
}
|
||||
|
||||
const { data, error } = await query.range(
|
||||
(page - 1) * limit,
|
||||
page * limit - 1
|
||||
);
|
||||
const { data, error, count } = await query
|
||||
.range((page - 1) * limit, page * limit - 1);
|
||||
|
||||
if (error) throw error;
|
||||
return data;
|
||||
if (error) throw error;
|
||||
|
||||
return {
|
||||
data,
|
||||
count,
|
||||
error: null
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error in listMedia:', error);
|
||||
return {
|
||||
data: [],
|
||||
count: 0,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Review functions
|
||||
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
# Initial schema setup for CampFire Critics
|
||||
|
||||
1. New Tables
|
||||
- `users`
|
||||
- `id` (uuid, primary key)
|
||||
- `email` (text, unique)
|
||||
- `username` (text, unique)
|
||||
- `role` (text)
|
||||
- `created_at` (timestamp)
|
||||
- `profile_picture` (text)
|
||||
- `bio` (text)
|
||||
- `is_critic` (boolean)
|
||||
|
||||
- `media`
|
||||
- `id` (uuid, primary key)
|
||||
- `title` (text)
|
||||
- `type` (text)
|
||||
- `poster_url` (text)
|
||||
- `backdrop_url` (text)
|
||||
- `overview` (text)
|
||||
- `release_date` (date)
|
||||
- `created_at` (timestamp)
|
||||
- `created_by` (uuid, references users)
|
||||
- `is_published` (boolean)
|
||||
|
||||
- `reviews`
|
||||
- `id` (uuid, primary key)
|
||||
- `user_id` (uuid, references users)
|
||||
- `media_id` (uuid, references media)
|
||||
- `content` (text)
|
||||
- `ratings` (jsonb)
|
||||
- `created_at` (timestamp)
|
||||
- `has_spoilers` (boolean)
|
||||
|
||||
2. Security
|
||||
- Enable RLS on all tables
|
||||
- Add policies for authenticated users
|
||||
- Add special policies for admin/moderator roles
|
||||
*/
|
||||
|
||||
-- Create users table
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email text UNIQUE NOT NULL,
|
||||
username text UNIQUE NOT NULL,
|
||||
role text NOT NULL DEFAULT 'user',
|
||||
created_at timestamptz DEFAULT now(),
|
||||
profile_picture text,
|
||||
bio text,
|
||||
is_critic boolean DEFAULT false
|
||||
);
|
||||
|
||||
-- Create media table
|
||||
CREATE TABLE IF NOT EXISTS media (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
title text NOT NULL,
|
||||
type text NOT NULL,
|
||||
poster_url text,
|
||||
backdrop_url text,
|
||||
overview text,
|
||||
release_date date,
|
||||
created_at timestamptz DEFAULT now(),
|
||||
created_by uuid REFERENCES users(id),
|
||||
is_published boolean DEFAULT false
|
||||
);
|
||||
|
||||
-- Create reviews table
|
||||
CREATE TABLE IF NOT EXISTS reviews (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid REFERENCES users(id),
|
||||
media_id uuid REFERENCES media(id),
|
||||
content text NOT NULL,
|
||||
ratings jsonb NOT NULL,
|
||||
created_at timestamptz DEFAULT now(),
|
||||
has_spoilers boolean DEFAULT false
|
||||
);
|
||||
|
||||
-- Enable RLS
|
||||
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE media ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE reviews ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Users policies
|
||||
CREATE POLICY "Users can read all users"
|
||||
ON users FOR SELECT
|
||||
TO authenticated
|
||||
USING (true);
|
||||
|
||||
CREATE POLICY "Users can update own profile"
|
||||
ON users FOR UPDATE
|
||||
TO authenticated
|
||||
USING (auth.uid() = id);
|
||||
|
||||
-- Media policies
|
||||
CREATE POLICY "Anyone can read published media"
|
||||
ON media FOR SELECT
|
||||
TO authenticated
|
||||
USING (is_published = true);
|
||||
|
||||
CREATE POLICY "Admins and moderators can manage all media"
|
||||
ON media FOR ALL
|
||||
TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM users
|
||||
WHERE id = auth.uid()
|
||||
AND role IN ('admin', 'moderator')
|
||||
)
|
||||
);
|
||||
|
||||
-- Reviews policies
|
||||
CREATE POLICY "Anyone can read reviews"
|
||||
ON reviews FOR SELECT
|
||||
TO authenticated
|
||||
USING (true);
|
||||
|
||||
CREATE POLICY "Users can create reviews"
|
||||
ON reviews FOR INSERT
|
||||
TO authenticated
|
||||
WITH CHECK (auth.uid() = user_id);
|
||||
|
||||
CREATE POLICY "Users can update own reviews"
|
||||
ON reviews FOR UPDATE
|
||||
TO authenticated
|
||||
USING (auth.uid() = user_id);
|
||||
|
||||
CREATE POLICY "Users can delete own reviews"
|
||||
ON reviews FOR DELETE
|
||||
TO authenticated
|
||||
USING (auth.uid() = user_id);
|
Loading…
Reference in New Issue
Block a user