courrier multi account restore compose

This commit is contained in:
alma 2025-04-29 09:04:15 +02:00
parent 53b95dd240
commit d6c6832a21

View File

@ -13,8 +13,13 @@ import { Badge } from '@/components/ui/badge';
interface EmailSidebarProps { interface EmailSidebarProps {
currentFolder: string; currentFolder: string;
folders: string[]; currentAccount: string;
onFolderChange: (folder: string) => void; accounts: Array<{
id: string;
email: string;
folders: string[];
}>;
onFolderChange: (folder: string, accountId: string) => void;
onRefresh: () => void; onRefresh: () => void;
onCompose: () => void; onCompose: () => void;
isLoading: boolean; isLoading: boolean;
@ -22,13 +27,15 @@ interface EmailSidebarProps {
export default function EmailSidebar({ export default function EmailSidebar({
currentFolder, currentFolder,
folders, currentAccount,
accounts,
onFolderChange, onFolderChange,
onRefresh, onRefresh,
onCompose, onCompose,
isLoading isLoading
}: EmailSidebarProps) { }: EmailSidebarProps) {
const [showFolders, setShowFolders] = useState(true); const [showAccounts, setShowAccounts] = useState(true);
const [expandedAccount, setExpandedAccount] = useState<string | null>(currentAccount);
// Get the appropriate icon for a folder // Get the appropriate icon for a folder
const getFolderIcon = (folder: string) => { const getFolderIcon = (folder: string) => {
@ -58,14 +65,23 @@ export default function EmailSidebar({
}; };
// Group folders into standard and custom // Group folders into standard and custom
const standardFolders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Archive', 'Junk']; const getStandardFolders = (folders: string[]) => {
const visibleStandardFolders = standardFolders.filter(f => const standardFolders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Archive', 'Junk'];
folders.includes(f) || folders.some(folder => folder.toLowerCase() === f.toLowerCase()) return standardFolders.filter(f =>
); folders.includes(f) || folders.some(folder => folder.toLowerCase() === f.toLowerCase())
);
};
const customFolders = folders.filter(f => const getCustomFolders = (folders: string[]) => {
!standardFolders.some(sf => sf.toLowerCase() === f.toLowerCase()) const standardFolders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Archive', 'Junk'];
); return folders.filter(f =>
!standardFolders.some(sf => sf.toLowerCase() === f.toLowerCase())
);
};
const handleAccountClick = (accountId: string) => {
setExpandedAccount(expandedAccount === accountId ? null : accountId);
};
return ( return (
<aside className="w-64 border-r h-full flex flex-col bg-white/95 backdrop-blur-sm"> <aside className="w-64 border-r h-full flex flex-col bg-white/95 backdrop-blur-sm">
@ -76,84 +92,98 @@ export default function EmailSidebar({
onClick={onCompose} onClick={onCompose}
> >
<Plus className="h-4 w-4 mr-2" /> <Plus className="h-4 w-4 mr-2" />
New Email Compose
</Button> </Button>
</div> </div>
{/* Folder navigation */} {/* Accounts and folders navigation */}
<ScrollArea className="flex-1"> <ScrollArea className="flex-1">
<div className="p-2 space-y-1"> <div className="p-2 space-y-1">
{/* Accounts header with toggle */} {/* Accounts header with toggle */}
<div className="flex items-center justify-between px-2 py-2 text-sm font-medium text-gray-600"> <div className="flex items-center justify-between px-2 py-2 text-sm font-medium text-gray-600">
<span>Accounts</span> <span>Accounts</span>
{isLoading && <RefreshCw className="h-3 w-3 animate-spin text-gray-400" />} <button
</div> onClick={() => setShowAccounts(!showAccounts)}
className="text-gray-400 hover:text-gray-600"
{/* Mail account with toggle arrow */}
<div className="px-2">
<Button
variant="ghost"
className="w-full justify-between p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100"
onClick={() => setShowFolders(!showFolders)}
> >
<div className="flex items-center"> {showAccounts ? (
<Mail className="h-4 w-4 mr-2" />
<span>Mail</span>
</div>
{showFolders ? (
<ChevronDown className="h-4 w-4" /> <ChevronDown className="h-4 w-4" />
) : ( ) : (
<ChevronRight className="h-4 w-4" /> <ChevronRight className="h-4 w-4" />
)} )}
</Button> </button>
</div> </div>
{/* Folders list - shown only when showFolders is true */} {/* Accounts list */}
{showFolders && ( {showAccounts && (
<div className="pl-6 space-y-1"> <div className="space-y-1">
{visibleStandardFolders.map((folder) => ( {accounts.map((account) => (
<Button <div key={account.id} className="space-y-1">
key={folder} {/* Account button */}
variant={currentFolder === folder ? "secondary" : "ghost"} <Button
className={`w-full justify-start ${ variant="ghost"
currentFolder === folder ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900' className={`w-full justify-between p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 ${
}`} expandedAccount === account.id ? 'bg-gray-100' : ''
onClick={() => onFolderChange(folder)} }`}
> onClick={() => handleAccountClick(account.id)}
<div className="flex items-center w-full"> >
<span className="flex items-center"> <div className="flex items-center">
{getFolderIcon(folder)} <Mail className="h-4 w-4 mr-2" />
<span className="ml-2 capitalize">{folder.toLowerCase()}</span> <span className="truncate">{account.email}</span>
</span> </div>
{folder === 'INBOX' && ( {expandedAccount === account.id ? (
<span className="ml-auto bg-blue-600 text-white text-xs px-2 py-0.5 rounded-full"> <ChevronDown className="h-4 w-4" />
{/* Unread count would go here */} ) : (
</span> <ChevronRight className="h-4 w-4" />
)} )}
</div> </Button>
</Button>
{/* Account folders - shown when account is expanded */}
{expandedAccount === account.id && (
<div className="pl-6 space-y-1">
{getStandardFolders(account.folders).map((folder) => (
<Button
key={folder}
variant={currentFolder === folder && currentAccount === account.id ? "secondary" : "ghost"}
className={`w-full justify-start ${
currentFolder === folder && currentAccount === account.id ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900'
}`}
onClick={() => onFolderChange(folder, account.id)}
>
<div className="flex items-center w-full">
<span className="flex items-center">
{getFolderIcon(folder)}
<span className="ml-2 capitalize">{folder.toLowerCase()}</span>
</span>
{folder === 'INBOX' && (
<span className="ml-auto bg-blue-600 text-white text-xs px-2 py-0.5 rounded-full">
{/* Unread count would go here */}
</span>
)}
</div>
</Button>
))}
{/* Custom folders */}
{getCustomFolders(account.folders).map(folder => (
<Button
key={folder}
variant={currentFolder === folder && currentAccount === account.id ? "secondary" : "ghost"}
className={`w-full justify-start ${
currentFolder === folder && currentAccount === account.id ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900'
}`}
onClick={() => onFolderChange(folder, account.id)}
>
<div className="flex items-center">
{getFolderIcon(folder)}
<span className="ml-2 truncate">{folder}</span>
</div>
</Button>
))}
</div>
)}
</div>
))} ))}
{/* Custom folders section */}
{customFolders.length > 0 && (
<>
{customFolders.map(folder => (
<Button
key={folder}
variant={currentFolder === folder ? "secondary" : "ghost"}
className={`w-full justify-start ${
currentFolder === folder ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900'
}`}
onClick={() => onFolderChange(folder)}
>
<div className="flex items-center">
{getFolderIcon(folder)}
<span className="ml-2 truncate">{folder}</span>
</div>
</Button>
))}
</>
)}
</div> </div>
)} )}
</div> </div>