courrier multi account restore compose
This commit is contained in:
parent
53b95dd240
commit
d6c6832a21
@ -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>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user