ui enhancement
This commit is contained in:
parent
78aac5a925
commit
45e3898acb
4 changed files with 175 additions and 91 deletions
|
|
@ -1,10 +1,9 @@
|
|||
import {
|
||||
Bot,
|
||||
ChevronDown,
|
||||
Clock3,
|
||||
FileEdit,
|
||||
Inbox,
|
||||
ListFilter,
|
||||
ListChecks,
|
||||
LogOut,
|
||||
Mail,
|
||||
Menu,
|
||||
|
|
@ -14,7 +13,6 @@ import {
|
|||
ShieldAlert,
|
||||
Sparkles,
|
||||
Star,
|
||||
Tags,
|
||||
Trash2,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
|
|
@ -30,26 +28,25 @@ const mailItems = [
|
|||
[Star, "Starred", "starred"],
|
||||
[Clock3, "Snoozed"],
|
||||
[Send, "Sent"],
|
||||
[FileEdit, "Drafts"],
|
||||
[FileEdit, "Drafts", "drafts"],
|
||||
[ShieldAlert, "Spam"],
|
||||
[Trash2, "Trash"],
|
||||
[Clock3, "Scheduled"],
|
||||
];
|
||||
|
||||
const labels = [
|
||||
["Important", "rose"],
|
||||
["Projects", "violet"],
|
||||
["Clients", "blue"],
|
||||
["Finance", "amber"],
|
||||
["Personal", "green"],
|
||||
["Important", "rose", "Important"],
|
||||
["Projects", "violet", "Projects"],
|
||||
["Clients", "blue", "Clients"],
|
||||
["Finance", "amber", "Finance"],
|
||||
["Personal", "green", "Personal"],
|
||||
];
|
||||
|
||||
const agentItems = [
|
||||
[Tags, "Tags"],
|
||||
[ListFilter, "Filters"],
|
||||
[Sparkles, "Summary"],
|
||||
[Plug, "Integration"],
|
||||
[Settings, "Settings"],
|
||||
[Sparkles, "Ask Agent", "ask"],
|
||||
[ListChecks, "Action Items", "actions"],
|
||||
[Sparkles, "Summaries", "summaries"],
|
||||
[Plug, "Integrations", "integrations"],
|
||||
];
|
||||
|
||||
function clearSession() {
|
||||
|
|
@ -57,28 +54,20 @@ function clearSession() {
|
|||
sessionStorage.removeItem("agmail_account");
|
||||
}
|
||||
|
||||
function NavGroup({ icon: Icon, title, items, active, counts, onSelect }) {
|
||||
function SidebarSection({ title, children, className = "" }) {
|
||||
return (
|
||||
<section className="dashboard-nav-group">
|
||||
<h2><Icon size={13} />{title}</h2>
|
||||
<nav aria-label={title}>
|
||||
{items.map(([ItemIcon, label, countKey]) => (
|
||||
<button
|
||||
className={active === label ? "active" : ""}
|
||||
key={label}
|
||||
onClick={() => onSelect(label)}
|
||||
type="button"
|
||||
>
|
||||
<ItemIcon size={16} />
|
||||
<span>{label}</span>
|
||||
{countKey && counts?.[countKey] > 0 && <em>{counts[countKey]}</em>}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
<section className={`dashboard-sidebar-section ${className}`}>
|
||||
<h2>{title}</h2>
|
||||
{children}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function NavBadge({ value }) {
|
||||
if (!value) return null;
|
||||
return <em>{value}</em>;
|
||||
}
|
||||
|
||||
export default function DashboardPage() {
|
||||
const [account, setAccount] = useState(null);
|
||||
const [companyDomain, setCompanyDomain] = useState(null);
|
||||
|
|
@ -90,9 +79,15 @@ export default function DashboardPage() {
|
|||
const [notice, setNotice] = useState("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [mailRefreshKey, setMailRefreshKey] = useState(0);
|
||||
const [labelsOpen, setLabelsOpen] = useState(true);
|
||||
const [lens, setLens] = useState("all");
|
||||
const [mailStats, setMailStats] = useState({ unread: 0, starred: 0, important: 0 });
|
||||
const [agentNav, setAgentNav] = useState(null);
|
||||
const [mailStats, setMailStats] = useState({
|
||||
unread: 0,
|
||||
starred: 0,
|
||||
important: 0,
|
||||
drafts: 0,
|
||||
labels: {},
|
||||
});
|
||||
const handleStats = useCallback((stats) => setMailStats(stats), []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -128,16 +123,14 @@ export default function DashboardPage() {
|
|||
window.location.assign("/login");
|
||||
}
|
||||
|
||||
function selectItem(item) {
|
||||
function selectMailItem(item) {
|
||||
setAgentNav(null);
|
||||
if (item === "Starred") {
|
||||
setActive("Inbox");
|
||||
setLens("starred");
|
||||
} else if (item === "Sent") {
|
||||
setActive("Outbox");
|
||||
setLens("all");
|
||||
} else if (labels.some(([name]) => name === item)) {
|
||||
setActive("Inbox");
|
||||
setLens(item);
|
||||
} else {
|
||||
setActive(item);
|
||||
setLens("all");
|
||||
|
|
@ -145,6 +138,20 @@ export default function DashboardPage() {
|
|||
setMenuOpen(false);
|
||||
}
|
||||
|
||||
function selectLabel(name) {
|
||||
setAgentNav(null);
|
||||
setActive("Inbox");
|
||||
setLens(name);
|
||||
setMenuOpen(false);
|
||||
}
|
||||
|
||||
function selectAgentItem(item, actionKey) {
|
||||
setActive("Inbox");
|
||||
setLens("all");
|
||||
setAgentNav(actionKey);
|
||||
setMenuOpen(false);
|
||||
}
|
||||
|
||||
function emailSent() {
|
||||
setComposeOpen(false);
|
||||
setActive("Outbox");
|
||||
|
|
@ -191,6 +198,13 @@ export default function DashboardPage() {
|
|||
const workspaceTitle = account.account_type === "company" && companyDomain
|
||||
? companyDomain.domain_name
|
||||
: "Personal workspace";
|
||||
const mailActive = lens === "starred"
|
||||
? "Starred"
|
||||
: active === "Outbox"
|
||||
? "Sent"
|
||||
: labels.some(([name]) => lens === name)
|
||||
? "Inbox"
|
||||
: active;
|
||||
|
||||
return (
|
||||
<div className="dashboard">
|
||||
|
|
@ -207,34 +221,63 @@ export default function DashboardPage() {
|
|||
<Brand />
|
||||
<button aria-label="Close navigation" type="button" onClick={() => setMenuOpen(false)}><X size={19} /></button>
|
||||
</div>
|
||||
|
||||
<button className="dashboard-compose" type="button" onClick={() => setComposeOpen(true)}>
|
||||
<Mail size={17} />Compose
|
||||
<Mail size={17} />
|
||||
<span>Compose</span>
|
||||
<ChevronDown size={14} className="dashboard-compose-caret" />
|
||||
</button>
|
||||
<NavGroup icon={Mail} title="Mail" items={mailItems} active={lens === "starred" ? "Starred" : active === "Outbox" ? "Sent" : active} counts={mailStats} onSelect={selectItem} />
|
||||
<section className="dashboard-labels">
|
||||
<button type="button" className="dashboard-labels-toggle" onClick={() => setLabelsOpen((open) => !open)} aria-expanded={labelsOpen}>
|
||||
<Tags size={16} />
|
||||
<span>Labels</span>
|
||||
<ChevronDown size={14} className={labelsOpen ? "open" : ""} />
|
||||
</button>
|
||||
{labelsOpen && (
|
||||
<nav aria-label="Labels">
|
||||
{labels.map(([name, tone]) => (
|
||||
<button
|
||||
className={lens === name ? "active" : ""}
|
||||
key={name}
|
||||
type="button"
|
||||
onClick={() => selectItem(name)}
|
||||
>
|
||||
<i className={`label-dot label-dot-${tone}`} />
|
||||
<span>{name}</span>
|
||||
{name === "Important" && mailStats.important > 0 && <em>{mailStats.important}</em>}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
)}
|
||||
</section>
|
||||
<NavGroup icon={Bot} title="Agent" items={agentItems} active={active} onSelect={selectItem} />
|
||||
|
||||
<SidebarSection title="Mail" className="dashboard-sidebar-mail">
|
||||
<nav aria-label="Mail">
|
||||
{mailItems.map(([ItemIcon, label, countKey]) => (
|
||||
<button
|
||||
className={`dashboard-nav-item${mailActive === label ? " active" : ""}`}
|
||||
key={label}
|
||||
type="button"
|
||||
onClick={() => selectMailItem(label)}
|
||||
>
|
||||
<ItemIcon size={15} />
|
||||
<span>{label}</span>
|
||||
<NavBadge value={countKey ? mailStats[countKey] : 0} />
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</SidebarSection>
|
||||
|
||||
<SidebarSection title="Labels" className="dashboard-sidebar-labels">
|
||||
<nav aria-label="Labels">
|
||||
{labels.map(([name, tone, countKey]) => (
|
||||
<button
|
||||
className={`dashboard-nav-item dashboard-label-item${lens === name ? " active" : ""}`}
|
||||
key={name}
|
||||
type="button"
|
||||
onClick={() => selectLabel(name)}
|
||||
>
|
||||
<i className={`label-dot label-dot-${tone}`} />
|
||||
<span>{name}</span>
|
||||
<NavBadge value={mailStats.labels?.[countKey]} />
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</SidebarSection>
|
||||
|
||||
<SidebarSection title="Agent" className="dashboard-sidebar-agent">
|
||||
<nav aria-label="Agent">
|
||||
{agentItems.map(([ItemIcon, label, actionKey]) => (
|
||||
<button
|
||||
className={`dashboard-nav-item dashboard-agent-item${agentNav === actionKey ? " active" : ""}`}
|
||||
key={label}
|
||||
type="button"
|
||||
onClick={() => selectAgentItem(label, actionKey)}
|
||||
>
|
||||
<ItemIcon size={15} />
|
||||
<span>{label}</span>
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</SidebarSection>
|
||||
|
||||
<div className="dashboard-profile">
|
||||
<span>{account.first_name[0]}{account.last_name[0]}</span>
|
||||
<div><strong>{account.first_name} {account.last_name}</strong><small>{account.email}</small></div>
|
||||
|
|
@ -256,8 +299,9 @@ export default function DashboardPage() {
|
|||
refreshKey={mailRefreshKey}
|
||||
account={account}
|
||||
lens={lens}
|
||||
agentNav={agentNav}
|
||||
onLogout={logout}
|
||||
onOpenSettings={() => selectItem("Settings")}
|
||||
onOpenSettings={() => selectMailItem("Settings")}
|
||||
onStats={handleStats}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -268,7 +312,7 @@ export default function DashboardPage() {
|
|||
refreshKey={mailRefreshKey}
|
||||
account={account}
|
||||
onLogout={logout}
|
||||
onOpenSettings={() => selectItem("Settings")}
|
||||
onOpenSettings={() => selectMailItem("Settings")}
|
||||
/>
|
||||
)}
|
||||
{active === "Trash" && (
|
||||
|
|
@ -278,7 +322,7 @@ export default function DashboardPage() {
|
|||
refreshKey={mailRefreshKey}
|
||||
account={account}
|
||||
onLogout={logout}
|
||||
onOpenSettings={() => selectItem("Settings")}
|
||||
onOpenSettings={() => selectMailItem("Settings")}
|
||||
/>
|
||||
)}
|
||||
{!["Inbox", "Outbox", "Trash"].includes(active) && (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue