import React, { useState, useEffect } from 'react'; import styled from 'styled-components'; import Post from '../components/Post/Post'; import api from '../services/api'; import { FaSpinner, FaExclamationTriangle, FaUsers } from 'react-icons/fa'; const PageContainer = styled.div` max-width: 100%; `; const PageHeader = styled.div` display: flex; align-items: center; gap: 0.75rem; margin-bottom: 2rem; `; const PageTitle = styled.h1` color: #1f2937; margin: 0; font-size: 1.8rem; display: flex; align-items: center; gap: 0.5rem; `; const PageDescription = styled.p` color: #6b7280; margin: 0.5rem 0 0 0; line-height: 1.5; `; const LoadingContainer = styled.div` text-align: center; padding: 2rem; color: #6b7280; `; const ErrorContainer = styled.div` background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; padding: 1rem; margin: 1rem 0; color: #dc2626; display: flex; align-items: center; gap: 0.5rem; `; const LoadMoreButton = styled.button` width: 100%; padding: 1rem; background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; color: #6b7280; cursor: pointer; margin: 1rem 0; &:hover { background: #f3f4f6; } &:disabled { cursor: not-allowed; opacity: 0.5; } `; const EmptyState = styled.div` text-align: center; padding: 3rem; color: #6b7280; .icon { font-size: 4rem; margin-bottom: 1rem; color: #d1d5db; } h3 { margin: 0 0 0.5rem 0; color: #374151; } p { margin: 0; line-height: 1.5; } `; const LocalTimelinePage = () => { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [loadingMore, setLoadingMore] = useState(false); const [hasMore, setHasMore] = useState(true); useEffect(() => { loadTimeline(); }, []); const loadTimeline = async (maxId = null) => { try { if (!maxId) { setLoading(true); setError(null); } const timelineData = await api.getPublicTimeline({ max_id: maxId, limit: 20, local: true // Only local content }); if (maxId) { setPosts(prev => [...prev, ...timelineData]); setLoadingMore(false); } else { setPosts(timelineData); setLoading(false); } setHasMore(timelineData.length === 20); } catch (err) { console.error('Error loading local timeline:', err); if (err.response?.status === 401) { setError('Authentication required to view the local timeline.'); } else if (err.response?.status === 403) { setError('Local timeline is not available on this instance.'); } else if (err.code === 'ECONNABORTED') { setError('Request timeout. Please check your connection and try again.'); } else { setError('Failed to load local timeline. Please try again.'); } setLoading(false); setLoadingMore(false); } }; const handleFavorite = async (post) => { try { let updatedPost; if (post.favourited) { updatedPost = await api.unfavoriteStatus(post.id); } else { updatedPost = await api.favoriteStatus(post.id); } setPosts(prev => prev.map(p => p.id === post.id ? updatedPost : p)); } catch (err) { console.error('Error toggling favorite:', err); } }; const handleReblog = async (post) => { try { let updatedPost; if (post.reblogged) { updatedPost = await api.unreblogStatus(post.id); } else { updatedPost = await api.reblogStatus(post.id); } setPosts(prev => prev.map(p => p.id === post.id ? updatedPost : p)); } catch (err) { console.error('Error toggling reblog:', err); } }; const handleLoadMore = () => { if (posts.length > 0 && hasMore && !loadingMore) { setLoadingMore(true); const lastPost = posts[posts.length - 1]; loadTimeline(lastPost.id); } }; if (loading) { return ( Local Timeline
Loading local timeline...
); } return ( Local Timeline Public posts from users on this instance only. This is a great way to see what your local community is talking about. {error && ( {error} )} {posts.length === 0 && !loading ? (

No local posts

There are no local public posts available right now.
This instance might be new or have limited local activity.

) : ( <> {posts.map(post => ( console.log('Reply to:', post)} /> ))} {hasMore && ( {loadingMore ? ( <> Loading more posts... ) : ( 'Load more posts' )} )} )}
); }; export default LocalTimelinePage;