User account page with firebase
The account page, dubbed Hearth, is the prime residency of the logged in user. It has buttons to view your wish list (desires) and liked images (collections). There is a button to edit your squarespace account and a button to edit your profile (the dossier). There is a button to enter peers chat, and a button to chat with the warden AI, which is my customer service chat bot with a strong personality. There is finally, also a button to log. This page will be extended as I make polivantage a more anchored experience. For now the bulk of user customization takes place in the dossier.
HTML:
JAVASCRIPT: <script type="module"> // Initialize Firebase import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.12.5/firebase-app.js'; import { getAuth, signOut, onAuthStateChanged, updatePassword, reauthenticateWithCredential, EmailAuthProvider } from 'https://www.gstatic.com/firebasejs/10.12.5/firebase-auth.js'; import { getFirestore, collection, setDoc, writeBatch, deleteDoc, getDocs, query, serverTimestamp, where, doc, getDoc } from 'https://www.gstatic.com/firebasejs/10.12.5/firebase-firestore.js'; const app = initializeApp(firebaseConfig); const auth = getAuth(app); const db = getFirestore(app); //main stuff document.addEventListener('DOMContentLoaded', function() { const subString = 'useraccount'; const getURL = window.location.href; const baseURL = "https://www.polivantage.com/"; //show and hide popover let hideTimeout; var popover = document.getElementById('custom-popover'); var popoverMessage = document.getElementById('popover-message'); function showPopover(message) { popoverMessage.textContent = message; popover.classList.add('show'); popover.style.pointerEvents = 'auto'; clearTimeout(hideTimeout); hideTimeout = setTimeout(function() { popover.classList.remove('show'); popover.style.pointerEvents = 'none'; }, 3000); } if (getURL.includes(subString)) { onAuthStateChanged(auth, async (user) => { if (user) { const imagesLikedTextBlock = document.getElementById('block-yui_3_17_2_1_1723629178851_25945'); const imagesLikedText = imagesLikedTextBlock.querySelector('p'); const statusTextBlock = document.getElementById('block-yui_3_17_2_1_1723629178851_17416'); const statusText = statusTextBlock.querySelector('p'); const SignOutButton = document.getElementById('block-ed832b202fab80c68286'); const desiresButton = document.getElementById('block-77b36cfb140b770fa15e'); const desiresTextBlock = document.getElementById('block-2faf595f9b3381a46ed6'); const desiresText = desiresTextBlock.querySelector('p'); const userAccountBadge = document.querySelector('.user-accounts-link'); const userAccountLink = userAccountBadge.querySelector('a'); const userAccountButton = document.getElementById('block-6456a0bb547b865b3236'); //squarespace user accounts link to button userAccountButton.addEventListener('click', function(event) { event.preventDefault(); userAccountLink.click(); }); //Sign out logic SignOutButton.addEventListener('click', async (event) => { event.preventDefault(); try { const user = auth.currentUser; if (user) { const userId = user.uid; await setDoc(doc(db, 'users', userId), { status: 'offline', lastStatusChange: serverTimestamp() }, { merge: true }); await signOut(auth); window.location.href = '/login'; } } catch (error) { statusText.textContent = '- Stay here traitor!'; // Sign out failed status console.error('Sign out error', error); } }); function checkSelectOptions(productItem) { var selects = productItem.querySelectorAll('select'); for (var i = 0; i < selects.length; i++) { if (selects[i].selectedIndex === 0) { return 'Please Select ' + selects[i].options[0].textContent; } } return null; } //display greeting const userDocRef = doc(db, 'users', user.uid); try { const userDocSnap = await getDoc(userDocRef); if (userDocSnap.exists()) { const userData = userDocSnap.data(); const userCodename = userData.codename || 'secret'; // Default statusText.textContent = userCodename === 'secret' ? 'Welcome Stranger.' : `Welcome ${userCodename}.`; // Use actual codename } else { statusText.textContent = `Welcome Stranger.`; // Default greeting } } catch (error) { console.error('Error fetching user data:', error); $('#popoverMessage').off('click'); popoverMessage.style.color = "#ea4b1a"; showPopover('Error fetching your data.'); statusText.textContent = `Welcome Stranger.`; // Default greeting on error } //check if mobile view let isTouch = false; const headerActions = document.querySelector('.header-actions'); function checkHeader() { const styles = window.getComputedStyle(headerActions); isTouch = styles.getPropertyValue('display') !== 'flex'; } checkHeader(); //sync wishlist from local and display number of desires and link to wishlist desiresButton.addEventListener('click', function(event) { event.preventDefault(); window.location.href = '/shop?view=wishlist'; }); const wishlistRef = collection(db, 'users', user.uid, 'wishlist'); try { const wishlistSnapshot = await getDocs(wishlistRef); let firestoreWishlist = wishlistSnapshot.docs.map(doc => doc.id); let localWishlist = JSON.parse(localStorage.getItem('wishlist') || '[]'); if (localWishlist){ const combinedWishlist = Array.from(new Set([...localWishlist, ...firestoreWishlist])); const batch = writeBatch(db); combinedWishlist.forEach(itemId => { const itemDocRef = doc(wishlistRef, itemId); batch.set(itemDocRef, { itemId: itemId }); }); await batch.commit(); localStorage.removeItem('wishlist'); } const desireCount = wishlistSnapshot.size; const desireWord = desireCount === 1 ? 'desire' : 'desires'; desiresText.textContent = `You have ${desireCount} ${desireWord}.`; } catch (error) { console.error('Error fetching liked images:', error); $('#popoverMessage').off('click'); popoverMessage.style.color = "#ea4b1a"; showPopover('Error fetching desires'); } //Display number of liked images const likedImagesRef = collection(db, 'users', user.uid, 'likedImages'); try { const likedImagesSnapshot = await getDocs(likedImagesRef); const itemCount = likedImagesSnapshot.size; const itemWord = itemCount === 1 ? 'sigil' : 'sigils'; imagesLikedText.textContent = `You are considering ${itemCount} ${itemWord}.`; } catch (error) { console.error('Error fetching liked images:', error); $('#popoverMessage').off('click'); popoverMessage.style.color = "#ea4b1a"; showPopover('Error fetching liked images'); } //exit strategy } else { window.location.href = '/login'; //if not logged in redirect } }); } }); </script>
CSS:
This page had more code to change password and code name, this functionality has been moved to the dossier page.
COMMENTS:
Leave a comment: