"use client"; import React, { useState, useCallback } from 'react'; // Types export interface MailMessage { id: string; from: { name: string; email: string; avatar?: string; }; to?: { name: string; email: string; }[]; subject: string; preview: string; body?: string; date: Date; isRead?: boolean; isStarred?: boolean; hasAttachment?: boolean; attachments?: MailAttachment[]; labels?: string[]; folder?: string; } export interface MailAttachment { id: string; name: string; size: string; type: string; url?: string; } export interface MailFolder { id: string; name: string; icon?: React.ReactNode; count?: number; color?: string; } export interface MailLabel { id: string; name: string; color: string; } // Mail Layout export interface MailLayoutProps { /** Sidebar content (folders, labels) */ sidebar?: React.ReactNode; /** Main content area */ children: React.ReactNode; /** Compose button handler */ onCompose?: () => void; /** Show sidebar */ showSidebar?: boolean; /** Additional CSS classes */ className?: string; } export const MailLayout: React.FC = ({ sidebar, children, onCompose, showSidebar = true, className = '', }) => { return (
{showSidebar && (
{onCompose && ( )} {sidebar}
)}
{children}
); }; // Mail Sidebar export interface MailSidebarProps { /** Folders list */ folders?: MailFolder[]; /** Labels list */ labels?: MailLabel[]; /** Active folder ID */ activeFolder?: string; /** Folder click handler */ onFolderClick?: (folder: MailFolder) => void; /** Label click handler */ onLabelClick?: (label: MailLabel) => void; /** Additional CSS classes */ className?: string; } export const MailSidebar: React.FC = ({ folders = [], labels = [], activeFolder, onFolderClick, onLabelClick, className = '', }) => { return (
{folders.length > 0 && (
Folders
    {folders.map((folder) => (
  • onFolderClick?.(folder)} > {folder.icon && {folder.icon}} {folder.name} {folder.count !== undefined && folder.count > 0 && ( {folder.count} )}
  • ))}
)} {labels.length > 0 && (
Labels
    {labels.map((label) => (
  • onLabelClick?.(label)} > {label.name}
  • ))}
)}
); }; // Mail List export interface MailListProps { /** Messages to display */ messages: MailMessage[]; /** Selected message IDs */ selectedIds?: string[]; /** Selection change handler */ onSelectionChange?: (ids: string[]) => void; /** Message click handler */ onMessageClick?: (message: MailMessage) => void; /** Star toggle handler */ onStarToggle?: (message: MailMessage) => void; /** Show checkboxes */ showCheckboxes?: boolean; /** Loading state */ loading?: boolean; /** Empty state message */ emptyMessage?: string; /** Additional CSS classes */ className?: string; } export const MailList: React.FC = ({ messages, selectedIds = [], onSelectionChange, onMessageClick, onStarToggle, showCheckboxes = true, loading = false, emptyMessage = 'No messages', className = '', }) => { const handleSelectAll = useCallback(() => { if (selectedIds.length === messages.length) { onSelectionChange?.([]); } else { onSelectionChange?.(messages.map((m) => m.id)); } }, [selectedIds, messages, onSelectionChange]); const handleSelectMessage = useCallback((id: string) => { if (selectedIds.includes(id)) { onSelectionChange?.(selectedIds.filter((sid) => sid !== id)); } else { onSelectionChange?.([...selectedIds, id]); } }, [selectedIds, onSelectionChange]); const formatDate = (date: Date) => { const now = new Date(); const diff = now.getTime() - date.getTime(); const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (days === 0) { return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } else if (days === 1) { return 'Yesterday'; } else if (days < 7) { return date.toLocaleDateString([], { weekday: 'short' }); } else { return date.toLocaleDateString([], { month: 'short', day: 'numeric' }); } }; if (loading) { return (
); } if (messages.length === 0) { return (

{emptyMessage}

); } return (
{showCheckboxes && (
{selectedIds.length > 0 ? `${selectedIds.length} selected` : `${messages.length} messages`}
)}
{messages.map((message) => (
{showCheckboxes && ( )}
onMessageClick?.(message)}>
{message.from.avatar ? ( {message.from.name} ) : ( {message.from.name.charAt(0).toUpperCase()} )}
{message.from.name} {formatDate(message.date)}
{message.subject}
{message.preview}
{message.hasAttachment && (
)}
))}
); }; // Mail Toolbar export interface MailToolbarProps { /** Selected count */ selectedCount?: number; /** Archive handler */ onArchive?: () => void; /** Delete handler */ onDelete?: () => void; /** Mark as read handler */ onMarkRead?: () => void; /** Mark as unread handler */ onMarkUnread?: () => void; /** Move handler */ onMove?: () => void; /** Refresh handler */ onRefresh?: () => void; /** Search value */ searchValue?: string; /** Search change handler */ onSearchChange?: (value: string) => void; /** Additional CSS classes */ className?: string; } export const MailToolbar: React.FC = ({ selectedCount = 0, onArchive, onDelete, onMarkRead, onMarkUnread, onMove, onRefresh, searchValue = '', onSearchChange, className = '', }) => { return (
{selectedCount > 0 ? ( <> {onArchive && ( )} {onDelete && ( )} {onMarkRead && ( )} {onMarkUnread && ( )} {onMove && ( )} ) : ( onRefresh && ( ) )}
{onSearchChange && (
onSearchChange(e.target.value)} />
)}
); }; // Mail Read View export interface MailReadProps { /** Message to display */ message: MailMessage; /** Back button handler */ onBack?: () => void; /** Reply handler */ onReply?: () => void; /** Reply all handler */ onReplyAll?: () => void; /** Forward handler */ onForward?: () => void; /** Delete handler */ onDelete?: () => void; /** Star toggle handler */ onStarToggle?: () => void; /** Additional CSS classes */ className?: string; } export const MailRead: React.FC = ({ message, onBack, onReply, onReplyAll, onForward, onDelete, onStarToggle, className = '', }) => { const formatDate = (date: Date) => { return date.toLocaleDateString([], { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit', }); }; return (
{onBack && ( )}
{onReply && ( )} {onReplyAll && ( )} {onForward && ( )} {onDelete && ( )} {onStarToggle && ( )}

