Balance (SOL) |
diff --git a/explorer/src/components/Navbar.tsx b/explorer/src/components/Navbar.tsx
index 92c22feb03..116a9e7658 100644
--- a/explorer/src/components/Navbar.tsx
+++ b/explorer/src/components/Navbar.tsx
@@ -1,17 +1,9 @@
import React from "react";
import Logo from "img/logos-solana/light-explorer-logo.svg";
-import { Location } from "history";
-import { pickCluster } from "utils/url";
+import { clusterPath } from "utils/url";
import { Link, NavLink } from "react-router-dom";
import { ClusterStatusButton } from "components/ClusterStatusButton";
-const clusterPath = (pathname: string) => {
- return (location: Location) => ({
- ...pickCluster(location),
- pathname,
- });
-};
-
export default function Navbar() {
// TODO: use `collapsing` to animate collapsible navbar
const [collapse, setCollapse] = React.useState(false);
@@ -31,11 +23,15 @@ export default function Navbar() {
-
+
-
- Cluster Status
+ Cluster Stats
-
diff --git a/explorer/src/components/SearchBar.tsx b/explorer/src/components/SearchBar.tsx
new file mode 100644
index 0000000000..7c0720f213
--- /dev/null
+++ b/explorer/src/components/SearchBar.tsx
@@ -0,0 +1,92 @@
+import React from "react";
+import bs58 from "bs58";
+import { useHistory, useLocation } from "react-router-dom";
+import Select, { InputActionMeta, ActionMeta, ValueType } from "react-select";
+import StateManager from "react-select";
+
+export function SearchBar() {
+ const [search, setSearch] = React.useState("");
+ const selectRef = React.useRef | null>(null);
+ const history = useHistory();
+ const location = useLocation();
+
+ const onChange = (
+ { value: pathname }: ValueType,
+ meta: ActionMeta
+ ) => {
+ if (meta.action === "select-option") {
+ history.push({ ...location, pathname });
+ setSearch("");
+ }
+ };
+
+ const onInputChange = (value: string, { action }: InputActionMeta) => {
+ if (action === "input-change") setSearch(value);
+ };
+
+ const options = ((searchValue: string) => {
+ try {
+ const decoded = bs58.decode(searchValue);
+ if (decoded.length === 32) {
+ return [
+ {
+ label: "Account",
+ options: [
+ {
+ label: searchValue,
+ value: "/address/" + searchValue,
+ },
+ ],
+ },
+ ];
+ } else if (decoded.length === 64) {
+ return [
+ {
+ label: "Transaction",
+ options: [
+ {
+ label: searchValue,
+ value: "/tx/" + searchValue,
+ },
+ ],
+ },
+ ];
+ }
+ } catch (err) {}
+ return [];
+ })(search);
+
+ const resetValue = "" as any;
+ return (
+
+
+
+
+
+
+ );
+}
+
+function DropdownIndicator() {
+ return (
+
+
+
+ );
+}
diff --git a/explorer/src/components/StatsCard.tsx b/explorer/src/components/StatsCard.tsx
index fd1a4a62f6..b1ddc504d5 100644
--- a/explorer/src/components/StatsCard.tsx
+++ b/explorer/src/components/StatsCard.tsx
@@ -19,7 +19,7 @@ export default function StatsCard() {
- Live Cluster Status
+ Live Cluster Stats
diff --git a/explorer/src/components/TransactionDetails.tsx b/explorer/src/components/TransactionDetails.tsx
index 1d1ddda495..a528ba83b9 100644
--- a/explorer/src/components/TransactionDetails.tsx
+++ b/explorer/src/components/TransactionDetails.tsx
@@ -36,13 +36,11 @@ export default function TransactionDetails({ signature }: Props) {
}, [signature]); // eslint-disable-line react-hooks/exhaustive-deps
return (
-
+
- Transaction
-
- {signature}
-
+ Details
+ Transaction
@@ -103,7 +101,7 @@ function StatusCard({ signature }: Props) {
return (
- Status
+ Overview
+
+ Signature |
+
+
+ {signature}
+
+ |
+
+
Result |
{renderResult()} |
diff --git a/explorer/src/providers/stats/solanaBeach.tsx b/explorer/src/providers/stats/solanaBeach.tsx
index cd76469243..56c473c63a 100644
--- a/explorer/src/providers/stats/solanaBeach.tsx
+++ b/explorer/src/providers/stats/solanaBeach.tsx
@@ -1,15 +1,7 @@
import React from "react";
import io from "socket.io-client";
-import {
- object,
- number,
- is,
- StructType,
- array,
- nullable,
- any,
-} from "superstruct";
+import { object, number, is, StructType, any } from "superstruct";
import { useCluster, Cluster } from "providers/cluster";
// TODO: use `partial` when it is fixed
@@ -51,11 +43,7 @@ export const PERF_UPDATE_SEC = 5;
// https://github.com/ianstormtaylor/superstruct/issues/405
const PerformanceInfo = object({
avgTPS: number(),
- perfHistory: object({
- s: array(nullable(number())),
- m: array(nullable(number())),
- l: array(nullable(number())),
- }),
+ perfHistory: any(),
totalTransactionCount: number(),
});
diff --git a/explorer/src/scss/_solana.scss b/explorer/src/scss/_solana.scss
index 9165072066..ae748b9c06 100644
--- a/explorer/src/scss/_solana.scss
+++ b/explorer/src/scss/_solana.scss
@@ -150,3 +150,16 @@ h4.slot-pill {
.line-height-md {
line-height: 1.5rem;
}
+
+.search-indicator {
+ color: hsl(0,0%,60%);
+ display: flex;
+ padding: 8px 10px;
+ transition: color 150ms;
+ box-sizing: border-box;
+ cursor: pointer;
+
+ &:hover {
+ color: hsl(0,0%,40%);
+ }
+}
diff --git a/explorer/src/utils/url.ts b/explorer/src/utils/url.ts
index 94f0d63d71..7a27c55ef6 100644
--- a/explorer/src/utils/url.ts
+++ b/explorer/src/utils/url.ts
@@ -5,6 +5,13 @@ export function useQuery() {
return new URLSearchParams(useLocation().search);
}
+export const clusterPath = (pathname: string) => {
+ return (location: Location) => ({
+ ...pickCluster(location),
+ pathname,
+ });
+};
+
export function pickCluster(location: Location): Location {
const cluster = new URLSearchParams(location.search).get("cluster");
|