'use client'; import { useState, useEffect } from 'react'; import { Inbox, Star, Send, File, Trash, RefreshCw, Plus, Search, Loader2, MailOpen, Mail, ArchiveIcon } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Separator } from '@/components/ui/separator'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Badge } from '@/components/ui/badge'; import EmailPanel from './EmailPanel'; import { EmailMessage } from '@/lib/services/email-service'; import { useToast } from "@/hooks/use-toast"; import { sendEmail } from '@/lib/services/email-service'; import { useSession } from "next-auth/react"; interface EmailLayoutProps { className?: string; } export default function EmailLayout({ className = '' }: EmailLayoutProps) { // Email state const [emails, setEmails] = useState([]); const [selectedEmail, setSelectedEmail] = useState<{ emailId: string; accountId: string; folder: string; } | null>(null); const [currentFolder, setCurrentFolder] = useState('INBOX'); const [folders, setFolders] = useState([]); const [mailboxes, setMailboxes] = useState([]); // UI state const [loading, setLoading] = useState(true); const [searching, setSearching] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const [error, setError] = useState(null); const [isSending, setIsSending] = useState(false); const [showComposeModal, setShowComposeModal] = useState(false); // Get toast and session const { toast } = useToast(); const { data: session } = useSession(); // Load emails on component mount and when folder changes useEffect(() => { loadEmails(); }, [currentFolder, page]); // Function to load emails const loadEmails = async (refresh = false) => { if (refresh) { setPage(1); } setLoading(true); setError(null); try { // Construct the API endpoint URL with parameters const queryParams = new URLSearchParams({ folder: currentFolder, page: page.toString(), perPage: '20' }); if (searchQuery) { queryParams.set('search', searchQuery); } const response = await fetch(`/api/courrier?${queryParams.toString()}`); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Failed to fetch emails'); } const data = await response.json(); if (refresh || page === 1) { setEmails(data.emails || []); } else { // Append emails for pagination setEmails(prev => [...prev, ...(data.emails || [])]); } // Update available folders if returned from API if (data.mailboxes && data.mailboxes.length > 0) { setMailboxes(data.mailboxes); // Create a nicer list of standard folders const standardFolders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk']; const customFolders = data.mailboxes.filter( (folder: string) => !standardFolders.includes(folder) ); // Combine standard folders that exist with custom folders const availableFolders = [ ...standardFolders.filter(f => data.mailboxes.includes(f)), ...customFolders ]; setFolders(availableFolders); } // Check if there are more emails to load setHasMore(data.emails && data.emails.length >= 20); } catch (err) { console.error('Error loading emails:', err); setError(err instanceof Error ? err.message : 'Failed to load emails'); } finally { setLoading(false); } }; // Handle folder change const handleFolderChange = (folder: string) => { setCurrentFolder(folder); setSelectedEmail(null); setPage(1); setSearchQuery(''); }; // Handle email selection const handleEmailSelect = (emailId: string, accountId: string, folder: string) => { setSelectedEmail({ emailId, accountId, folder }); }; // Handle search const handleSearch = () => { if (searchQuery.trim()) { setSearching(true); setPage(1); loadEmails(true); } }; // Handle refreshing emails const handleRefresh = () => { loadEmails(true); }; // Handle composing a new email const handleComposeNew = () => { setSelectedEmail(null); // The compose functionality will be handled by the EmailPanel component }; // Handle email sending const handleSendEmail = async (emailData: { to: string; cc?: string; bcc?: string; subject: string; body: string; attachments?: Array<{ name: string; content: string; type: string; }>; }): Promise => { setIsSending(true); try { // The sendEmail function requires userId as the first parameter const result = await sendEmail(session?.user?.id as string, emailData); if (result.success) { toast({ title: "Success", description: "Email sent successfully" }); setShowComposeModal(false); } else { toast({ variant: "destructive", title: "Error", description: `Failed to send email: ${result.error || 'Unknown error'}` }); } } catch (error) { console.error('Error sending email:', error); toast({ variant: "destructive", title: "Error", description: "Failed to send email" }); } finally { setIsSending(false); } }; // Format the date in a readable format const formatDate = (dateString: string) => { const date = new Date(dateString); const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const yesterday = new Date(today); yesterday.setDate(yesterday.getDate() - 1); // Check if date is today if (date >= today) { return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } // Check if date is yesterday if (date >= yesterday) { return 'Yesterday'; } // Check if date is this year if (date.getFullYear() === now.getFullYear()) { return date.toLocaleDateString([], { month: 'short', day: 'numeric' }); } // Date is from a previous year return date.toLocaleDateString([], { year: 'numeric', month: 'short', day: 'numeric' }); }; // Get folder icon const getFolderIcon = (folder: string) => { switch (folder.toLowerCase()) { case 'inbox': return ; case 'sent': case 'sent items': return ; case 'drafts': return ; case 'trash': case 'deleted': case 'bin': return ; case 'junk': case 'spam': return ; default: return ; } }; return (
{/* Sidebar */}
{/* New email button */}
{/* Folder navigation */}
{folders.map((folder) => ( ))}
{/* Main content */}
{/* Email list */}
{/* Search and refresh */}
setSearchQuery(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSearch()} />
{/* Email list */} {loading && emails.length === 0 ? (
) : emails.length === 0 ? (
No emails found
) : (
{emails.map((email) => (
handleEmailSelect(email.id, email.accountId || '', email.folder || '')} >
{email.flags.seen ? ( ) : ( )}

{email.from[0]?.name || email.from[0]?.address || 'Unknown'}

{formatDate(email.date.toString())}

{email.subject}

{email.preview}

{/* Email indicators */}
{email.hasAttachments && ( Attachment )}
))}
)}
{/* Email preview */}
); }