{message.subject}

{message.labels && message.labels.length > 0 && (
{message.labels.map((label, index) => ( {label} ))}
)}
{message.from.avatar ? ( {message.from.name} ) : ( {message.from.name.charAt(0).toUpperCase()} )}
{message.from.name} <{message.from.email}>
to {message.to?.map((r) => r.name).join(', ') || 'me'}
{formatDate(message.date)}
{message.body || message.preview}
{message.attachments && message.attachments.length > 0 && (
{message.attachments.length} attachment{message.attachments.length > 1 ? 's' : ''}
{message.attachments.map((attachment) => (
{attachment.name} {attachment.size}
))}
)}
); }; // Mail Compose export interface MailComposeProps { /** Initial values */ initialTo?: string; initialSubject?: string; initialBody?: string; /** Send handler */ onSend?: (data: { to: string; cc?: string; bcc?: string; subject: string; body: string }) => void; /** Save draft handler */ onSaveDraft?: (data: { to: string; cc?: string; bcc?: string; subject: string; body: string }) => void; /** Discard handler */ onDiscard?: () => void; /** Close handler */ onClose?: () => void; /** Show as modal */ isModal?: boolean; /** Additional CSS classes */ className?: string; } export const MailCompose: React.FC = ({ initialTo = '', initialSubject = '', initialBody = '', onSend, onSaveDraft, onDiscard, onClose, isModal = false, className = '', }) => { const [to, setTo] = useState(initialTo); const [cc, setCc] = useState(''); const [bcc, setBcc] = useState(''); const [subject, setSubject] = useState(initialSubject); const [body, setBody] = useState(initialBody); const [showCc, setShowCc] = useState(false); const [showBcc, setShowBcc] = useState(false); const handleSend = () => { onSend?.({ to, cc, bcc, subject, body }); }; const handleSaveDraft = () => { onSaveDraft?.({ to, cc, bcc, subject, body }); }; return (

New Message

{onClose && ( )}
setTo(e.target.value)} placeholder="Recipients" />
{!showCc && ( )} {!showBcc && ( )}
{showCc && (
setCc(e.target.value)} placeholder="Cc recipients" />
)} {showBcc && (
setBcc(e.target.value)} placeholder="Bcc recipients" />
)}
setSubject(e.target.value)} placeholder="Subject" />