// Initialize Supabase const supabase = createClient( 'https://iiwthrqlshgmzvgudpkt.supabase.co', 'sb_publishable_slaECC8UMtgUni2caodaZA_N-uidsoa' ); // DOM Elements const scriptsContainer = document.getElementById('scripts-container'); const contributorsContainer = document.getElementById('contributors-container'); const newestBtn = document.getElementById('newest-btn'); const popularBtn = document.getElementById('popular-btn'); const trendingBtn = document.getElementById('trending-btn'); const loadMoreBtn = document.getElementById('load-more'); // State let currentSort = 'newest'; let currentPage = 1; let isLoading = false; // Format date function formatDate(dateString) { const date = new Date(dateString); return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); } // Render scripts async function renderScripts(sortBy = 'newest', page = 1) { try { isLoading = true; scriptsContainer.innerHTML = `

Loading scripts...

`; const scripts = await fetchScripts(sortBy, page); if (scripts.error) throw scripts.error; if (scripts.length === 0) { scriptsContainer.innerHTML = `

No scripts found

Be the first to upload a script!

`; feather.replace(); return; } let html = ''; scripts.forEach(script => { html += `
${script.username || 'Anonymous'}

${script.title}

${script.description || 'No description provided'}

${script.view_count || 0} ${script.like_count || 0} ${formatDate(script.created_at)}
`; }); scriptsContainer.innerHTML = html; feather.replace(); loadMoreBtn.classList.toggle('hidden', scripts.length < 10); } catch (error) { console.error('Render error:', error); scriptsContainer.innerHTML = `

Error loading scripts

${error.message}

`; feather.replace(); } finally { isLoading = false; } } // Render contributors async function renderContributors() { try { contributorsContainer.innerHTML = `

Loading contributors...

`; const { data: contributors, error } = await supabase .from('profiles') .select('username, avatar_url, script_count') .order('script_count', { ascending: false }) .limit(6); if (error) throw error; let html = ''; contributors.forEach(contributor => { html += `
${contributor.avatar_url ? `${contributor.username}` : ``}

${contributor.username}

${contributor.script_count || 0} scripts

`; }); contributorsContainer.innerHTML = html; feather.replace(); } catch (error) { console.error('Contributors error:', error); contributorsContainer.innerHTML = `

Error loading contributors

