ui improvements

This commit is contained in:
debu-2 2026-10-03 21:46:03 +05:30
parent cce9a8c9ba
commit 78aac5a925
7 changed files with 769 additions and 138 deletions

View file

@ -1,6 +1,8 @@
import {
Bot,
ChevronDown,
Clock3,
FileEdit,
Inbox,
ListFilter,
LogOut,
@ -11,11 +13,12 @@ import {
Settings,
ShieldAlert,
Sparkles,
Star,
Tags,
Trash2,
X,
} from "lucide-react";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { getCurrentAccount, getMyCompanyDomain } from "../api";
import Brand from "./Brand";
import CompanyDnsSetup from "./CompanyDnsSetup";
@ -23,12 +26,22 @@ import ComposeModal from "./ComposeModal";
import MailboxView from "./MailboxView";
const mailItems = [
[Inbox, "Inbox"],
[Send, "Outbox"],
[Inbox, "Inbox", "unread"],
[Star, "Starred", "starred"],
[Clock3, "Snoozed"],
[Send, "Sent"],
[FileEdit, "Drafts"],
[ShieldAlert, "Spam"],
[Trash2, "Trash"],
[Clock3, "Scheduled"],
[Settings, "Settings"],
];
const labels = [
["Important", "rose"],
["Projects", "violet"],
["Clients", "blue"],
["Finance", "amber"],
["Personal", "green"],
];
const agentItems = [
@ -36,6 +49,7 @@ const agentItems = [
[ListFilter, "Filters"],
[Sparkles, "Summary"],
[Plug, "Integration"],
[Settings, "Settings"],
];
function clearSession() {
@ -43,20 +57,21 @@ function clearSession() {
sessionStorage.removeItem("agmail_account");
}
function NavGroup({ icon: Icon, title, items, active, onSelect }) {
function NavGroup({ icon: Icon, title, items, active, counts, onSelect }) {
return (
<section className="dashboard-nav-group">
<h2><Icon size={15} />{title}</h2>
<h2><Icon size={13} />{title}</h2>
<nav aria-label={title}>
{items.map(([ItemIcon, label]) => (
{items.map(([ItemIcon, label, countKey]) => (
<button
className={active === label ? "active" : ""}
key={label}
onClick={() => onSelect(label)}
type="button"
>
<ItemIcon size={17} />
<ItemIcon size={16} />
<span>{label}</span>
{countKey && counts?.[countKey] > 0 && <em>{counts[countKey]}</em>}
</button>
))}
</nav>
@ -75,6 +90,10 @@ 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 handleStats = useCallback((stats) => setMailStats(stats), []);
useEffect(() => {
const token = sessionStorage.getItem("agmail_access_token");
@ -110,7 +129,19 @@ export default function DashboardPage() {
}
function selectItem(item) {
setActive(item);
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");
}
setMenuOpen(false);
}
@ -179,7 +210,30 @@ export default function DashboardPage() {
<button className="dashboard-compose" type="button" onClick={() => setComposeOpen(true)}>
<Mail size={17} />Compose
</button>
<NavGroup icon={Mail} title="Mail" items={mailItems} active={active} onSelect={selectItem} />
<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} />
<div className="dashboard-profile">
<span>{account.first_name[0]}{account.last_name[0]}</span>
@ -195,9 +249,38 @@ export default function DashboardPage() {
<span className="dashboard-account-pill">{workspaceLabel}</span>
</div>
)}
{active === "Inbox" && <MailboxView mailbox="inbox" title="Inbox" refreshKey={mailRefreshKey} />}
{active === "Outbox" && <MailboxView mailbox="sent" title="Sent" refreshKey={mailRefreshKey} />}
{active === "Trash" && <MailboxView mailbox="trash" title="Trash" refreshKey={mailRefreshKey} />}
{active === "Inbox" && (
<MailboxView
mailbox="inbox"
title="Inbox"
refreshKey={mailRefreshKey}
account={account}
lens={lens}
onLogout={logout}
onOpenSettings={() => selectItem("Settings")}
onStats={handleStats}
/>
)}
{active === "Outbox" && (
<MailboxView
mailbox="sent"
title="Sent"
refreshKey={mailRefreshKey}
account={account}
onLogout={logout}
onOpenSettings={() => selectItem("Settings")}
/>
)}
{active === "Trash" && (
<MailboxView
mailbox="trash"
title="Trash"
refreshKey={mailRefreshKey}
account={account}
onLogout={logout}
onOpenSettings={() => selectItem("Settings")}
/>
)}
{!["Inbox", "Outbox", "Trash"].includes(active) && (
<section className="dashboard-empty">
<span><Sparkles size={24} /></span>