.beta-actions{display:flex;gap:8px;margin-top:14px;align-items:center} .beta-btn{cursor:pointer;border:0;border-radius:8px;padding:10px 12px;font-weight:600} .beta-btn.primary{background:linear-gradient(135deg,#22c55e,#16a34a);color:#001b0a} .beta-btn.ghost{background:transparent;color:#93c5fd;border:1px solid #334155} .beta-err{color:#fecaca;font-size:12px;margin-top:8px;min-height:16px} .avatar-fab{position:fixed;right:16px;bottom:16px;background:#0ea5e9;color:#00111a;border-radius:999px;padding:10px 14px;font-weight:700;cursor:pointer;box-shadow:0 10px 20px rgba(0,0,0,.3);z-index:10000} `; document.head.appendChild(style); // Gate UI const wrap = document.createElement('div'); wrap.className = 'beta-gate'; wrap.innerHTML = `

Sign in to continue

Use your email and password. New here? Click Register.

`; document.body.appendChild(wrap); function setErr(msg){ const el=document.getElementById('beta-err'); if(el) el.textContent = msg||''; } function val(id){ const el=document.getElementById(id); const value = (el && el.value||'').trim(); console.log('val() called for', id, '- element found:', !!el, '- value:', value); // Debug log if (el) { console.log('Element details:', { id: el.id, type: el.type, value: el.value, classList: Array.from(el.classList) }); } return value; } async function ensureProfile(user){ const email = user.email; const computedRole = (email && window.ADMIN_EMAIL && email.toLowerCase()===String(window.ADMIN_EMAIL).toLowerCase()) ? 'admin' : 'user'; try { // If database isn't initialized yet, these calls can fail. We fall back gracefully. const { data: existing, error: selErr } = await sb .from('profiles') .select('id,email,role,avatar_url') .eq('id', user.id) .maybeSingle(); if (selErr) throw selErr; if (!existing) { const { error: insErr } = await sb.from('profiles').insert({ id: user.id, email, role: computedRole }); if (insErr) throw insErr; return computedRole; } else if (existing.role !== computedRole && computedRole === 'admin') { const { error: updErr } = await sb.from('profiles').update({ role: computedRole }).eq('id', user.id); if (updErr) throw updErr; return computedRole; } return existing.role || computedRole; } catch (e) { // Profiles table or RLS not set up yet – proceed using computed role only. console.warn('ensureProfile skipped (schema not ready):', e?.message || e); return computedRole; } } async function afterAuth(session){ const { user } = session; let role = 'user'; try { role = await ensureProfile(user); } catch {} try { sessionStorage.setItem(gateKey, JSON.stringify({ email: user.email, role, id: user.id })); } catch {} // Bridge to app's local user model try { const current = { id: user.id, email: user.email, role, username: user.email, firstName: user.user_metadata?.first_name||'', lastName: user.user_metadata?.last_name||'' }; localStorage.setItem('current-user', JSON.stringify(current)); } catch {} if (wrap && wrap.parentNode) wrap.parentNode.removeChild(wrap); showAvatarFab(); try { window.location.hash = '#/browse'; } catch {} } async function signIn(){ console.log('Sign in function called'); // Debug log setErr(''); const email = val('beta-email'); const password = val('beta-pass'); console.log('Sign in data:', { email, password: password ? '***' : 'empty' }); // Debug log if (!email || !password) { console.log('Missing email or password'); // Debug log setErr('Enter email and password'); return; } try { console.log('Starting sign-in process...'); // Debug log // Get existing users const existingUsers = JSON.parse(localStorage.getItem('users') || '[]'); console.log('Existing users count:', existingUsers.length); // Debug log // Find user by email and password const user = existingUsers.find(u => u.email === email && u.password === password); console.log('User found:', user ? 'yes' : 'no'); // Debug log if (!user) { console.log('Invalid credentials'); // Debug log setErr('Invalid email or password. Try registering if you don\'t have an account.'); return; } // Set as current user localStorage.setItem('current-user', JSON.stringify(user)); console.log('Current user set for sign-in'); // Debug log // Verify it was actually set const verifyUser = JSON.parse(localStorage.getItem('current-user') || 'null'); console.log('Verification - user immediately after setting:', verifyUser); // Debug log // Remove the login gate and redirect to browse if (wrap && wrap.parentNode) { wrap.parentNode.removeChild(wrap); console.log('Login gate removed for sign-in'); // Debug log } console.log('Sign-in successful, about to redirect...'); // Debug log // Add a small delay before redirecting to see if timing is the issue setTimeout(() => { const userBeforeRedirect = JSON.parse(localStorage.getItem('current-user') || 'null'); console.log('User just before redirect:', userBeforeRedirect); // Debug log window.location.hash = '#/browse'; }, 100); } catch (e) { console.error('Sign-in error:', e); // Debug log setErr('Sign-in failed: ' + (e?.message || 'Unknown error')); } } async function register(){ console.log('Register function called'); // Debug log // Debug: Check if elements exist and their values directly const emailEl = document.getElementById('beta-email'); const passEl = document.getElementById('beta-pass'); console.log('Direct element check:'); console.log('Email element:', emailEl ? {id: emailEl.id, value: emailEl.value, type: emailEl.type} : 'NOT FOUND'); console.log('Password element:', passEl ? {id: passEl.id, value: passEl.value, type: passEl.type} : 'NOT FOUND'); // Check all elements with these IDs const allEmailEls = document.querySelectorAll('#beta-email'); const allPassEls = document.querySelectorAll('#beta-pass'); console.log('All email elements found:', allEmailEls.length); console.log('All password elements found:', allPassEls.length); setErr(''); const email = val('beta-email'); const password = val('beta-pass'); console.log('Register data:', { email, password: password ? '***' : 'empty' }); // Debug log if (!email || !password) { console.log('Missing email or password'); // Debug log setErr('Enter email and password'); return; } try { console.log('Starting registration process...'); // Debug log // Get existing users const existingUsers = JSON.parse(localStorage.getItem('users') || '[]'); console.log('Existing users count:', existingUsers.length); // Debug log // Check if user already exists if (existingUsers.find(u => u.email === email)) { console.log('User already exists'); // Debug log setErr('Account with this email already exists. Please sign in instead.'); return; } // Create new user const newUser = { id: 'u-' + Date.now(), email: email, password: password, username: email.split('@')[0], fullName: email.split('@')[0], role: 'user', accountType: 'Individual', phone: '', homeAddress: '', city: '', state: '', zipCode: '', createdAt: new Date().toISOString() }; console.log('New user created:', { ...newUser, password: '***' }); // Debug log // Save to users array existingUsers.push(newUser); localStorage.setItem('users', JSON.stringify(existingUsers)); console.log('User saved to localStorage'); // Debug log // Set as current user localStorage.setItem('current-user', JSON.stringify(newUser)); console.log('Current user set'); // Debug log // Remove the login gate and redirect to browse if (wrap && wrap.parentNode) { wrap.parentNode.removeChild(wrap); console.log('Login gate removed'); // Debug log } console.log('Registration successful, redirecting...'); // Debug log window.location.hash = '#/browse'; } catch (e) { console.error('Registration error:', e); // Debug log setErr('Registration failed: ' + (e?.message || 'Unknown error')); } } wrap.addEventListener('click', (e)=>{ console.log('Button clicked:', e.target.id); // Debug log if (e.target && e.target.id==='beta-signin') { console.log('Sign in button clicked'); // Debug log signIn(); } if (e.target && e.target.id==='beta-register') { console.log('Register button clicked'); // Debug log register(); } }); wrap.addEventListener('keydown', (e)=>{ if (e.key==='Enter') signIn(); }); // Avatar upload button with signed URLs for private storage function showAvatarFab(){ if (document.getElementById('avatar-fab')) return; const btn = document.createElement('button'); btn.id = 'avatar-fab'; btn.className = 'avatar-fab'; btn.textContent = 'Upload Avatar'; const input = document.createElement('input'); input.type = 'file'; input.accept = 'image/*'; input.style.display = 'none'; btn.addEventListener('click', ()=> input.click()); input.addEventListener('change', async ()=>{ const file = input.files && input.files[0]; if (!file) return; try { const session = (await sb.auth.getSession()).data.session; if (!session) { alert('Please sign in again.'); return; } const uid = session.user.id; const ext = file.name.split('.').pop()||'jpg'; const path = `private/${uid}.${ext}`; const { error: upErr } = await sb.storage.from('avatars').upload(path, file, { upsert: true, contentType: file.type }); if (upErr) throw upErr; // Use signed URL for secure access (1 year expiry, refresh on load) const { data: signedData, error: signErr } = await sb.storage.from('avatars').createSignedUrl(path, 31536000); if (signErr) throw signErr; const signedUrl = signedData.signedUrl; await sb.from('profiles').update({ avatar_url: signedUrl }).eq('id', uid); try { const cur = JSON.parse(localStorage.getItem('current-user')||'{}'); cur.avatarUrl = signedUrl; localStorage.setItem('current-user', JSON.stringify(cur)); } catch {} alert('Avatar updated securely with signed URL'); } catch (err){ alert('Upload failed: '+ (err?.message||err)); } }); document.body.appendChild(btn); document.body.appendChild(input); } // If session already exists, skip gate and show FAB sb.auth.getSession().then(({ data })=>{ if (data.session) { const user = data.session.user; sessionStorage.setItem(gateKey, JSON.stringify({ email: user.email, id: user.id })); showAvatarFab(); if (wrap && wrap.parentNode) wrap.parentNode.removeChild(wrap); try { window.location.hash = '#/browse'; } catch {} } }); })();