175 lines
5.9 KiB
TypeScript
175 lines
5.9 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState } from 'react';
|
|
import {
|
|
Inbox, Send, Trash, Archive, Star,
|
|
File, RefreshCw, Plus, MailOpen, Settings,
|
|
ChevronDown, ChevronRight, Mail
|
|
} from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { cn } from '@/lib/utils';
|
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
import { Badge } from '@/components/ui/badge';
|
|
|
|
interface EmailSidebarProps {
|
|
currentFolder: string;
|
|
folders: string[];
|
|
onFolderChange: (folder: string) => void;
|
|
onRefresh: () => void;
|
|
onCompose: () => void;
|
|
isLoading: boolean;
|
|
}
|
|
|
|
export default function EmailSidebar({
|
|
currentFolder,
|
|
folders,
|
|
onFolderChange,
|
|
onRefresh,
|
|
onCompose,
|
|
isLoading
|
|
}: EmailSidebarProps) {
|
|
const [showFolders, setShowFolders] = useState(true);
|
|
|
|
// Get the appropriate icon for a folder
|
|
const getFolderIcon = (folder: string) => {
|
|
const folderLower = folder.toLowerCase();
|
|
|
|
switch (folderLower) {
|
|
case 'inbox':
|
|
return <Inbox className="h-4 w-4" />;
|
|
case 'sent':
|
|
case 'sent items':
|
|
return <Send className="h-4 w-4" />;
|
|
case 'drafts':
|
|
return <File className="h-4 w-4" />;
|
|
case 'trash':
|
|
case 'deleted':
|
|
case 'bin':
|
|
return <Trash className="h-4 w-4" />;
|
|
case 'archive':
|
|
case 'archived':
|
|
return <Archive className="h-4 w-4" />;
|
|
case 'starred':
|
|
case 'important':
|
|
return <Star className="h-4 w-4" />;
|
|
default:
|
|
return <MailOpen className="h-4 w-4" />;
|
|
}
|
|
};
|
|
|
|
// Group folders into standard and custom
|
|
const standardFolders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Archive', 'Junk'];
|
|
const visibleStandardFolders = standardFolders.filter(f =>
|
|
folders.includes(f) || folders.some(folder => folder.toLowerCase() === f.toLowerCase())
|
|
);
|
|
|
|
const customFolders = folders.filter(f =>
|
|
!standardFolders.some(sf => sf.toLowerCase() === f.toLowerCase())
|
|
);
|
|
|
|
return (
|
|
<aside className="w-64 border-r h-full flex flex-col bg-white/95 backdrop-blur-sm">
|
|
{/* Compose button area */}
|
|
<div className="p-4">
|
|
<Button
|
|
className="w-full bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center justify-center py-2"
|
|
onClick={onCompose}
|
|
>
|
|
<Plus className="h-4 w-4 mr-2" />
|
|
New Email
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Folder navigation */}
|
|
<ScrollArea className="flex-1">
|
|
<div className="p-2 space-y-1">
|
|
{/* Accounts header with toggle */}
|
|
<div className="flex items-center justify-between px-2 py-2 text-sm font-medium text-gray-600">
|
|
<span>Accounts</span>
|
|
{isLoading && <RefreshCw className="h-3 w-3 animate-spin text-gray-400" />}
|
|
</div>
|
|
|
|
{/* 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">
|
|
<Mail className="h-4 w-4 mr-2" />
|
|
<span>Mail</span>
|
|
</div>
|
|
{showFolders ? (
|
|
<ChevronDown className="h-4 w-4" />
|
|
) : (
|
|
<ChevronRight className="h-4 w-4" />
|
|
)}
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Folders list - shown only when showFolders is true */}
|
|
{showFolders && (
|
|
<div className="pl-6 space-y-1">
|
|
{visibleStandardFolders.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 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 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>
|
|
</ScrollArea>
|
|
|
|
{/* Settings button (bottom) */}
|
|
<div className="p-2 border-t border-gray-100">
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
className="w-full justify-start text-gray-600 hover:text-gray-900"
|
|
>
|
|
<Settings className="h-4 w-4 mr-2" />
|
|
<span>Email settings</span>
|
|
</Button>
|
|
</div>
|
|
</aside>
|
|
);
|
|
}
|