'use client'; import React, { useState } from 'react'; import { Loader2, Mail, Search, X } from 'lucide-react'; import { Email } from '@/hooks/use-courrier'; import EmailListItem from './EmailListItem'; import EmailListHeader from './EmailListHeader'; import BulkActionsToolbar from './BulkActionsToolbar'; import { Input } from '@/components/ui/input'; interface EmailListProps { emails: Email[]; selectedEmailIds: string[]; selectedEmail: Email | null; currentFolder: string; isLoading: boolean; totalEmails: number; hasMoreEmails: boolean; onSelectEmail: (emailId: string) => void; onToggleSelect: (emailId: string) => void; onToggleSelectAll: () => void; onBulkAction: (action: 'delete' | 'mark-read' | 'mark-unread' | 'archive') => void; onToggleStarred: (emailId: string) => void; onLoadMore: () => void; onSearch?: (query: string) => void; } export default function EmailList({ emails, selectedEmailIds, selectedEmail, currentFolder, isLoading, totalEmails, hasMoreEmails, onSelectEmail, onToggleSelect, onToggleSelectAll, onBulkAction, onToggleStarred, onLoadMore, onSearch }: EmailListProps) { const [scrollPosition, setScrollPosition] = useState(0); const [searchQuery, setSearchQuery] = useState(''); const scrollRef = React.useRef(null); const [emailsLength, setEmailsLength] = useState(emails.length); const [isScrollingToTop, setIsScrollingToTop] = useState(false); // Track changes in emails array to manage scrolling React.useEffect(() => { // If email count increased, we loaded more emails if (emails.length > emailsLength) { // If not loading more at the bottom, let's maintain scroll position if (!isLoading && scrollRef.current && !isScrollingToTop) { // This ensures the visible emails stay the same after loading more setTimeout(() => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollPosition; } }, 50); } } // Update the emails length tracker setEmailsLength(emails.length); }, [emails, emailsLength, isLoading, scrollPosition]); // Add event listener for scroll reset from parent component React.useEffect(() => { const handleResetScroll = () => { console.log("Resetting scroll position to top"); if (scrollRef.current) { setTimeout(() => { if (scrollRef.current) { // Force scroll to top scrollRef.current.scrollTop = 0; } }, 100); } }; // Listen for the custom event window.addEventListener('reset-email-scroll', handleResetScroll); // Also reset scroll when folder changes handleResetScroll(); return () => { window.removeEventListener('reset-email-scroll', handleResetScroll); }; }, [currentFolder]); // Reset scroll when folder changes // Handle scroll to detect when user reaches the bottom or scrolls up const handleScroll = (event: React.UIEvent) => { const target = event.target as HTMLDivElement; const { scrollTop, scrollHeight, clientHeight } = target; // Save scroll position for restoration when needed setScrollPosition(scrollTop); // Detect scrolling direction setIsScrollingToTop(scrollTop < scrollPosition); // If user scrolls near the bottom and we have more emails, load more if (scrollHeight - scrollTop - clientHeight < 200 && hasMoreEmails && !isLoading) { // Store current scroll data before loading more const currentScrollTop = scrollTop; const currentScrollHeight = scrollHeight; // Request more emails onLoadMore(); } }; // Add a function to scroll to top const scrollToTop = () => { if (scrollRef.current) { scrollRef.current.scrollTop = 0; } }; // Update title to show date sort order React.useEffect(() => { // Add a small indicator in the header to show emails are sorted by date const headerElement = document.querySelector('.email-header-title'); if (headerElement) { headerElement.setAttribute('title', 'Emails are sorted by date (newest first)'); } }, []); // Handle search const handleSearch = (e: React.FormEvent) => { e.preventDefault(); onSearch?.(searchQuery); }; const clearSearch = () => { setSearchQuery(''); onSearch?.(''); }; // Render loading state if (isLoading && emails.length === 0) { return (
); } // Render empty state if (emails.length === 0) { return (

{searchQuery ? 'No emails match your search' : currentFolder === 'INBOX' ? "Your inbox is empty. You're all caught up!" : 'No emails in this folder'}

); } // Are all emails selected const allSelected = selectedEmailIds.length === emails.length && emails.length > 0; // Are some (but not all) emails selected const someSelected = selectedEmailIds.length > 0 && selectedEmailIds.length < emails.length; return (
{/* Search header */}
setSearchQuery(e.target.value)} /> {searchQuery && ( )}
{selectedEmailIds.length > 0 && ( )}
{/* Add a small note to show emails are sorted by date */}
Sorted by date (newest first)
{emails.map((email) => ( onSelectEmail(email.id)} onToggleSelect={(e: React.MouseEvent) => { e.stopPropagation(); onToggleSelect(email.id); }} onToggleStarred={(e: React.MouseEvent) => { e.stopPropagation(); onToggleStarred(email.id); }} /> ))} {isLoading && emails.length > 0 && (
)}
); }