`; feather.replace(); } } // Event Listeners newestBtn.addEventListener('click', () => { if (currentSort === 'newest' || isLoading) return; currentSort = 'newest'; currentPage = 1; newestBtn.classList.replace('bg-gray-700', 'bg-indigo-600'); popularBtn.classList.replace('bg-indigo-600', 'bg-gray-700'); trendingBtn.classList.replace('bg-indigo-600', 'bg-gray-700'); renderScripts('newest', 1); }); popularBtn.addEventListener('click', () => { if (currentSort === 'most_liked' || isLoading) return; currentSort = 'most_liked'; currentPage = 1; newestBtn.classList.replace('bg-indigo-600', 'bg-gray-700'); popularBtn.classList.replace('bg-gray-700', 'bg-indigo-600'); trendingBtn.classList.replace('bg-indigo-600', 'bg-gray-700'); renderScripts('most_liked', 1); }); trendingBtn.addEventListener('click', () => { if (currentSort === 'trending' || isLoading) return; currentSort = 'trending'; currentPage = 1; newestBtn.classList.replace('bg-indigo-600', 'bg-gray-700'); popularBtn.classList.replace('bg-indigo-600', 'bg-gray-700'); trendingBtn.classList.replace('bg-gray-700', 'bg-indigo-600'); renderScripts('trending', 1); }); loadMoreBtn.addEventListener('click', () => { if (isLoading) return; currentPage++; renderScripts(currentSort, currentPage); }); // Initialize document.addEventListener('DOMContentLoaded', () => { renderScripts(); renderContributors(); feather.replace(); // Auth state listener supabase.auth.onAuthStateChange((event, session) => { if (event === 'SIGNED_IN') { console.log('User signed in:', session.user); // Update UI for logged in state } else if (event === 'SIGNED_OUT') { console.log('User signed out'); // Update UI for logged out state } }); }); // Auth functions async function handleSignUp(email, password) { try { const { data, error } = await supabase.auth.signUp({ email, password, }); if (error) throw error; return data; } catch (error) { console.error('Sign up error:', error.message); return { error }; } } async function handleSignIn(email, password) { try { const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) throw error; return data; } catch (error) { console.error('Sign in error:', error.message); return { error }; } } async function handleSignOut() { try { const { error } = await supabase.auth.signOut(); if (error) throw error; return { success: true }; } catch (error) { console.error('Sign out error:', error.message); return { error }; } } // Script functions async function fetchScripts(sortBy = 'newest', page = 1, searchQuery = '') { try { let query = supabase .from('scripts') .select('*') .eq('visibility', 'public') .order('created_at', { ascending: sortBy === 'newest' ? false : true }); if (searchQuery) { query = query.or(`title.ilike.%${searchQuery}%,description.ilike.%${searchQuery}%`); } if (sortBy === 'most_liked') { query = query.order('like_count', { ascending: false }); } else if (sortBy === 'trending') { // Trending could be a combination of views and likes over time query = query.order('view_count', { ascending: false }); } const { data, error } = await query.range((page - 1) * 10, page * 10 - 1); if (error) throw error; return data; } catch (error) { console.error('Fetch scripts error:', error.message); return { error }; } } async function fetchScriptById(id) { try { // Increment view count await supabase.rpc('increment_script_views', { script_id: id }); const { data, error } = await supabase .from('scripts') .select('*, script_versions(*), profiles(username, avatar_url)') .eq('id', id) .single(); if (error) throw error; return data; } catch (error) { console.error('Fetch script error:', error.message); return { error }; } } // Comment functions async function fetchComments(scriptId) { try { const { data, error } = await supabase .from('comments_safe') .select('*') .eq('script_id', scriptId) .order('created_at', { ascending: true }); if (error) throw error; return data; } catch (error) { console.error('Fetch comments error:', error.message); return { error }; } } async function postComment(scriptId, content, parentId = null) { try { const { data: { user } } = await supabase.auth.getUser(); if (!user) throw new Error('Not authenticated'); const { data, error } = await supabase .from('comments') .insert({ script_id: scriptId, user_id: user.id, content, parent_id: parentId }) .select() .single(); if (error) throw error; return data; } catch (error) { console.error('Post comment error:', error.message); return { error }; } } // Like functions async function toggleLike(scriptId) { try { const { data: { user } } = await supabase.auth.getUser(); if (!user) throw new Error('Not authenticated'); // Check if already liked const { data: existingLike, error: likeError } = await supabase .from('likes') .select('id') .eq('script_id', scriptId) .eq('user_id', user.id) .maybeSingle(); if (likeError) throw likeError; if (existingLike) { // Unlike const { error } = await supabase .from('likes') .delete() .eq('id', existingLike.id); if (error) throw error; return { action: 'unliked' }; } else { // Like const { error } = await supabase .from('likes') .insert({ script_id: scriptId, user_id: user.id }); if (error) throw error; return { action: 'liked' }; } } catch (error) { console.error('Toggle like error:', error.message); return { error }; } } // Report functions async function submitReport(scriptId, reason) { try { const { data: { user } } = await supabase.auth.getUser(); if (!user) throw new Error('Not authenticated'); const { data, error } = await supabase .from('reports') .insert({ script_id: scriptId, reporter_id: user.id, reason }) .select() .single(); if (error) throw error; return data; } catch (error) { console.error('Submit report error:', error.message); return { error }; } } // Initialize event listeners when DOM is loaded document.addEventListener('DOMContentLoaded', () => { // Check auth state supabase.auth.onAuthStateChange((event, session) => { if (event === 'SIGNED_IN') { console.log('User signed in:', session.user); // Update UI to show logged in state } else if (event === 'SIGNED_OUT') { console.log('User signed out'); // Update UI to show logged out state } }); });