657 lines
22 KiB
JavaScript
657 lines
22 KiB
JavaScript
import {
|
|
ChevronDown,
|
|
CircleDollarSign,
|
|
CircleEllipsis,
|
|
Clock3,
|
|
Crown,
|
|
FileEdit,
|
|
Globe,
|
|
Home,
|
|
Inbox,
|
|
ListChecks,
|
|
LogOut,
|
|
Mail,
|
|
Menu,
|
|
HandHelping,
|
|
Plug,
|
|
Send,
|
|
Settings,
|
|
Shield,
|
|
ShieldAlert,
|
|
Sparkles,
|
|
Star,
|
|
Trash2,
|
|
Users,
|
|
UsersRound,
|
|
UserRound,
|
|
X,
|
|
} from "lucide-react";
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import { getCurrentAccount, getMyCompanyDomain } from "../api";
|
|
import {
|
|
clearSession,
|
|
getAccessToken,
|
|
saveStoredAccount,
|
|
} from "../auth";
|
|
import Brand from "./Brand";
|
|
import MobileChrome from "./MobileChrome";
|
|
import { ShellModeContext } from "../shellMode";
|
|
import CompanyDnsSetup from "./CompanyDnsSetup";
|
|
import CompanyDomains from "./CompanyDomains";
|
|
import CompanyAdministrators from "./CompanyAdministrators";
|
|
import CompanyAliases from "./CompanyAliases";
|
|
import CompanyGroups from "./CompanyGroups";
|
|
import CompanyPeople from "./CompanyPeople";
|
|
import CompanySecurity from "./CompanySecurity";
|
|
import CompanyOverview from "./CompanyOverview";
|
|
import CompanyOverviewSetup, { isOrgSetupComplete } from "./CompanyOverviewSetup";
|
|
import ChangePasswordModal from "./ChangePasswordModal";
|
|
import ComposeDock, { triggerOpenCompose } from "./ComposeDock";
|
|
import HumanHandoff from "./HumanHandoff";
|
|
import AccountProfile from "./AccountProfile";
|
|
import AccountSettings from "./AccountSettings";
|
|
import MailboxView from "./MailboxView";
|
|
|
|
const mailItems = [
|
|
[Inbox, "Inbox", "unread"],
|
|
[Star, "Starred", "starred"],
|
|
[Clock3, "Snoozed"],
|
|
[Send, "Sent"],
|
|
[FileEdit, "Drafts", "drafts"],
|
|
[ShieldAlert, "Spam"],
|
|
[Trash2, "Trash"],
|
|
[Clock3, "Scheduled"],
|
|
];
|
|
|
|
const labels = [
|
|
["Important", "rose", "Important"],
|
|
["Projects", "violet", "Projects"],
|
|
["Clients", "blue", "Clients"],
|
|
["Finance", "amber", "Finance"],
|
|
["Personal", "green", "Personal"],
|
|
];
|
|
|
|
const agentItems = [
|
|
[HandHelping, "Human Handoff", "handoff"],
|
|
[Sparkles, "Ask Agent", "ask"],
|
|
[ListChecks, "Action Items", "actions"],
|
|
[Sparkles, "Summaries", "summaries"],
|
|
[Plug, "Integrations", "integrations"],
|
|
];
|
|
|
|
const companyNavItems = [
|
|
[Home, "Overview"],
|
|
[Users, "People"],
|
|
[UsersRound, "Groups"],
|
|
[Globe, "Domains"],
|
|
[CircleEllipsis, "Aliases"],
|
|
];
|
|
|
|
const manageNavItems = [
|
|
[Shield, "Security"],
|
|
[Crown, "Administrators"],
|
|
[CircleDollarSign, "Billing"],
|
|
[Settings, "Settings"],
|
|
];
|
|
|
|
function SidebarSection({ title, children, className = "" }) {
|
|
return (
|
|
<section className={`dashboard-sidebar-section ${className}`}>
|
|
<h2>{title}</h2>
|
|
{children}
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function NavBadge({ value, variant = "coral" }) {
|
|
if (!value || value <= 0) return null;
|
|
return <em className={variant === "neutral" ? "nav-badge-neutral" : "nav-badge-coral"}>{value}</em>;
|
|
}
|
|
|
|
export default function DashboardPage() {
|
|
const [account, setAccount] = useState(null);
|
|
const [companyDomain, setCompanyDomain] = useState(null);
|
|
const [needsDnsSetup, setNeedsDnsSetup] = useState(false);
|
|
const [domainError, setDomainError] = useState("");
|
|
const [active, setActive] = useState("Inbox");
|
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
|
const [sidebarExpanded, setSidebarExpanded] = useState(
|
|
() => typeof window !== "undefined" && window.matchMedia("(min-width: 1200px)").matches,
|
|
);
|
|
const [sheet, setSheet] = useState(null);
|
|
const [notice, setNotice] = useState("");
|
|
const [loading, setLoading] = useState(true);
|
|
const [mailRefreshKey, setMailRefreshKey] = useState(0);
|
|
const [lens, setLens] = useState("all");
|
|
const [agentNav, setAgentNav] = useState(null);
|
|
const [openThreadId, setOpenThreadId] = useState(null);
|
|
const [labelsExpanded, setLabelsExpanded] = useState(false);
|
|
const [companyActive, setCompanyActive] = useState(null);
|
|
const [mustChangePassword, setMustChangePassword] = useState(false);
|
|
const [mailStats, setMailStats] = useState({
|
|
unread: 0,
|
|
starred: 0,
|
|
important: 0,
|
|
drafts: 0,
|
|
actionItems: 0,
|
|
labels: {},
|
|
});
|
|
const handleStats = useCallback((stats) => setMailStats(stats), []);
|
|
|
|
useEffect(() => {
|
|
const token = getAccessToken();
|
|
if (!token) {
|
|
window.location.replace("/login");
|
|
return;
|
|
}
|
|
|
|
getCurrentAccount(token)
|
|
.then(async (currentAccount) => {
|
|
saveStoredAccount(currentAccount);
|
|
setAccount(currentAccount);
|
|
setMustChangePassword(Boolean(currentAccount.must_change_password));
|
|
if (currentAccount.account_type === "company" && currentAccount.is_domain_owner) {
|
|
try {
|
|
const domain = await getMyCompanyDomain(token);
|
|
setCompanyDomain(domain);
|
|
setNeedsDnsSetup(domain.status === "pending_dns");
|
|
} catch (error) {
|
|
setDomainError(error.message || "Could not load your company domain.");
|
|
}
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch(() => {
|
|
if (!getAccessToken()) return;
|
|
clearSession();
|
|
window.location.replace("/login");
|
|
});
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!account?.is_domain_owner || needsDnsSetup) return;
|
|
if (!isOrgSetupComplete(account.id)) {
|
|
setCompanyActive("Overview");
|
|
}
|
|
}, [account, needsDnsSetup]);
|
|
|
|
function logout() {
|
|
clearSession();
|
|
window.location.replace("/login");
|
|
}
|
|
|
|
function closeMobileMenu() {
|
|
if (window.matchMedia("(max-width: 767.98px)").matches) {
|
|
setMobileMenuOpen(false);
|
|
}
|
|
}
|
|
|
|
function toggleSidebar() {
|
|
if (window.matchMedia("(max-width: 767.98px)").matches) {
|
|
setMobileMenuOpen(false);
|
|
return;
|
|
}
|
|
setSidebarExpanded((open) => !open);
|
|
}
|
|
|
|
const sidebarClasses = [
|
|
"dashboard-sidebar",
|
|
mobileMenuOpen ? "open" : "",
|
|
sidebarExpanded ? "expanded" : "",
|
|
].filter(Boolean).join(" ");
|
|
|
|
function selectCompanyItem(label) {
|
|
setCompanyActive(label);
|
|
setAgentNav(null);
|
|
closeMobileMenu();
|
|
setSheet(null);
|
|
}
|
|
|
|
function selectMailItem(item) {
|
|
setCompanyActive(null);
|
|
setAgentNav(null);
|
|
if (item === "Starred") {
|
|
setActive("Inbox");
|
|
setLens("starred");
|
|
} else if (item === "Sent") {
|
|
setActive("Outbox");
|
|
setLens("all");
|
|
} else {
|
|
setActive(item);
|
|
setLens("all");
|
|
}
|
|
closeMobileMenu();
|
|
setSheet(null);
|
|
}
|
|
|
|
function selectLabel(name) {
|
|
setCompanyActive(null);
|
|
setAgentNav(null);
|
|
setActive("Inbox");
|
|
setLens(name);
|
|
closeMobileMenu();
|
|
setSheet(null);
|
|
}
|
|
|
|
function selectAgentItem(item, actionKey) {
|
|
setCompanyActive(null);
|
|
setActive("Inbox");
|
|
setLens("all");
|
|
setAgentNav(actionKey);
|
|
closeMobileMenu();
|
|
const compact = window.matchMedia("(max-width: 1199.98px)").matches;
|
|
setSheet(actionKey === "handoff" || !compact ? null : "agent");
|
|
}
|
|
|
|
function openAgentDestination(actionKey) {
|
|
setCompanyActive(null);
|
|
setActive("Inbox");
|
|
setLens("all");
|
|
setAgentNav(actionKey);
|
|
closeMobileMenu();
|
|
setSheet("agent");
|
|
}
|
|
|
|
function showMailboxForSheet() {
|
|
setCompanyActive(null);
|
|
setActive("Inbox");
|
|
setLens("all");
|
|
closeMobileMenu();
|
|
}
|
|
|
|
function openSheet(next) {
|
|
if (next === "agent" || next === "calendar" || next === "notes") {
|
|
showMailboxForSheet();
|
|
setAgentNav(next === "agent" ? "ask" : null);
|
|
}
|
|
setSheet(next);
|
|
}
|
|
|
|
function openCompose(context = null) {
|
|
triggerOpenCompose(context);
|
|
}
|
|
|
|
function openProfile() {
|
|
setCompanyActive(null);
|
|
setActive("Profile");
|
|
setAgentNav(null);
|
|
closeMobileMenu();
|
|
setSheet(null);
|
|
}
|
|
|
|
function updateAccount(next) {
|
|
setAccount(next);
|
|
saveStoredAccount(next);
|
|
}
|
|
|
|
function openExternalThread(threadId) {
|
|
setCompanyActive(null);
|
|
setActive("Inbox");
|
|
setLens("all");
|
|
setAgentNav(null);
|
|
setOpenThreadId(threadId);
|
|
}
|
|
|
|
function emailSent() {
|
|
setActive("Outbox");
|
|
setMailRefreshKey((key) => key + 1);
|
|
setNotice("Message accepted by the mail server. Delivery can take a few minutes — check spam if it does not arrive.");
|
|
window.setTimeout(() => setNotice(""), 4000);
|
|
}
|
|
|
|
if (loading || !account) {
|
|
return <main className="dashboard-loading"><Brand /><span>Opening your workspace…</span></main>;
|
|
}
|
|
|
|
if (account.account_type === "company" && domainError) {
|
|
return (
|
|
<main className="company-dns-setup">
|
|
<header className="company-dns-header">
|
|
<Brand />
|
|
<button type="button" onClick={logout}>Log out</button>
|
|
</header>
|
|
<section className="company-dns-card">
|
|
<p className="eyebrow">Company setup</p>
|
|
<h1>Domain not ready</h1>
|
|
<p className="form-error" role="alert">{domainError}</p>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
if (needsDnsSetup && companyDomain) {
|
|
return (
|
|
<CompanyDnsSetup
|
|
account={account}
|
|
domain={companyDomain}
|
|
onComplete={() => {
|
|
setCompanyDomain({ ...companyDomain, status: "active" });
|
|
setNeedsDnsSetup(false);
|
|
setCompanyActive("Overview");
|
|
}}
|
|
onLogout={logout}
|
|
/>
|
|
);
|
|
}
|
|
|
|
const workspaceLabel = account.account_type === "company" ? "Company" : "Individual";
|
|
const workspaceTitle = account.account_type === "company" && companyDomain
|
|
? companyDomain.domain_name
|
|
: "Personal workspace";
|
|
const isDomainOwner = account.account_type === "company" && account.is_domain_owner;
|
|
const isOrgOnboarding = isDomainOwner && !isOrgSetupComplete(account.id);
|
|
const mailActive = lens === "starred"
|
|
? "Starred"
|
|
: active === "Outbox"
|
|
? "Sent"
|
|
: labels.some(([name]) => lens === name)
|
|
? "Inbox"
|
|
: active;
|
|
|
|
return (
|
|
<ShellModeContext.Provider value={{ sheet, setSheet }}>
|
|
<div
|
|
className="dashboard"
|
|
data-sheet={sheet || undefined}
|
|
data-onboarding={isOrgOnboarding ? "true" : undefined}
|
|
>
|
|
<header className="dashboard-mobile-header">
|
|
<Brand forceHome />
|
|
<button aria-label="Open navigation" type="button" onClick={() => { setSheet(null); setMobileMenuOpen(true); }}>
|
|
<Menu size={21} />
|
|
</button>
|
|
</header>
|
|
|
|
{mobileMenuOpen && (
|
|
<button className="dashboard-scrim" aria-label="Close navigation" onClick={() => setMobileMenuOpen(false)} />
|
|
)}
|
|
<aside className={sidebarClasses}>
|
|
<div className="dashboard-brand-row">
|
|
<Brand forceHome />
|
|
<button
|
|
aria-label={(mobileMenuOpen || sidebarExpanded) ? "Collapse navigation" : "Expand navigation"}
|
|
type="button"
|
|
onClick={toggleSidebar}
|
|
>
|
|
{(mobileMenuOpen || sidebarExpanded) ? <X size={19} /> : <Menu size={19} />}
|
|
</button>
|
|
</div>
|
|
|
|
{!isOrgOnboarding && (
|
|
<button className="dashboard-compose" type="button" onClick={openCompose}>
|
|
<Mail size={16} strokeWidth={1.75} />
|
|
<span>Compose</span>
|
|
</button>
|
|
)}
|
|
|
|
<div className="dashboard-sidebar-scroll">
|
|
{isDomainOwner && (
|
|
<>
|
|
<SidebarSection title="Company" className="dashboard-sidebar-company dashboard-sidebar-first">
|
|
<nav aria-label="Company">
|
|
{companyNavItems.map(([ItemIcon, label]) => (
|
|
<button
|
|
className={`dashboard-nav-item dashboard-company-item${companyActive === label ? " active" : ""}`}
|
|
key={label}
|
|
type="button"
|
|
onClick={() => selectCompanyItem(label)}
|
|
>
|
|
<ItemIcon size={16} strokeWidth={1.75} />
|
|
<span>{label}</span>
|
|
</button>
|
|
))}
|
|
</nav>
|
|
</SidebarSection>
|
|
<SidebarSection title="Manage" className="dashboard-sidebar-manage">
|
|
<nav aria-label="Manage">
|
|
{manageNavItems.map(([ItemIcon, label]) => (
|
|
<button
|
|
className={`dashboard-nav-item dashboard-company-item${companyActive === label ? " active" : ""}`}
|
|
key={label}
|
|
type="button"
|
|
onClick={() => selectCompanyItem(label)}
|
|
>
|
|
<ItemIcon size={16} strokeWidth={1.75} />
|
|
<span>{label}</span>
|
|
</button>
|
|
))}
|
|
</nav>
|
|
</SidebarSection>
|
|
</>
|
|
)}
|
|
|
|
{!isOrgOnboarding && (
|
|
<SidebarSection title="Mail" className="dashboard-sidebar-mail">
|
|
<nav aria-label="Mail">
|
|
{mailItems.map(([ItemIcon, label, countKey]) => (
|
|
<button
|
|
className={`dashboard-nav-item${!companyActive && mailActive === label ? " active" : ""}`}
|
|
key={label}
|
|
type="button"
|
|
onClick={() => selectMailItem(label)}
|
|
>
|
|
<ItemIcon size={16} strokeWidth={1.75} />
|
|
<span>{label}</span>
|
|
<NavBadge value={countKey ? mailStats[countKey] : 0} />
|
|
</button>
|
|
))}
|
|
</nav>
|
|
</SidebarSection>
|
|
)}
|
|
|
|
{!isOrgOnboarding && (
|
|
<SidebarSection title="Labels" className="dashboard-sidebar-labels">
|
|
<nav aria-label="Labels">
|
|
{labels.map(([name, tone, countKey]) => (
|
|
<button
|
|
className={`dashboard-nav-item dashboard-label-item${!companyActive && lens === name ? " active" : ""}`}
|
|
key={name}
|
|
type="button"
|
|
onClick={() => selectLabel(name)}
|
|
>
|
|
<i className={`label-dot label-dot-${tone}`} />
|
|
<span>{name}</span>
|
|
<NavBadge variant="neutral" value={mailStats.labels?.[countKey]} />
|
|
</button>
|
|
))}
|
|
<button
|
|
type="button"
|
|
className="dashboard-nav-item dashboard-label-more"
|
|
onClick={() => setLabelsExpanded((open) => !open)}
|
|
>
|
|
<ChevronDown size={14} strokeWidth={1.75} className={labelsExpanded ? "open" : ""} />
|
|
<span>{labelsExpanded ? "Less" : "More"}</span>
|
|
</button>
|
|
</nav>
|
|
</SidebarSection>
|
|
)}
|
|
|
|
{!isOrgOnboarding && (
|
|
<SidebarSection title="Agent" className="dashboard-sidebar-agent">
|
|
<nav aria-label="Agent">
|
|
{agentItems.map(([ItemIcon, label, actionKey]) => (
|
|
<button
|
|
className={`dashboard-nav-item dashboard-agent-item${!companyActive && agentNav === actionKey ? " active" : ""}`}
|
|
key={label}
|
|
type="button"
|
|
onClick={() => selectAgentItem(label, actionKey)}
|
|
>
|
|
<ItemIcon size={16} strokeWidth={1.75} />
|
|
<span>{label}</span>
|
|
<NavBadge value={actionKey === "actions" ? mailStats.actionItems : 0} />
|
|
</button>
|
|
))}
|
|
</nav>
|
|
</SidebarSection>
|
|
)}
|
|
</div>
|
|
|
|
<div className="dashboard-profile">
|
|
{account.profile_picture_url ? (
|
|
<img src={account.profile_picture_url} alt="" className="dashboard-profile-photo" />
|
|
) : (
|
|
<span>{account.first_name[0]}{account.last_name[0]}</span>
|
|
)}
|
|
<div><strong>{account.first_name} {account.last_name}</strong><small>{account.email}</small></div>
|
|
<button aria-label="Open profile" title="Profile" type="button" onClick={openProfile}><UserRound size={17} /></button>
|
|
<button aria-label="Log out" title="Log out" type="button" onClick={logout}><LogOut size={17} /></button>
|
|
</div>
|
|
</aside>
|
|
|
|
<main className="dashboard-content">
|
|
{companyActive && !["Overview", "Domains", "People", "Groups", "Aliases", "Security", "Administrators", "Settings"].includes(companyActive) && (
|
|
<div className="dashboard-content-heading">
|
|
<div><p>{workspaceTitle}</p><h1>{companyActive}</h1></div>
|
|
<span className="dashboard-account-pill">{workspaceLabel}</span>
|
|
</div>
|
|
)}
|
|
{!companyActive && !["Inbox", "Outbox", "Trash", "Profile", "Settings"].includes(active) && (
|
|
<div className="dashboard-content-heading">
|
|
<div><p>{workspaceTitle}</p><h1>{active}</h1></div>
|
|
<span className="dashboard-account-pill">{workspaceLabel}</span>
|
|
</div>
|
|
)}
|
|
{!companyActive && active === "Inbox" && agentNav === "handoff" && (
|
|
<HumanHandoff account={account} onOpenExternal={openExternalThread} />
|
|
)}
|
|
{!companyActive && active === "Inbox" && agentNav !== "handoff" && (
|
|
<MailboxView
|
|
mailbox="inbox"
|
|
title="Inbox"
|
|
refreshKey={mailRefreshKey}
|
|
account={account}
|
|
lens={lens}
|
|
agentNav={agentNav}
|
|
initialThreadId={openThreadId}
|
|
onLogout={logout}
|
|
onOpenSettings={() => selectMailItem("Settings")}
|
|
onOpenProfile={openProfile}
|
|
onAccountUpdate={updateAccount}
|
|
onCompose={openCompose}
|
|
onStats={handleStats}
|
|
/>
|
|
)}
|
|
{!companyActive && active === "Outbox" && (
|
|
<MailboxView
|
|
mailbox="sent"
|
|
title="Sent"
|
|
refreshKey={mailRefreshKey}
|
|
account={account}
|
|
onLogout={logout}
|
|
onOpenSettings={() => selectMailItem("Settings")}
|
|
onOpenProfile={openProfile}
|
|
onAccountUpdate={updateAccount}
|
|
onCompose={openCompose}
|
|
/>
|
|
)}
|
|
{!companyActive && active === "Trash" && (
|
|
<MailboxView
|
|
mailbox="trash"
|
|
title="Trash"
|
|
refreshKey={mailRefreshKey}
|
|
account={account}
|
|
onLogout={logout}
|
|
onOpenSettings={() => selectMailItem("Settings")}
|
|
onOpenProfile={openProfile}
|
|
onAccountUpdate={updateAccount}
|
|
onCompose={openCompose}
|
|
/>
|
|
)}
|
|
{!companyActive && active === "Profile" && (
|
|
<AccountProfile account={account} onUpdated={updateAccount} />
|
|
)}
|
|
{companyActive === "Overview" && isDomainOwner && !isOrgSetupComplete(account.id) && (
|
|
<CompanyOverviewSetup
|
|
account={account}
|
|
companyDomain={companyDomain}
|
|
onComplete={() => {
|
|
setCompanyActive(null);
|
|
setActive("Inbox");
|
|
}}
|
|
/>
|
|
)}
|
|
{companyActive === "Overview" && isDomainOwner && isOrgSetupComplete(account.id) && (
|
|
<CompanyOverview
|
|
account={account}
|
|
companyDomain={companyDomain}
|
|
onNavigate={selectCompanyItem}
|
|
/>
|
|
)}
|
|
{companyActive === "Domains" && isDomainOwner && (
|
|
<CompanyDomains
|
|
account={account}
|
|
primaryDomainName={account.company_domain}
|
|
/>
|
|
)}
|
|
{companyActive === "People" && isDomainOwner && (
|
|
<CompanyPeople account={account} />
|
|
)}
|
|
{companyActive === "Groups" && isDomainOwner && (
|
|
<CompanyGroups account={account} />
|
|
)}
|
|
{companyActive === "Aliases" && isDomainOwner && (
|
|
<CompanyAliases account={account} />
|
|
)}
|
|
{companyActive === "Security" && isDomainOwner && (
|
|
<CompanySecurity />
|
|
)}
|
|
{companyActive === "Administrators" && isDomainOwner && (
|
|
<CompanyAdministrators account={account} />
|
|
)}
|
|
{companyActive && !["Overview", "Domains", "People", "Groups", "Aliases", "Security", "Administrators", "Settings"].includes(companyActive) && (
|
|
<section className="dashboard-empty dashboard-company-view">
|
|
<span><Sparkles size={24} /></span>
|
|
<h2>{companyActive}</h2>
|
|
<p>Company {companyActive.toLowerCase()} controls will appear here.</p>
|
|
</section>
|
|
)}
|
|
{(active === "Settings" || companyActive === "Settings") && (
|
|
<AccountSettings />
|
|
)}
|
|
{!companyActive && !["Inbox", "Outbox", "Trash", "Settings", "Profile"].includes(active) && (
|
|
<section className="dashboard-empty">
|
|
<span><Sparkles size={24} /></span>
|
|
<h2>{active} is ready for you</h2>
|
|
<p>Your personal mail and agent tools will appear here.</p>
|
|
</section>
|
|
)}
|
|
</main>
|
|
{notice && <div className="dashboard-notice" role="status">{notice}</div>}
|
|
{mustChangePassword && (
|
|
<ChangePasswordModal
|
|
account={account}
|
|
onComplete={(updated) => {
|
|
setAccount(updated);
|
|
setMustChangePassword(false);
|
|
saveStoredAccount(updated);
|
|
}}
|
|
/>
|
|
)}
|
|
{sheet && sheet !== "more" && (
|
|
<button className="shell-drawer-scrim" type="button" aria-label="Close panel" onClick={() => setSheet(null)} />
|
|
)}
|
|
{!isOrgOnboarding && (
|
|
<MobileChrome
|
|
sheet={sheet}
|
|
mailActive={!sheet && !companyActive && agentNav !== "handoff"}
|
|
account={account}
|
|
onMail={() => selectMailItem("Inbox")}
|
|
onAgent={() => openSheet("agent")}
|
|
onCompose={() => openCompose()}
|
|
onCalendar={() => openSheet("calendar")}
|
|
onMore={() => setSheet((current) => (current === "more" ? null : "more"))}
|
|
onClose={() => setSheet(null)}
|
|
onSettings={() => selectMailItem("Settings")}
|
|
onNotes={() => openSheet("notes")}
|
|
onHandoff={() => selectAgentItem("Human Handoff", "handoff")}
|
|
onActionItems={() => openAgentDestination("actions")}
|
|
onSummaries={() => openAgentDestination("summaries")}
|
|
onIntegrations={() => openAgentDestination("integrations")}
|
|
onLogout={logout}
|
|
/>
|
|
)}
|
|
<ComposeDock account={account} onSent={emailSent} agentOpen={!companyActive} />
|
|
</div>
|
|
</ShellModeContext.Provider>
|
|
);
|
|
}
|