AccountDeletePostV1
This commit is contained in:
146
script.js
146
script.js
@@ -68,7 +68,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// --- QUERY SELECTORS ---
|
||||
const loginForm = document.querySelector('.login-form');
|
||||
const loginContainer = document.querySelector('.login-container');
|
||||
const loginView = document.getElementById('login-view');
|
||||
const feedView = document.getElementById('feed-view');
|
||||
const emailInput = document.getElementById('email');
|
||||
const passwordInput = document.getElementById('password');
|
||||
@@ -80,6 +80,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const title = document.querySelector('.brand-section h1');
|
||||
const subtitle = document.querySelector('.brand-section p');
|
||||
|
||||
// Onboarding Elements
|
||||
const verificationView = document.getElementById('verification-view');
|
||||
const onboardingView = document.getElementById('onboarding-view');
|
||||
const otpInput = document.getElementById('otp-input');
|
||||
const verifyBtn = document.getElementById('verify-btn');
|
||||
const displayNameInput = document.getElementById('display-name');
|
||||
const bioInput = document.getElementById('bio-input');
|
||||
const avatarInput = document.getElementById('avatar-input');
|
||||
const avatarPreview = document.getElementById('avatar-preview');
|
||||
const avatarTrigger = document.getElementById('avatar-upload-trigger');
|
||||
const completeSetupBtn = document.getElementById('complete-setup-btn');
|
||||
|
||||
// Post Creation Elements
|
||||
const createPostView = document.getElementById('create-post-view');
|
||||
const cancelPostBtn = document.getElementById('cancel-post-btn');
|
||||
@@ -95,9 +107,71 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const lightboxView = document.getElementById('lightbox-view');
|
||||
const lightboxClose = document.getElementById('lightbox-close');
|
||||
const lightboxCarousel = document.querySelector('.lightbox-carousel');
|
||||
// We check for counter inside helper, as it might be common class
|
||||
|
||||
let isLoginMode = true;
|
||||
let pendingUser = null;
|
||||
let generatedOTP = null;
|
||||
let newAvatarBase64 = null;
|
||||
|
||||
// --- ONBOARDING LOGIC ---
|
||||
// Avatar Upload Handler
|
||||
if (avatarTrigger && avatarInput) {
|
||||
avatarTrigger.addEventListener('click', () => avatarInput.click());
|
||||
avatarInput.addEventListener('change', (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
newAvatarBase64 = e.target.result;
|
||||
avatarPreview.src = newAvatarBase64;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Verify OTP Handler
|
||||
if (verifyBtn) {
|
||||
verifyBtn.addEventListener('click', () => {
|
||||
if (otpInput.value === generatedOTP) {
|
||||
verificationView.classList.add('hidden');
|
||||
onboardingView.classList.remove('hidden');
|
||||
onboardingView.classList.add('fade-in');
|
||||
} else {
|
||||
alert('Invalid Code');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Complete Setup Handler
|
||||
if (completeSetupBtn) {
|
||||
completeSetupBtn.addEventListener('click', async () => {
|
||||
const name = displayNameInput.value.trim();
|
||||
if (!name) { alert('Name is required'); return; }
|
||||
|
||||
const bio = bioInput.value.trim();
|
||||
|
||||
// Finalize User
|
||||
const finalUser = {
|
||||
...pendingUser,
|
||||
username: name,
|
||||
bio: bio,
|
||||
avatar: newAvatarBase64 || 'https://i.pravatar.cc/150?img=12'
|
||||
};
|
||||
|
||||
// Save to DB
|
||||
const existingUsers = JSON.parse(localStorage.getItem('socialAppUsers') || '[]');
|
||||
existingUsers.push(finalUser);
|
||||
localStorage.setItem('socialAppUsers', JSON.stringify(existingUsers));
|
||||
localStorage.setItem('currentUser', JSON.stringify(finalUser)); // Log them in
|
||||
|
||||
// Transition
|
||||
onboardingView.classList.add('hidden');
|
||||
feedView.classList.remove('hidden');
|
||||
feedView.classList.add('fade-in');
|
||||
initFeed();
|
||||
});
|
||||
}
|
||||
|
||||
// --- LIGHTBOX LOGIC ---
|
||||
function openLightbox(media, startIndex) {
|
||||
@@ -120,7 +194,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// Scroll to index
|
||||
const width = window.innerWidth;
|
||||
// Need brief timeout for layout to stabilise
|
||||
setTimeout(() => {
|
||||
lightboxCarousel.scrollLeft = width * startIndex;
|
||||
}, 10);
|
||||
@@ -208,11 +281,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
function navigateToFeed() {
|
||||
if (loginContainer && feedView) {
|
||||
loginContainer.style.opacity = '0';
|
||||
if (loginView && feedView) {
|
||||
loginView.style.opacity = '0';
|
||||
setTimeout(() => {
|
||||
loginContainer.classList.add('hidden');
|
||||
loginContainer.style.display = 'none';
|
||||
loginView.classList.add('hidden');
|
||||
loginView.style.display = 'none';
|
||||
feedView.classList.remove('hidden');
|
||||
void feedView.offsetWidth;
|
||||
feedView.classList.add('fade-in');
|
||||
@@ -234,6 +307,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (isLoginMode) {
|
||||
const user = existingUsers.find(u => u.email === email && u.password === password);
|
||||
if (user) {
|
||||
localStorage.setItem('currentUser', JSON.stringify(user));
|
||||
showFeedback(true, 'Success!');
|
||||
setTimeout(navigateToFeed, 1000);
|
||||
} else {
|
||||
@@ -248,11 +322,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
showFeedback(false, 'Passwords do not match');
|
||||
return;
|
||||
}
|
||||
const newUser = { email, password, joinedAt: timestamp };
|
||||
existingUsers.push(newUser);
|
||||
localStorage.setItem('socialAppUsers', JSON.stringify(existingUsers));
|
||||
showFeedback(true, 'Account Created!');
|
||||
setTimeout(() => { isLoginMode = true; updateUI(); setTimeout(navigateToFeed, 1000); }, 1500);
|
||||
|
||||
// Start Verification Flow
|
||||
pendingUser = { email, password, joinedAt: timestamp };
|
||||
generatedOTP = Math.floor(100000 + Math.random() * 900000).toString();
|
||||
|
||||
alert(`[MOCK EMAIL] Your verification code is: ${generatedOTP}`);
|
||||
|
||||
loginView.classList.add('hidden');
|
||||
verificationView.classList.remove('hidden');
|
||||
verificationView.classList.add('fade-in');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -270,7 +349,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
for (const post of postsToRender) {
|
||||
if (!isPostDeleted(post.id) && !document.querySelector(`[data-post-id="${post.id}"]`)) {
|
||||
let mediaItems = post.media;
|
||||
// Backwards Compatibility implementation
|
||||
if (!mediaItems && post.imageSrc) {
|
||||
mediaItems = [{ type: 'image', src: post.imageSrc }];
|
||||
}
|
||||
@@ -323,13 +401,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
function renderPost(post, prepend = false) {
|
||||
if (document.querySelector(`[data-post-id="${post.id}"]`)) return;
|
||||
|
||||
const feedContainer = document.querySelector('.feed-container');
|
||||
const container = document.querySelector('.feed-container'); // Renamed variable
|
||||
const article = document.createElement('article');
|
||||
article.className = 'post-card';
|
||||
article.setAttribute('data-post-id', post.id);
|
||||
|
||||
const isUserPost = post.id && post.id.startsWith('post_');
|
||||
const optionsHTML = isUserPost ? `
|
||||
const currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}');
|
||||
const isOwner = post.userEmail && post.userEmail === currentUser.email;
|
||||
|
||||
// Only show options if owner
|
||||
const optionsHTML = isOwner ? `
|
||||
<button class="icon-btn-sm options-trigger">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" fill="none" stroke-width="2"><circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle><circle cx="5" cy="12" r="1"></circle></svg>
|
||||
</button>
|
||||
@@ -339,7 +420,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
Delete Post
|
||||
</button>
|
||||
</div>
|
||||
` : `<button class="icon-btn-sm">...</button>`;
|
||||
` : '';
|
||||
|
||||
let slidesHTML = '';
|
||||
let dotsHTML = '';
|
||||
@@ -370,7 +451,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
article.innerHTML = `
|
||||
<div class="post-header">
|
||||
<div class="post-user">
|
||||
<img src="https://i.pravatar.cc/150?img=12" alt="User" class="avatar-sm">
|
||||
<img src="${post.userAvatar || 'https://i.pravatar.cc/150?img=12'}" alt="User" class="avatar-sm">
|
||||
<span class="username">${post.username}</span>
|
||||
</div>
|
||||
${optionsHTML}
|
||||
@@ -403,11 +484,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
`;
|
||||
|
||||
if (prepend) {
|
||||
if (!feedContainer.querySelector(`[data-post-id="${post.id}"]`)) {
|
||||
feedContainer.insertBefore(article, feedContainer.firstChild);
|
||||
if (!container.querySelector(`[data-post-id="${post.id}"]`)) {
|
||||
container.insertBefore(article, container.firstChild);
|
||||
}
|
||||
}
|
||||
else feedContainer.appendChild(article);
|
||||
else container.appendChild(article);
|
||||
|
||||
// Attach Drag-to-Scroll & Lightbox Click
|
||||
const carousel = article.querySelector('.media-carousel');
|
||||
@@ -487,15 +568,26 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const card = deleteBtn.closest('.post-card');
|
||||
const id = card.getAttribute('data-post-id');
|
||||
if (id && id.startsWith('post_')) {
|
||||
const userPosts = JSON.parse(localStorage.getItem('socialAppUserPosts') || '[]');
|
||||
const postToDelete = userPosts.find(p => p.id === id);
|
||||
const currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}');
|
||||
|
||||
if (!postToDelete || postToDelete.userEmail !== currentUser.email) {
|
||||
alert('You can only delete your own posts.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirm('Delete this post?')) {
|
||||
card.style.transition = 'opacity 0.3s, transform 0.3s';
|
||||
card.style.opacity = '0';
|
||||
card.style.transform = 'scale(0.9)';
|
||||
setTimeout(() => card.remove(), 300);
|
||||
let userPosts = JSON.parse(localStorage.getItem('socialAppUserPosts') || '[]');
|
||||
userPosts = userPosts.filter(p => p.id !== id);
|
||||
localStorage.setItem('socialAppUserPosts', JSON.stringify(userPosts));
|
||||
|
||||
const updatedPosts = userPosts.filter(p => p.id !== id);
|
||||
localStorage.setItem('socialAppUserPosts', JSON.stringify(updatedPosts));
|
||||
|
||||
deleteImageFromDB(id);
|
||||
|
||||
const deletedPosts = JSON.parse(localStorage.getItem('socialAppDeletedPosts') || '[]');
|
||||
if (!deletedPosts.includes(id)) {
|
||||
deletedPosts.push(id);
|
||||
@@ -687,12 +779,15 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const caption = captionInput.value.trim();
|
||||
const id = 'post_' + Date.now();
|
||||
|
||||
const currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}');
|
||||
const displayPost = {
|
||||
id,
|
||||
media: stagedMedia,
|
||||
caption,
|
||||
timestamp: new Date().toISOString(),
|
||||
username: 'you',
|
||||
username: currentUser.username || 'You',
|
||||
userAvatar: currentUser.avatar,
|
||||
userEmail: currentUser.email, // Secure Owner ID
|
||||
likes: 0
|
||||
};
|
||||
renderPost(displayPost, true);
|
||||
@@ -703,6 +798,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
caption,
|
||||
timestamp: displayPost.timestamp,
|
||||
username: displayPost.username,
|
||||
userEmail: currentUser.email, // Secure Owner ID
|
||||
likes: 0
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user