import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { motion } from 'framer-motion'; import Navbar from './Navbar'; import Footer from './footer'; import './Explore.css'; const Explore = () => { const navigate = useNavigate(); const [publicPosts, setPublicPosts] = useState([]); const [searchQuery, setSearchQuery] = useState(''); const [searchResults, setSearchResults] = useState([]); const [isLoading, setIsLoading] = useState(false); const [isSearching, setIsSearching] = useState(false); const [showPostDetailModal, setShowPostDetailModal] = useState(false); const [selectedPost, setSelectedPost] = useState(null); const [users, setUsers] = useState({}); const [likedPosts, setLikedPosts] = useState([]); const [newComment, setNewComment] = useState(''); const [pins, setPins] = useState([]); // Fetch all public posts and pins useEffect(() => { const fetchPublicPosts = async () => { setIsLoading(true); try { // Fetch public posts const postsResponse = await fetch('https://jp-backend-kc80.onrender.com/api/userposts'); const postsData = await postsResponse.json(); const filteredPosts = Array.isArray(postsData) ? postsData.filter(post => post.public) : []; setPublicPosts(filteredPosts); // Fetch all pins const pinsResponse = await fetch('https://jp-backend-kc80.onrender.com/api/pins'); const pinsData = await pinsResponse.json(); setPins(Array.isArray(pinsData) ? pinsData : []); // Fetch user data for each post's author const uniqueUsernames = [...new Set(filteredPosts.map(post => post.username))]; const usersData = {}; for (const username of uniqueUsernames) { const userResponse = await fetch(`https://jp-backend-kc80.onrender.com/api/users?username=${username}`); const userData = await userResponse.json(); if (userData.length > 0) { usersData[username] = userData[0]; } } setUsers(usersData); // Load liked posts from localStorage const storedLikes = localStorage.getItem('likedPosts'); if (storedLikes) { setLikedPosts(JSON.parse(storedLikes)); } } catch (error) { console.error('Error fetching data:', error); } finally { setIsLoading(false); } }; fetchPublicPosts(); }, []); // Handle search for users const handleSearch = async (e) => { e.preventDefault(); if (!searchQuery.trim()) return; setIsSearching(true); try { const response = await fetch('https://jp-backend-kc80.onrender.com/api/getuser'); const users = await response.json(); // Filter users based on search query (case insensitive) const filteredUsers = Array.isArray(users) ? users.filter(user => user.username.toLowerCase().includes(searchQuery.toLowerCase())) : []; setSearchResults(filteredUsers); } catch (error) { console.error('Error searching users:', error); } finally { setIsSearching(false); } }; // Handle post click const handlePostClick = (post) => { setSelectedPost(post); setShowPostDetailModal(true); }; // Handle like post const handleLikePost = async (postId) => { if (likedPosts.includes(postId)) return; try { const response = await fetch(`https://jp-backend-kc80.onrender.com/api/userposts/${postId}/like`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) throw new Error('Failed to like post'); const result = await response.json(); // Update liked posts state const newLikedPosts = [...likedPosts, postId]; setLikedPosts(newLikedPosts); localStorage.setItem('likedPosts', JSON.stringify(newLikedPosts)); // Update the selected post's like count if (selectedPost && selectedPost.id === postId) { setSelectedPost(prev => ({ ...prev, likes: result.likes })); } // Update the post in the main posts list setPublicPosts(prev => prev.map(post => post.id === postId ? { ...post, likes: result.likes } : post ) ); } catch (error) { console.error('Error liking post:', error); } }; // Handle add comment const handleAddComment = async (e) => { e.preventDefault(); if (!newComment.trim() || !selectedPost || !localStorage.getItem('username')) return; const storedUsername = localStorage.getItem('username'); try { const response = await fetch(`https://jp-backend-kc80.onrender.com/api/userposts/${selectedPost.id}/comment`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username: storedUsername, comment: newComment }), }); if (!response.ok) throw new Error('Failed to add comment'); // Create the new comment entry const newCommentEntry = { [localStorage.getItem('username')]: newComment }; // Update the selected post's comments setSelectedPost(prev => ({ ...prev, comments: { ...(prev.comments || {}), ...newCommentEntry } })); // Also update the post in the main posts list setPublicPosts(prev => prev.map(post => post.id === selectedPost.id ? { ...post, comments: { ...(post.comments || {}), ...newCommentEntry } } : post ) ); setNewComment(''); } catch (error) { console.error('Error adding comment:', error); } }; // Navigate to user's profile const navigateToProfile = (username) => { navigate(`/profile/${username}`); }; return (
{/* Search Bar */}
setSearchQuery(e.target.value)} />
{/* Search Results */} {searchResults.length > 0 && (

Search Results

{searchResults.map(user => (
navigateToProfile(user.username)} > {user.username} {user.username}
))}
)} {/* Public Posts Grid */}

Explore Public Posts

{isLoading ? (
Loading posts...
) : publicPosts.length > 0 ? (
{publicPosts.map((post, index) => (
handlePostClick(post)}> {`Post
❤️ {post.likes || 0} 💬 {Object.keys(post.comments || {}).length}
))}
) : (

No public posts available.

)}
{/* Post Detail Modal */} {showPostDetailModal && selectedPost && (
setShowPostDetailModal(false)}> e.stopPropagation()} >
Post
navigateToProfile(selectedPost.username)}> Profile {selectedPost.username}

{selectedPost.description}

Tags: {selectedPost.tags || 'No tags'}
{/* Add this section for the pin location */} {selectedPost.pin_id && (
Location: {pins.find(pin => pin.id === selectedPost.pin_id)?.pin_name || 'Unknown location'}
)}
💬 {Object.keys(selectedPost.comments || {}).length} comments
{/* Comments section */}

Comments

{selectedPost.comments && Object.keys(selectedPost.comments).length > 0 ? (
{Object.entries(selectedPost.comments).map(([username, comment]) => (
{username}: {comment}
))}
) : (

No comments yet

)}
{/* Add comment form */} {localStorage.getItem('username') && (
setNewComment(e.target.value)} />
)}
Posted on: {new Date(selectedPost.created_at).toLocaleDateString()}
)}
); }; export default Explore;