Add announcement banner to explorer (#11210)
* Add announcement banner to explorer * Remove ^M and trailing spaces * Update Banner.tsx
This commit is contained in:
parent
234449c627
commit
f796adc5ea
|
@ -13,6 +13,7 @@ import TabbedPage from "components/TabbedPage";
|
||||||
import TopAccountsCard from "components/TopAccountsCard";
|
import TopAccountsCard from "components/TopAccountsCard";
|
||||||
import SupplyCard from "components/SupplyCard";
|
import SupplyCard from "components/SupplyCard";
|
||||||
import { pickCluster } from "utils/url";
|
import { pickCluster } from "utils/url";
|
||||||
|
import Banner from "components/Banner";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
@ -36,6 +37,8 @@ function App() {
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
<Banner />
|
||||||
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/supply">
|
<Route exact path="/supply">
|
||||||
<TabbedPage tab="Supply">
|
<TabbedPage tab="Supply">
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
import React from "react";
|
||||||
|
import { useCluster, Cluster } from "providers/cluster";
|
||||||
|
import { displayTimestamp } from "utils/date";
|
||||||
|
|
||||||
|
type Announcement = {
|
||||||
|
message: string;
|
||||||
|
estimate?: string;
|
||||||
|
start?: Date;
|
||||||
|
end?: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
const announcements = new Map<Cluster, Announcement>();
|
||||||
|
// announcements.set(Cluster.Devnet, {
|
||||||
|
// message: "Devnet API node is restarting",
|
||||||
|
// start: new Date("July 25, 2020 18:00:00 GMT+8:00"),
|
||||||
|
// estimate: "2 hours",
|
||||||
|
// });
|
||||||
|
// announcements.set(Cluster.MainnetBeta, {
|
||||||
|
// message: "Mainnet Beta upgrade in progress. Transactions are disabled",
|
||||||
|
// start: new Date("August 1, 2020 00:00:00 GMT+0:00"),
|
||||||
|
// end: new Date("August 3, 2020 00:00:00 GMT+0:00"),
|
||||||
|
// });
|
||||||
|
|
||||||
|
export default function Banner() {
|
||||||
|
const cluster = useCluster().cluster;
|
||||||
|
const announcement = announcements.get(cluster);
|
||||||
|
if (!announcement) return null;
|
||||||
|
const { message, start, end, estimate } = announcement;
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
if (end && now > end) return null;
|
||||||
|
if (start && now < start) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-danger text-white">
|
||||||
|
<div className="container">
|
||||||
|
<div className="d-flex flex-column align-items-center justify-content-center text-center py-3">
|
||||||
|
<h3 className="mb-3">
|
||||||
|
<span className="fe fe-alert-circle mr-2"></span>
|
||||||
|
{message}
|
||||||
|
</h3>
|
||||||
|
<hr className="text-gray-500 w-100 mt-0 mb-3 opacity-50" />
|
||||||
|
{estimate && (
|
||||||
|
<h5 className="font-sm text-gray-200">
|
||||||
|
<span className="text-uppercase">Estimated Duration: </span>
|
||||||
|
{estimate}
|
||||||
|
</h5>
|
||||||
|
)}
|
||||||
|
{start && (
|
||||||
|
<h5 className="font-sm text-gray-200">
|
||||||
|
<span className="text-uppercase">Started at: </span>
|
||||||
|
{displayTimestamp(start.getTime())}
|
||||||
|
</h5>
|
||||||
|
)}
|
||||||
|
{end && (
|
||||||
|
<h5 className="font-sm text-gray-200">
|
||||||
|
<span className="text-uppercase">End: </span>
|
||||||
|
{displayTimestamp(end.getTime())}
|
||||||
|
</h5>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -27,10 +27,7 @@ function Button({ expand }: { expand?: boolean }) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let spinnerClasses = "spinner-grow spinner-grow-sm mr-2";
|
const spinnerClasses = "spinner-grow spinner-grow-sm mr-2";
|
||||||
if (!expand) {
|
|
||||||
spinnerClasses += " text-warning";
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ClusterStatus.Connected:
|
case ClusterStatus.Connected:
|
||||||
|
|
|
@ -168,7 +168,7 @@ function StatusCard({ signature }: Props) {
|
||||||
<td>Timestamp</td>
|
<td>Timestamp</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
{info.timestamp !== "unavailable" ? (
|
{info.timestamp !== "unavailable" ? (
|
||||||
displayTimestamp(info.timestamp)
|
displayTimestamp(info.timestamp * 1000)
|
||||||
) : (
|
) : (
|
||||||
<InfoTooltip
|
<InfoTooltip
|
||||||
bottom
|
bottom
|
||||||
|
|
|
@ -27,7 +27,7 @@ export function StakeAccountCards({
|
||||||
function LockupCard({ stakeAccount }: { stakeAccount: StakeAccount }) {
|
function LockupCard({ stakeAccount }: { stakeAccount: StakeAccount }) {
|
||||||
const unixTimestamp = stakeAccount.meta?.lockup.unixTimestamp;
|
const unixTimestamp = stakeAccount.meta?.lockup.unixTimestamp;
|
||||||
if (unixTimestamp && unixTimestamp > 0) {
|
if (unixTimestamp && unixTimestamp > 0) {
|
||||||
const prettyTimestamp = displayTimestamp(unixTimestamp);
|
const prettyTimestamp = displayTimestamp(unixTimestamp * 1000);
|
||||||
return (
|
return (
|
||||||
<div className="alert alert-warning text-center">
|
<div className="alert alert-warning text-center">
|
||||||
<strong>Account is locked!</strong> Lockup expires on {prettyTimestamp}
|
<strong>Account is locked!</strong> Lockup expires on {prettyTimestamp}
|
||||||
|
|
|
@ -57,10 +57,6 @@ code {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.b-white {
|
|
||||||
background: $white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-exit {
|
.dropdown-exit {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
@ -70,10 +66,8 @@ code {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-outline-warning:hover {
|
.opacity-50 {
|
||||||
.spinner-grow {
|
opacity: 0.5;
|
||||||
color: $dark !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn.input-group {
|
.btn.input-group {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export function displayTimestamp(unixTimestamp: number): string {
|
export function displayTimestamp(unixTimestamp: number): string {
|
||||||
const expireDate = new Date(unixTimestamp * 1000);
|
const expireDate = new Date(unixTimestamp);
|
||||||
const dateString = new Intl.DateTimeFormat("en-US", {
|
const dateString = new Intl.DateTimeFormat("en-US", {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
|
|
Loading…
Reference in New Issue