ui enhancement company

This commit is contained in:
debu-2 2026-10-04 20:32:18 +05:30
parent cc3f3f3de5
commit c01914736b
14 changed files with 876 additions and 159 deletions

View file

@ -0,0 +1,158 @@
import { Crown, Search } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { listOrgMembers, updateOrgMemberRole } from "../api";
function initials(firstName, lastName) {
return `${firstName?.[0] || ""}${lastName?.[0] || ""}`.toUpperCase();
}
function roleLabel(member) {
if (member.is_domain_owner || member.org_role === "owner") return "Owner";
if (member.org_role === "admin") return "User Admin";
return "User";
}
export default function CompanyAdministrators({ account }) {
const token = sessionStorage.getItem("agmail_access_token");
const [members, setMembers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
const [search, setSearch] = useState("");
const [updatingId, setUpdatingId] = useState(null);
const loadMembers = useCallback(async () => {
setLoading(true);
setError("");
try {
const data = await listOrgMembers(token);
setMembers(data.items);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, [token]);
useEffect(() => {
loadMembers();
}, [loadMembers]);
const filteredMembers = useMemo(() => {
const query = search.trim().toLowerCase();
if (!query) return members;
return members.filter((member) => {
const haystack = `${member.first_name} ${member.last_name} ${member.email}`.toLowerCase();
return haystack.includes(query);
});
}, [members, search]);
async function handleRoleChange(member, nextRole) {
if (member.is_domain_owner || member.org_role === "owner") return;
if (member.id === account.id) return;
setUpdatingId(member.id);
setError("");
try {
const updated = await updateOrgMemberRole(member.id, { org_role: nextRole }, token);
setMembers((current) => current.map((item) => (
item.id === updated.id ? updated : item
)));
} catch (err) {
setError(err.message);
} finally {
setUpdatingId(null);
}
}
return (
<section className="company-people">
<header className="company-people-head">
<div>
<h1>Administrators</h1>
<p>Assign roles and control who can manage your organization.</p>
</div>
</header>
<div className="people-filters">
<label className="people-search">
<Search size={16} />
<input
value={search}
onChange={(event) => setSearch(event.target.value)}
placeholder="Search users…"
/>
</label>
</div>
{error && <p className="form-error" role="alert">{error}</p>}
<div className="people-table-wrap">
<table className="people-table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Status</th>
<th>Role</th>
</tr>
</thead>
<tbody>
{loading ? (
<tr>
<td colSpan={4} className="people-table-empty">Loading administrators…</td>
</tr>
) : filteredMembers.length === 0 ? (
<tr>
<td colSpan={4} className="people-table-empty">No users match your search.</td>
</tr>
) : (
filteredMembers.map((member) => {
const isOwner = member.is_domain_owner || member.org_role === "owner";
const isSelf = member.id === account.id;
const roleValue = isOwner ? "owner" : member.org_role;
return (
<tr key={member.id}>
<td>
<div className="people-name-cell">
<span className="people-avatar">{initials(member.first_name, member.last_name)}</span>
<span>
{member.first_name} {member.last_name}
{isOwner && (
<em className="admin-owner-badge">
<Crown size={12} /> Owner
</em>
)}
</span>
</div>
</td>
<td>{member.email}</td>
<td>{member.member_status}</td>
<td>
{isOwner || isSelf ? (
<span className="admin-role-readonly">{roleLabel(member)}</span>
) : (
<select
className="admin-role-select"
value={roleValue}
disabled={updatingId === member.id}
onChange={(event) => handleRoleChange(member, event.target.value)}
>
<option value="user">User</option>
<option value="admin">User Admin</option>
</select>
)}
</td>
</tr>
);
})
)}
</tbody>
</table>
</div>
<p className="admin-role-hint">
User Admins can manage people, groups, aliases, and security settings.
Only the domain owner can assign administrator roles.
</p>
</section>
);
}

View file

@ -1,5 +1,5 @@
import { ArrowRight, Check } from "lucide-react";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
const STEPS = [
{ id: 1, title: "Add domain", hint: "Use your company domain for email" },
@ -28,6 +28,8 @@ const COUNTRIES = [
"Other",
];
const EMAIL_LOCAL_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,62}[A-Za-z0-9])?$/;
function storageKey(accountId, suffix) {
return `agmail_org_${suffix}_${accountId}`;
}
@ -38,37 +40,126 @@ function loadStep(accountId) {
return 4;
}
function parseEmailLocal(email, domain) {
const normalized = String(email || "").toLowerCase();
const suffix = `@${domain}`;
if (normalized.endsWith(suffix)) {
return normalized.slice(0, -suffix.length);
}
const at = normalized.indexOf("@");
return at > 0 ? normalized.slice(0, at) : normalized;
}
function loadDetails(account, companyDomain) {
const domain = companyDomain?.domain_name || account.company_domain || "";
try {
const raw = localStorage.getItem(storageKey(account.id, "details"));
if (raw) return JSON.parse(raw);
if (raw) {
const saved = JSON.parse(raw);
return {
companyName: saved.companyName || "",
orgSize: saved.orgSize || "51-200 employees",
country: saved.country || "India",
contactName: saved.contactName || "",
emailLocal: saved.emailLocal || parseEmailLocal(saved.workEmail || account.email, domain),
};
}
} catch {
/* ignore */
}
return {
companyName: companyDomain?.domain_name?.split(".")[0] || "",
companyName: domain?.split(".")[0] || "",
orgSize: "51-200 employees",
country: "India",
contactName: `${account.first_name} ${account.last_name}`.trim(),
workEmail: account.email,
emailLocal: parseEmailLocal(account.email, domain),
};
}
function validateDetails(details) {
const errors = {};
if (!details.companyName.trim()) {
errors.companyName = "Please enter your company name.";
}
if (!details.contactName.trim()) {
errors.contactName = "Please enter your name.";
}
const local = details.emailLocal.trim();
if (!local) {
errors.emailLocal = "Please enter your admin email.";
} else if (!EMAIL_LOCAL_PATTERN.test(local)) {
errors.emailLocal = "Enter a valid email address before @.";
}
return errors;
}
export function isOrgSetupComplete(accountId) {
return localStorage.getItem(storageKey(accountId, "complete")) === "1";
}
function RequiredLabel({ children }) {
return (
<span className="org-setup-label-text">
{children}
<span className="org-setup-required" aria-hidden="true">*</span>
</span>
);
}
function SetupField({
label,
error,
children,
}) {
return (
<label className={`org-setup-field${error ? " has-error" : ""}`}>
{label}
{children}
{error && <span className="org-setup-field-error" role="alert">{error}</span>}
</label>
);
}
export default function CompanyOverviewSetup({ account, companyDomain, onComplete }) {
const companyDomainName = companyDomain?.domain_name || account.company_domain || "";
const [step, setStep] = useState(() => loadStep(account.id));
const [details, setDetails] = useState(() => loadDetails(account, companyDomain));
const [fieldErrors, setFieldErrors] = useState({});
const [submitAttempted, setSubmitAttempted] = useState(false);
useEffect(() => {
localStorage.setItem(storageKey(account.id, "step"), String(step));
}, [account.id, step]);
const formValid = useMemo(() => Object.keys(validateDetails(details)).length === 0, [details]);
function updateField(field, value) {
setDetails((current) => {
const next = { ...current, [field]: value };
if (submitAttempted || fieldErrors[field]) {
const nextErrors = validateDetails(next);
setFieldErrors((errors) => ({
...errors,
[field]: nextErrors[field],
}));
}
return next;
});
}
function saveDetails(event) {
event.preventDefault();
localStorage.setItem(storageKey(account.id, "details"), JSON.stringify(details));
setSubmitAttempted(true);
const errors = validateDetails(details);
setFieldErrors(errors);
if (Object.keys(errors).length > 0) {
return;
}
const payload = {
...details,
workEmail: `${details.emailLocal.trim().toLowerCase()}@${companyDomainName}`,
};
localStorage.setItem(storageKey(account.id, "details"), JSON.stringify(payload));
setStep(5);
}
@ -87,17 +178,21 @@ export default function CompanyOverviewSetup({ account, companyDomain, onComplet
<div className="org-setup-layout">
<ol className="org-setup-steps" aria-label="Setup progress">
{STEPS.map((item) => {
{STEPS.map((item, index) => {
const complete = item.id < step || (item.id <= 3);
const active = item.id === step;
const isLast = index === STEPS.length - 1;
return (
<li
key={item.id}
className={`org-setup-step${complete ? " complete" : ""}${active ? " active" : ""}`}
>
<span className="org-setup-step-mark" aria-hidden="true">
{complete ? <Check size={14} strokeWidth={2.5} /> : item.id}
</span>
<div className="org-setup-step-indicator">
<span className="org-setup-step-mark" aria-hidden="true">
{complete ? <Check size={14} strokeWidth={2.5} /> : item.id}
</span>
{!isLast && <span className="org-setup-step-connector" aria-hidden="true" />}
</div>
<span className="org-setup-step-copy">
<strong>{item.title}</strong>
<small>{item.hint}</small>
@ -110,105 +205,118 @@ export default function CompanyOverviewSetup({ account, companyDomain, onComplet
<div className="org-setup-panel">
{step === 4 && (
<>
<h2>Company details</h2>
<p className="org-setup-section-label">Organization information</p>
<form className="org-setup-form" onSubmit={saveDetails}>
<label>
Company name <span aria-hidden="true">*</span>
<input
required
value={details.companyName}
onChange={(event) => setDetails((current) => ({
...current,
companyName: event.target.value,
}))}
placeholder="Acme Pvt Ltd"
/>
</label>
<label>
Organization size <span aria-hidden="true">*</span>
<select
required
value={details.orgSize}
onChange={(event) => setDetails((current) => ({
...current,
orgSize: event.target.value,
}))}
<div className="org-setup-panel-intro">
<h2>Company details</h2>
<p className="org-setup-section-label">Tell us a little about your organization.</p>
</div>
<form className="org-setup-form" onSubmit={saveDetails} noValidate>
<div className="org-setup-form-shell">
<SetupField
label={<RequiredLabel>Company name</RequiredLabel>}
error={fieldErrors.companyName}
>
{ORG_SIZES.map((size) => (
<option key={size} value={size}>{size}</option>
))}
</select>
</label>
<label>
Country <span aria-hidden="true">*</span>
<select
required
value={details.country}
onChange={(event) => setDetails((current) => ({
...current,
country: event.target.value,
}))}
<input
value={details.companyName}
onChange={(event) => updateField("companyName", event.target.value)}
placeholder="Acme Pvt Ltd"
aria-invalid={Boolean(fieldErrors.companyName)}
/>
</SetupField>
<div className="org-setup-form-row">
<SetupField
label={<RequiredLabel>Organization size</RequiredLabel>}
error={fieldErrors.orgSize}
>
<select
value={details.orgSize}
onChange={(event) => updateField("orgSize", event.target.value)}
>
{ORG_SIZES.map((size) => (
<option key={size} value={size}>{size}</option>
))}
</select>
</SetupField>
<SetupField
label={<RequiredLabel>Country</RequiredLabel>}
error={fieldErrors.country}
>
<select
value={details.country}
onChange={(event) => updateField("country", event.target.value)}
>
{COUNTRIES.map((country) => (
<option key={country} value={country}>{country}</option>
))}
</select>
</SetupField>
</div>
<SetupField
label={<RequiredLabel>Your name</RequiredLabel>}
error={fieldErrors.contactName}
>
{COUNTRIES.map((country) => (
<option key={country} value={country}>{country}</option>
))}
</select>
</label>
<label>
Your name <span aria-hidden="true">*</span>
<input
required
value={details.contactName}
onChange={(event) => setDetails((current) => ({
...current,
contactName: event.target.value,
}))}
/>
</label>
<label>
Your work email <span aria-hidden="true">*</span>
<input
required
type="email"
value={details.workEmail}
onChange={(event) => setDetails((current) => ({
...current,
workEmail: event.target.value,
}))}
/>
</label>
<div className="org-setup-actions">
<button type="submit" className="button button-purple">
Continue <ArrowRight size={16} />
</button>
<input
value={details.contactName}
onChange={(event) => updateField("contactName", event.target.value)}
aria-invalid={Boolean(fieldErrors.contactName)}
/>
</SetupField>
<SetupField
label={<RequiredLabel>Your admin email</RequiredLabel>}
error={fieldErrors.emailLocal}
>
<div className="org-setup-email-field">
<input
value={details.emailLocal}
onChange={(event) => updateField("emailLocal", event.target.value)}
placeholder="suyash"
aria-invalid={Boolean(fieldErrors.emailLocal)}
/>
<span>@{companyDomainName}</span>
</div>
<small className="org-setup-field-hint">
This becomes your login address on your company domain.
</small>
</SetupField>
<div className="org-setup-actions">
<button
type="submit"
className="button button-purple org-setup-submit"
disabled={!formValid}
>
Continue <ArrowRight size={16} />
</button>
</div>
</div>
</form>
</>
)}
{step === 5 && (
<>
<div className="org-setup-form-shell">
<h2>Add employees</h2>
<p className="org-setup-lead">
Invite teammates to <strong>{companyDomain?.domain_name}</strong>. You can add people now or skip and do this later from People.
Invite teammates to <strong>{companyDomainName}</strong>. You can add people now or skip and do this later from People.
</p>
<div className="org-setup-placeholder">
Employee invites will be available here soon.
</div>
<div className="org-setup-actions">
<button type="button" className="button button-purple" onClick={() => setStep(6)}>
<button type="button" className="button button-purple org-setup-submit" onClick={() => setStep(6)}>
Continue <ArrowRight size={16} />
</button>
</div>
</>
</div>
)}
{step === 6 && (
<>
<div className="org-setup-form-shell">
<h2>Finish setup</h2>
<p className="org-setup-lead">
Domain <strong>{companyDomain?.domain_name}</strong> is connected. You&apos;re ready to use AGMail.
Domain <strong>{companyDomainName}</strong> is connected. You&apos;re ready to use AGMail.
</p>
<ul className="org-setup-summary">
<li><Check size={14} /> Domain added and verified</li>
@ -216,11 +324,11 @@ export default function CompanyOverviewSetup({ account, companyDomain, onComplet
<li><Check size={14} /> Organization details saved</li>
</ul>
<div className="org-setup-actions">
<button type="button" className="button button-purple" onClick={finishSetup}>
<button type="button" className="button button-purple org-setup-submit" onClick={finishSetup}>
Go to inbox <ArrowRight size={16} />
</button>
</div>
</>
</div>
)}
</div>
</div>

View file

@ -0,0 +1,151 @@
import { useCallback, useEffect, useState } from "react";
import { getOrgSecurity, updateOrgSecurity } from "../api";
const SESSION_TIMEOUTS = [
{ value: 15, label: "15 minutes" },
{ value: 30, label: "30 minutes" },
{ value: 60, label: "1 hour" },
{ value: 120, label: "2 hours" },
{ value: 480, label: "8 hours" },
{ value: 1440, label: "24 hours" },
];
function ToggleRow({ title, description, checked, disabled, onChange }) {
return (
<div className="security-setting-row">
<div>
<strong>{title}</strong>
<p>{description}</p>
</div>
<label className="security-toggle">
<input
type="checkbox"
checked={checked}
disabled={disabled}
onChange={(event) => onChange(event.target.checked)}
/>
<span aria-hidden="true" />
</label>
</div>
);
}
export default function CompanySecurity() {
const token = sessionStorage.getItem("agmail_access_token");
const [settings, setSettings] = useState(null);
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [error, setError] = useState("");
const [notice, setNotice] = useState("");
const loadSettings = useCallback(async () => {
setLoading(true);
setError("");
try {
const data = await getOrgSecurity(token);
setSettings(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, [token]);
useEffect(() => {
loadSettings();
}, [loadSettings]);
async function savePatch(patch) {
setSaving(true);
setError("");
setNotice("");
try {
const data = await updateOrgSecurity(patch, token);
setSettings(data);
setNotice("Security settings saved.");
window.setTimeout(() => setNotice(""), 2500);
} catch (err) {
setError(err.message);
} finally {
setSaving(false);
}
}
function updateToggle(field, value) {
setSettings((current) => ({ ...current, [field]: value }));
savePatch({ [field]: value });
}
function updateTimeout(value) {
const minutes = Number(value);
setSettings((current) => ({ ...current, session_timeout_minutes: minutes }));
savePatch({ session_timeout_minutes: minutes });
}
return (
<section className="company-people company-security">
<header className="company-people-head">
<div>
<h1>Security</h1>
<p>Protect your organization and manage access.</p>
</div>
</header>
{error && <p className="form-error" role="alert">{error}</p>}
{notice && <p className="security-notice" role="status">{notice}</p>}
{loading || !settings ? (
<p className="people-table-empty">Loading security settings…</p>
) : (
<>
<div className="security-panel">
<h2>Authentication</h2>
<ToggleRow
title="Require strong passwords"
description="Minimum 8 characters with numbers and symbols."
checked={settings.require_strong_passwords}
disabled={saving}
onChange={(value) => updateToggle("require_strong_passwords", value)}
/>
<ToggleRow
title="Require MFA for administrators"
description="Recommended for better security."
checked={settings.require_mfa_admins}
disabled={saving}
onChange={(value) => updateToggle("require_mfa_admins", value)}
/>
<ToggleRow
title="Require MFA for all users"
description="Users will be prompted to set up MFA on first login."
checked={settings.require_mfa_all_users}
disabled={saving}
onChange={(value) => updateToggle("require_mfa_all_users", value)}
/>
</div>
<div className="security-panel">
<h2>Session timeout</h2>
<div className="security-setting-row">
<div>
<strong>Automatically sign out inactive users</strong>
<p>Users are signed out after a period of inactivity.</p>
</div>
<select
className="security-timeout-select"
value={settings.session_timeout_minutes}
disabled={saving}
onChange={(event) => updateTimeout(event.target.value)}
>
{SESSION_TIMEOUTS.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
</div>
</>
)}
</section>
);
}

View file

@ -29,9 +29,11 @@ import { getCurrentAccount, getMyCompanyDomain } from "../api";
import Brand from "./Brand";
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 CompanyOverviewSetup, { isOrgSetupComplete } from "./CompanyOverviewSetup";
import ComposeModal from "./ComposeModal";
import MailboxView from "./MailboxView";
@ -62,12 +64,15 @@ const agentItems = [
[Plug, "Integrations", "integrations"],
];
const companyItems = [
const companyNavItems = [
[Home, "Overview"],
[Users, "People"],
[UsersRound, "Groups"],
[Globe, "Domains"],
[CircleEllipsis, "Aliases"],
];
const manageNavItems = [
[Shield, "Security"],
[Crown, "Administrators"],
[CircleDollarSign, "Billing"],
@ -244,6 +249,7 @@ export default function DashboardPage() {
? 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"
@ -268,54 +274,76 @@ export default function DashboardPage() {
<button aria-label="Close navigation" type="button" onClick={() => setMenuOpen(false)}><X size={19} /></button>
</div>
<div className="dashboard-compose-wrap">
<button className="dashboard-compose" type="button" onClick={() => setComposeOpen(true)}>
<span className="dashboard-compose-main">
<Mail size={16} strokeWidth={1.75} />
<span>Compose</span>
</span>
</button>
<button className="dashboard-compose-menu" type="button" aria-label="Compose options">
<ChevronDown size={14} strokeWidth={1.75} />
</button>
</div>
{!isOrgOnboarding && (
<div className="dashboard-compose-wrap">
<button className="dashboard-compose" type="button" onClick={() => setComposeOpen(true)}>
<span className="dashboard-compose-main">
<Mail size={16} strokeWidth={1.75} />
<span>Compose</span>
</span>
</button>
<button className="dashboard-compose-menu" type="button" aria-label="Compose options">
<ChevronDown size={14} strokeWidth={1.75} />
</button>
</div>
)}
<div className="dashboard-sidebar-scroll">
{isDomainOwner && (
<SidebarSection title="Company" className="dashboard-sidebar-company dashboard-sidebar-first">
<nav aria-label="Company">
{companyItems.map(([ItemIcon, label]) => (
<>
<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 dashboard-company-item${companyActive === label ? " active" : ""}`}
className={`dashboard-nav-item${!companyActive && mailActive === label ? " active" : ""}`}
key={label}
type="button"
onClick={() => selectCompanyItem(label)}
onClick={() => selectMailItem(label)}
>
<ItemIcon size={16} strokeWidth={1.75} />
<span>{label}</span>
<NavBadge value={countKey ? mailStats[countKey] : 0} />
</button>
))}
</nav>
</SidebarSection>
)}
<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]) => (
@ -340,7 +368,9 @@ export default function DashboardPage() {
</button>
</nav>
</SidebarSection>
)}
{!isOrgOnboarding && (
<SidebarSection title="Agent" className="dashboard-sidebar-agent">
<nav aria-label="Agent">
{agentItems.map(([ItemIcon, label, actionKey]) => (
@ -357,6 +387,7 @@ export default function DashboardPage() {
))}
</nav>
</SidebarSection>
)}
</div>
<div className="dashboard-profile">
@ -367,7 +398,7 @@ export default function DashboardPage() {
</aside>
<main className="dashboard-content">
{companyActive && !["Overview", "Domains", "People", "Groups", "Aliases"].includes(companyActive) && (
{companyActive && !["Overview", "Domains", "People", "Groups", "Aliases", "Security", "Administrators"].includes(companyActive) && (
<div className="dashboard-content-heading">
<div><p>{workspaceTitle}</p><h1>{companyActive}</h1></div>
<span className="dashboard-account-pill">{workspaceLabel}</span>
@ -437,7 +468,13 @@ export default function DashboardPage() {
{companyActive === "Aliases" && isDomainOwner && (
<CompanyAliases account={account} />
)}
{companyActive && !["Overview", "Domains", "People", "Groups", "Aliases"].includes(companyActive) && (
{companyActive === "Security" && isDomainOwner && (
<CompanySecurity />
)}
{companyActive === "Administrators" && isDomainOwner && (
<CompanyAdministrators account={account} />
)}
{companyActive && !["Overview", "Domains", "People", "Groups", "Aliases", "Security", "Administrators"].includes(companyActive) && (
<section className="dashboard-empty dashboard-company-view">
<span><Sparkles size={24} /></span>
<h2>{companyActive}</h2>