sourabhrealtime
Version:
ROBUST RICH TEXT EDITOR: Single-pane contentEditable with direct text selection formatting, speech features, undo/redo, professional UI - Perfect TipTap alternative
245 lines (219 loc) • 7.58 kB
JavaScript
// Production Supabase Integration
const SUPABASE_URL = "https://supabase.merai.app";
const SERVICE_ROLE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q";
const supabaseAPI = {
async createTablesIfNotExist() {
try {
// Create projects table
await fetch(`${SUPABASE_URL}/rest/v1/rpc/create_projects_table`, {
method: 'POST',
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json'
}
});
// Create approval_requests table
await fetch(`${SUPABASE_URL}/rest/v1/rpc/create_approval_requests_table`, {
method: 'POST',
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json'
}
});
} catch (error) {
console.log('Tables may already exist');
}
},
async authenticateUser(email, password) {
try {
// Ensure tables exist
await this.createTablesIfNotExist();
const response = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=password`, {
method: 'POST',
headers: {
'apikey': SERVICE_ROLE_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});
if (response.ok) {
const data = await response.json();
return {
success: true,
user: {
id: data.user.id,
email: data.user.email,
name: data.user.user_metadata?.name || data.user.email.split('@')[0],
role: data.user.user_metadata?.role || 'user'
},
token: data.access_token
};
}
return { success: false, message: 'Invalid credentials' };
} catch (error) {
return { success: false, message: 'Authentication failed' };
}
},
async getProjects(userId, userRole) {
try {
// Ensure tables exist first
await this.createTablesIfNotExist();
let url = `${SUPABASE_URL}/rest/v1/projects?select=*`;
if (userRole !== 'super_admin') {
url += `&or=(created_by.eq.${userId},members.cs.{${userId}})`;
}
const response = await fetch(url, {
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
const projects = await response.json();
return { success: true, projects };
} else {
// If table doesn't exist, return empty array
return { success: true, projects: [] };
}
} catch (error) {
return { success: true, projects: [] };
}
},
async createProject(projectData, creatorId) {
try {
// Ensure tables exist first
await this.createTablesIfNotExist();
const projectPayload = {
name: projectData.name,
description: projectData.description || '',
content: '<p>Start typing...</p>',
created_by: creatorId,
members: `{${creatorId}}`,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
};
const response = await fetch(`${SUPABASE_URL}/rest/v1/projects`, {
method: 'POST',
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json',
'Prefer': 'return=representation'
},
body: JSON.stringify(projectPayload)
});
if (response.ok) {
const projects = await response.json();
const project = Array.isArray(projects) ? projects[0] : projects;
return { success: true, project };
} else {
const error = await response.text();
throw new Error(`HTTP ${response.status}: ${error}`);
}
} catch (error) {
return { success: false, message: error.message };
}
},
async updateProjectContent(projectId, content, userId) {
try {
const response = await fetch(`${SUPABASE_URL}/rest/v1/projects?id=eq.${projectId}`, {
method: 'PATCH',
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
content,
updated_at: new Date().toISOString(),
updated_by: userId
})
});
return { success: response.ok };
} catch (error) {
return { success: false };
}
},
async getApprovalRequests() {
try {
// Ensure tables exist first
await this.createTablesIfNotExist();
const response = await fetch(`${SUPABASE_URL}/rest/v1/approval_requests?status=eq.pending&select=*`, {
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
const requests = await response.json();
return { success: true, requests };
} else {
// If table doesn't exist, return empty array
return { success: true, requests: [] };
}
} catch (error) {
return { success: true, requests: [] };
}
},
async createApprovalRequest(requestData) {
try {
// Ensure tables exist first
await this.createTablesIfNotExist();
const requestPayload = {
project_id: requestData.projectId,
project_name: requestData.projectName,
content: requestData.content,
user_id: requestData.user.id,
user_name: requestData.user.name,
user_email: requestData.user.email,
status: 'pending',
created_at: new Date().toISOString()
};
const response = await fetch(`${SUPABASE_URL}/rest/v1/approval_requests`, {
method: 'POST',
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json',
'Prefer': 'return=representation'
},
body: JSON.stringify(requestPayload)
});
if (response.ok) {
const requests = await response.json();
const request = Array.isArray(requests) ? requests[0] : requests;
return { success: true, request };
} else {
const error = await response.text();
throw new Error(`HTTP ${response.status}: ${error}`);
}
} catch (error) {
return { success: false, message: error.message };
}
},
async updateApprovalRequest(requestId, status, adminId) {
try {
const response = await fetch(`${SUPABASE_URL}/rest/v1/approval_requests?id=eq.${requestId}`, {
method: 'PATCH',
headers: {
'apikey': SERVICE_ROLE_KEY,
'Authorization': `Bearer ${SERVICE_ROLE_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
status,
reviewed_by: adminId,
reviewed_at: new Date().toISOString()
})
});
return { success: response.ok };
} catch (error) {
return { success: false };
}
}
};
export default supabaseAPI;