public render(): ReactNode {
const { className } = this.props;
const { section } = this.state;
return (
<section className={classNames("dashboard", className)}>
<header className="dashboard__header">
<div>
<div className="dashboard__label">Workspace</div>
<h2 className="dashboard__title">Operations</h2>
<p className="dashboard__subtitle">
Metrics, activity and system status
</p>
</div>
<div className="dashboard__tabs">
{this.renderTab("overview", "Overview")}
{this.renderTab("activity", "Activity")}
{this.renderTab("reports", "Reports")}
</div>
</header>
<div className="dashboard__layout">
<div className="dashboard__main">
{section === "overview" && this.renderOverview()}
{section === "activity" && this.renderActivity()}
{section === "reports" && this.renderReports()}
</div>
<aside className="dashboard__side">
{this.renderHealth()}
{this.renderProgress()}
</aside>
</div>
</section>
);
}
private renderTab(section: IDashboardState["section"], label: string): ReactNode {
return (
<button
className={classNames("dashboard__tab", {
"is-active": this.state.section === section,
})}
onClick={() => this.setState({ section })}
>
{label}
</button>
);
}
private renderOverview(): ReactNode {
return (
<div className="dashboard-grid">
<div className="dashboard-cards">
{this._cards.map((c) => (
<div key={c.id} className="dashboard-card">
<div className="dashboard-card__title">{c.title}</div>
<div className="dashboard-card__value">{c.value}</div>
{c.delta && (
<div
className={classNames("dashboard-card__delta", {
"is-success": c.tone === "success",
"is-warning": c.tone === "warning",
"is-danger": c.tone === "danger",
})}
>
{c.delta}
</div>
)}
</div>
))}
</div>
<div className="panel">
<div className="panel__header">
<h3>Performance</h3>
</div>
<div className="chart">
<div className="chart__bars">
{[36, 62, 48, 74, 57, 83, 68].map((h, i) => (
<span key={i} style={{ height: `${h}%` }} />
))}
</div>
</div>
</div>
</div>
);
}
private renderActivity(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>Recent Activity</h3>
</div>
<div className="activity">
{this._activity.map((a) => (
<div key={a.id} className="activity__item">
<span
className={classNames("activity__dot", {
"is-done": a.status === "done",
"is-active": a.status === "active",
"is-waiting": a.status === "waiting",
})}
/>
<div>
<div className="activity__text">{a.label}</div>
<div className="activity__time">{a.time}</div>
</div>
</div>
))}
</div>
</div>
);
}
private renderReports(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>Reports</h3>
</div>
{[
"Monthly revenue",
"User acquisition",
"Quarterly review",
].map((r) => (
<div key={r} className="report">
<span>{r}</span>
<button className="link">Open</button>
</div>
))}
</div>
);
}
private renderHealth(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>System</h3>
</div>
{[
["API", "ok"],
["Queue", "delay"],
["Storage", "ok"],
].map(([label, state]) => (
<div key={label} className="health">
<span>{label}</span>
<span className={`badge badge--${state}`}>
{state === "ok" ? "Stable" : "Delayed"}
</span>
</div>
))}
</div>
);
}
private renderProgress(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>Progress</h3>
</div>
{[72, 48].map((v, i) => (
<div key={i} className="progress">
<div className="progress__label">
<span>{i === 0 ? "Quarter" : "Migration"}</span>
<strong>{v}%</strong>
</div>
<div className="progress__bar">
<div style={{ width: `${v}%` }} />
</div>
</div>
))}
</div>
);
}
}
public render(): ReactNode {
const { className } = this.props;
const { section } = this.state;
return (
<section className={classNames("dashboard", className)}>
<header className="dashboard__header">
<div>
<div className="dashboard__label">Workspace</div>
<h2 className="dashboard__title">Operations</h2>
<p className="dashboard__subtitle">
Metrics, activity and system status
</p>
</div>
<div className="dashboard__tabs">
{this.renderTab("overview", "Overview")}
{this.renderTab("activity", "Activity")}
{this.renderTab("reports", "Reports")}
</div>
</header>
<div className="dashboard__layout">
<div className="dashboard__main">
{section === "overview" && this.renderOverview()}
{section === "activity" && this.renderActivity()}
{section === "reports" && this.renderReports()}
</div>
<aside className="dashboard__side">
{this.renderHealth()}
{this.renderProgress()}
</aside>
</div>
</section>
);
}
private renderTab(section: IDashboardState["section"], label: string): ReactNode {
return (
<button
className={classNames("dashboard__tab", {
"is-active": this.state.section === section,
})}
onClick={() => this.setState({ section })}
>
{label}
</button>
);
}
private renderOverview(): ReactNode {
return (
<div className="dashboard-grid">
<div className="dashboard-cards">
{this._cards.map((c) => (
<div key={c.id} className="dashboard-card">
<div className="dashboard-card__title">{c.title}</div>
<div className="dashboard-card__value">{c.value}</div>
{c.delta && (
<div
className={classNames("dashboard-card__delta", {
"is-success": c.tone === "success",
"is-warning": c.tone === "warning",
"is-danger": c.tone === "danger",
})}
>
{c.delta}
</div>
)}
</div>
))}
</div>
<div className="panel">
<div className="panel__header">
<h3>Performance</h3>
</div>
<div className="chart">
<div className="chart__bars">
{[36, 62, 48, 74, 57, 83, 68].map((h, i) => (
<span key={i} style={{ height: `${h}%` }} />
))}
</div>
</div>
</div>
</div>
);
}
private renderActivity(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>Recent Activity</h3>
</div>
<div className="activity">
{this._activity.map((a) => (
<div key={a.id} className="activity__item">
<span
className={classNames("activity__dot", {
"is-done": a.status === "done",
"is-active": a.status === "active",
"is-waiting": a.status === "waiting",
})}
/>
<div>
<div className="activity__text">{a.label}</div>
<div className="activity__time">{a.time}</div>
</div>
</div>
))}
</div>
</div>
);
}
private renderReports(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>Reports</h3>
</div>
{[
"Monthly revenue",
"User acquisition",
"Quarterly review",
].map((r) => (
<div key={r} className="report">
<span>{r}</span>
<button className="link">Open</button>
</div>
))}
</div>
);
}
private renderHealth(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>System</h3>
</div>
{[
["API", "ok"],
["Queue", "delay"],
["Storage", "ok"],
].map(([label, state]) => (
<div key={label} className="health">
<span>{label}</span>
<span className={`badge badge--${state}`}>
{state === "ok" ? "Stable" : "Delayed"}
</span>
</div>
))}
</div>
);
}
private renderProgress(): ReactNode {
return (
<div className="panel">
<div className="panel__header">
<h3>Progress</h3>
</div>
{[72, 48].map((v, i) => (
<div key={i} className="progress">
<div className="progress__label">
<span>{i === 0 ? "Quarter" : "Migration"}</span>
<strong>{v}%</strong>
</div>
<div className="progress__bar">
<div style={{ width: `${v}%` }} />
</div>
</div>
))}
</div>
);
}
}