331 lines
13 KiB
JavaScript
331 lines
13 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
const loginForm = document.querySelector('.login-form');
|
|
const loginContainer = document.querySelector('.login-container');
|
|
const feedView = document.getElementById('feed-view');
|
|
const emailInput = document.getElementById('email');
|
|
const passwordInput = document.getElementById('password');
|
|
const confirmPasswordInput = document.getElementById('confirm-password');
|
|
const confirmPasswordGroup = document.getElementById('confirm-password-group');
|
|
const submitBtn = document.querySelector('.btn-primary');
|
|
const btnText = submitBtn.querySelector('span');
|
|
const helperText = document.querySelector('.signup-link');
|
|
const toggleLink = document.querySelector('.signup-link a');
|
|
const title = document.querySelector('.brand-section h1');
|
|
const subtitle = document.querySelector('.brand-section p');
|
|
|
|
let isLoginMode = true;
|
|
|
|
// Toggle between Login and Signup
|
|
if (toggleLink) {
|
|
toggleLink.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
isLoginMode = !isLoginMode;
|
|
updateUI();
|
|
});
|
|
}
|
|
|
|
function updateUI() {
|
|
if (isLoginMode) {
|
|
title.innerText = 'Welcome Back';
|
|
subtitle.innerText = 'Enter your details below';
|
|
btnText.innerText = 'Sign In';
|
|
helperText.innerHTML = 'Don\'t have an account? <a href="#">Create One</a>';
|
|
confirmPasswordGroup.classList.add('hidden');
|
|
confirmPasswordInput.required = false;
|
|
} else {
|
|
title.innerText = 'Create Account';
|
|
subtitle.innerText = 'Start your journey with us';
|
|
btnText.innerText = 'Sign Up';
|
|
helperText.innerHTML = 'Already have an account? <a href="#">Sign In</a>';
|
|
confirmPasswordGroup.classList.remove('hidden');
|
|
confirmPasswordInput.required = true;
|
|
}
|
|
|
|
// Re-attach listener to the new link element
|
|
const newLink = document.querySelector('.signup-link a');
|
|
newLink.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
isLoginMode = !isLoginMode;
|
|
updateUI();
|
|
});
|
|
|
|
// Reset form and styles
|
|
loginForm.reset();
|
|
resetButton();
|
|
}
|
|
|
|
function resetButton() {
|
|
submitBtn.style.background = '';
|
|
submitBtn.style.transform = '';
|
|
btnText.innerText = isLoginMode ? 'Sign In' : 'Sign Up';
|
|
}
|
|
|
|
function showFeedback(isSuccess, message) {
|
|
btnText.innerText = message;
|
|
if (isSuccess) {
|
|
submitBtn.style.background = 'linear-gradient(135deg, #10B981 0%, #059669 100%)'; // Success Green
|
|
} else {
|
|
submitBtn.style.background = 'linear-gradient(135deg, #EF4444 0%, #B91C1C 100%)'; // Error Red
|
|
submitBtn.animate([
|
|
{ transform: 'translateX(0)' },
|
|
{ transform: 'translateX(-5px)' },
|
|
{ transform: 'translateX(5px)' },
|
|
{ transform: 'translateX(0)' }
|
|
], { duration: 300 });
|
|
}
|
|
|
|
setTimeout(() => {
|
|
if (!message.includes('Success')) {
|
|
resetButton();
|
|
}
|
|
}, 2000);
|
|
}
|
|
|
|
function navigateToFeed() {
|
|
if (loginContainer && feedView) {
|
|
// Fade out login
|
|
loginContainer.style.opacity = '0';
|
|
|
|
setTimeout(() => {
|
|
loginContainer.classList.add('hidden');
|
|
loginContainer.style.display = 'none'; // Ensure it's gone
|
|
|
|
// Show Feed
|
|
feedView.classList.remove('hidden');
|
|
// Trigger reflow
|
|
void feedView.offsetWidth;
|
|
feedView.classList.add('fade-in');
|
|
|
|
// Load persisted state for posts
|
|
loadPostState();
|
|
|
|
// Remove fade-in class after animation to fix fixed positioning context
|
|
setTimeout(() => {
|
|
feedView.classList.remove('fade-in');
|
|
}, 600);
|
|
}, 600); // Wait for transition
|
|
}
|
|
}
|
|
|
|
if (loginForm) {
|
|
loginForm.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
|
|
const email = emailInput.value.trim();
|
|
const password = passwordInput.value.trim();
|
|
const confirmPassword = confirmPasswordInput.value.trim();
|
|
const timestamp = new Date().toISOString();
|
|
|
|
// Get existing users
|
|
const existingUsers = JSON.parse(localStorage.getItem('socialAppUsers') || '[]');
|
|
|
|
if (isLoginMode) {
|
|
// --- LOGIN LOGIC ---
|
|
const user = existingUsers.find(u => u.email === email && u.password === password);
|
|
|
|
if (user) {
|
|
console.log('Login Successful:', user);
|
|
showFeedback(true, 'Success!');
|
|
setTimeout(navigateToFeed, 1000);
|
|
} else {
|
|
console.warn('Login Failed: Invalid credentials');
|
|
showFeedback(false, 'Incorrect details');
|
|
}
|
|
|
|
} else {
|
|
// --- SIGNUP LOGIC ---
|
|
// 1. Check if user already exists
|
|
if (existingUsers.some(u => u.email === email)) {
|
|
showFeedback(false, 'User exists');
|
|
return;
|
|
}
|
|
|
|
// 2. Validate Password Match
|
|
if (password !== confirmPassword) {
|
|
showFeedback(false, 'Passwords do not match');
|
|
return;
|
|
}
|
|
|
|
const newUser = { email, password, joinedAt: timestamp };
|
|
existingUsers.push(newUser);
|
|
localStorage.setItem('socialAppUsers', JSON.stringify(existingUsers));
|
|
|
|
console.log('New User Registered:', newUser);
|
|
showFeedback(true, 'Account Created!');
|
|
|
|
// Switch to login mode after success
|
|
setTimeout(() => {
|
|
isLoginMode = true;
|
|
updateUI();
|
|
setTimeout(navigateToFeed, 1000);
|
|
}, 1500);
|
|
}
|
|
});
|
|
}
|
|
|
|
// --- PERSISTENCE LOGIC ---
|
|
function getPostState() {
|
|
return JSON.parse(localStorage.getItem('socialAppPostState') || '{}');
|
|
}
|
|
|
|
function savePostState(state) {
|
|
localStorage.setItem('socialAppPostState', JSON.stringify(state));
|
|
}
|
|
|
|
function loadPostState() {
|
|
const state = getPostState();
|
|
const posts = document.querySelectorAll('.post-card');
|
|
|
|
posts.forEach(card => {
|
|
const id = card.getAttribute('data-post-id');
|
|
if (id && state[id]) {
|
|
const data = state[id];
|
|
|
|
// Restore Likes
|
|
const likeIcon = card.querySelector('.heart-icon');
|
|
const likesText = card.querySelector('.likes');
|
|
|
|
if (data.liked) {
|
|
likeIcon.classList.add('liked');
|
|
likeIcon.style.fill = '#EF4444';
|
|
likeIcon.style.stroke = '#EF4444';
|
|
} else {
|
|
likeIcon.classList.remove('liked');
|
|
likeIcon.style.fill = 'none';
|
|
likeIcon.style.stroke = 'white';
|
|
}
|
|
likesText.innerText = data.likesCount + ' likes';
|
|
|
|
// Restore Comments
|
|
const commentsContainer = card.querySelector('.added-comments');
|
|
commentsContainer.innerHTML = ''; // Clear existing to prevent dupes on re-run
|
|
if (data.comments && data.comments.length > 0) {
|
|
data.comments.forEach(text => {
|
|
const commentEl = document.createElement('div');
|
|
commentEl.classList.add('comment-item');
|
|
commentEl.innerHTML = `<span class="comment-user">you</span> ${text}`;
|
|
commentsContainer.appendChild(commentEl);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// --- FEED INTERACTIONS ---
|
|
if (feedView) {
|
|
feedView.addEventListener('click', (e) => {
|
|
const target = e.target;
|
|
|
|
// 1. LIKE ACTION
|
|
const likeBtn = target.closest('.heart-icon')?.closest('.icon-btn');
|
|
if (likeBtn) {
|
|
const icon = likeBtn.querySelector('.heart-icon');
|
|
const postCard = likeBtn.closest('.post-card');
|
|
const likesText = postCard.querySelector('.likes');
|
|
const postId = postCard.getAttribute('data-post-id');
|
|
|
|
// Toggle State
|
|
icon.classList.toggle('liked');
|
|
|
|
// Update Count (Simple parsing)
|
|
let count = parseInt(likesText.innerText);
|
|
let isLiked = false;
|
|
|
|
if (icon.classList.contains('liked')) {
|
|
icon.style.fill = '#EF4444';
|
|
icon.style.stroke = '#EF4444';
|
|
count++;
|
|
isLiked = true;
|
|
} else {
|
|
icon.style.fill = 'none';
|
|
icon.style.stroke = 'white';
|
|
count--;
|
|
isLiked = false;
|
|
}
|
|
likesText.innerText = count + ' likes';
|
|
|
|
// Save State
|
|
if (postId) {
|
|
const state = getPostState();
|
|
if (!state[postId]) state[postId] = { comments: [] };
|
|
state[postId].liked = isLiked;
|
|
state[postId].likesCount = count;
|
|
// Preserve existing comments if we didn't just load them
|
|
if (!state[postId].comments) state[postId].comments = [];
|
|
savePostState(state);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 2. COMMENT TOGGLE ACTION
|
|
const commentBtn = target.closest('.icon-btn');
|
|
if (commentBtn && !commentBtn.querySelector('.heart-icon')) {
|
|
// Check if it's the comment button (has specific path)
|
|
const path = commentBtn.querySelector('path');
|
|
if (path && (path.getAttribute('d').startsWith('M21 11.5') || path.closest('svg')?.innerHTML.includes('M21 11.5'))) {
|
|
const postCard = commentBtn.closest('.post-card');
|
|
const commentSection = postCard.querySelector('.comment-section');
|
|
commentSection.classList.toggle('active');
|
|
if (commentSection.classList.contains('active')) {
|
|
commentSection.querySelector('input').focus();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 3. POST COMMENT ACTION
|
|
if (target.classList.contains('post-btn')) {
|
|
const wrapper = target.closest('.comment-input-wrapper');
|
|
const input = wrapper.querySelector('.comment-input');
|
|
const text = input.value.trim();
|
|
const postCard = wrapper.closest('.post-card');
|
|
const postId = postCard.getAttribute('data-post-id');
|
|
|
|
if (text) {
|
|
addComment(wrapper.closest('.comment-section'), text);
|
|
|
|
if (postId) {
|
|
const state = getPostState();
|
|
if (!state[postId]) state[postId] = { liked: false, likesCount: parseInt(postCard.querySelector('.likes').innerText) || 0, comments: [] };
|
|
if (!state[postId].comments) state[postId].comments = [];
|
|
state[postId].comments.push(text);
|
|
savePostState(state);
|
|
}
|
|
input.value = '';
|
|
}
|
|
}
|
|
});
|
|
|
|
// Enter key for comments
|
|
feedView.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Enter' && e.target.classList.contains('comment-input')) {
|
|
const text = e.target.value.trim();
|
|
const wrapper = e.target.closest('.comment-input-wrapper');
|
|
const postCard = wrapper.closest('.post-card');
|
|
const postId = postCard.getAttribute('data-post-id');
|
|
|
|
if (text) {
|
|
addComment(e.target.closest('.comment-section'), text);
|
|
|
|
if (postId) {
|
|
const state = getPostState();
|
|
if (!state[postId]) state[postId] = { liked: false, likesCount: parseInt(postCard.querySelector('.likes').innerText) || 0, comments: [] };
|
|
if (!state[postId].comments) state[postId].comments = [];
|
|
state[postId].comments.push(text);
|
|
savePostState(state);
|
|
}
|
|
e.target.value = '';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function addComment(section, text) {
|
|
const container = section.querySelector('.added-comments');
|
|
const commentEl = document.createElement('div');
|
|
commentEl.classList.add('comment-item');
|
|
commentEl.innerHTML = `<span class="comment-user">you</span> ${text}`;
|
|
container.appendChild(commentEl);
|
|
}
|
|
});
|