Skip to content

Commit ac83809

Browse files
authored
Merge pull request #2319 from pyth-network/cprussin/insights-mdp-feedback
feat(insights): implement many tweaks & improvements
2 parents 4f8631d + 911e972 commit ac83809

40 files changed

+1455
-1215
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import type { Metadata } from "next";
22

3-
import { Cluster, getData } from "../../../services/pyth";
3+
import { Cluster, getFeeds } from "../../../services/pyth";
44
export { PriceFeedLayout as default } from "../../../components/PriceFeed/layout";
55

66
export const metadata: Metadata = {
77
title: "Price Feeds",
88
};
99

1010
export const generateStaticParams = async () => {
11-
const data = await getData(Cluster.Pythnet);
12-
return data.map(({ symbol }) => ({ slug: encodeURIComponent(symbol) }));
11+
const feeds = await getFeeds(Cluster.Pythnet);
12+
return feeds.map(({ symbol }) => ({ slug: encodeURIComponent(symbol) }));
1313
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@use "@pythnetwork/component-library/theme";
2+
3+
.trigger {
4+
@each $size, $values in theme.$button-sizes {
5+
&[data-size="#{$size}"] {
6+
margin: -#{theme.map-get-strict($values, "padding")};
7+
}
8+
}
9+
}
10+
11+
.description {
12+
p {
13+
margin: 0;
14+
}
15+
16+
b {
17+
font-weight: theme.font-weight("semibold");
18+
}
19+
20+
ul {
21+
margin: 0;
22+
}
23+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Info } from "@phosphor-icons/react/dist/ssr/Info";
2+
import { Lightbulb } from "@phosphor-icons/react/dist/ssr/Lightbulb";
3+
import { Alert, AlertTrigger } from "@pythnetwork/component-library/Alert";
4+
import { Button } from "@pythnetwork/component-library/Button";
5+
import type { ComponentProps, ReactNode } from "react";
6+
7+
import styles from "./index.module.scss";
8+
9+
type Props = {
10+
size: ComponentProps<typeof Button>["size"];
11+
title: string;
12+
children: ReactNode;
13+
};
14+
15+
export const Explain = ({ size, title, children }: Props) => (
16+
<AlertTrigger>
17+
<Button
18+
className={styles.trigger ?? ""}
19+
variant="ghost"
20+
size={size}
21+
beforeIcon={(props) => <Info weight="fill" {...props} />}
22+
rounded
23+
hideText
24+
>
25+
Explain {title}
26+
</Button>
27+
<Alert
28+
title={title}
29+
icon={<Lightbulb />}
30+
bodyClassName={styles.description}
31+
>
32+
{children}
33+
</Alert>
34+
</AlertTrigger>
35+
);
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { Button } from "@pythnetwork/component-library/Button";
2+
import { useMemo } from "react";
3+
4+
import { Explain } from "../Explain";
5+
import { FormattedDate } from "../FormattedDate";
6+
7+
export const ExplainAverage = ({
8+
scoreTime,
9+
}: {
10+
scoreTime?: Date | undefined;
11+
}) => {
12+
return (
13+
<Explain size="xs" title="Average Feed Score">
14+
<p>
15+
Each <b>Price Feed Component</b> that a <b>Publisher</b> provides has an
16+
associated <b>Score</b>, which is determined by that component{"'"}s{" "}
17+
<b>Uptime</b>, <b>Price Deviation</b>, and <b>Staleness</b>. The{" "}
18+
<b>Average Feed Score</b> is the average of the scores for all{" "}
19+
<b>Price Feed Components</b>.
20+
</p>
21+
{scoreTime && <EvaluationTime scoreTime={scoreTime} />}
22+
<Button
23+
size="xs"
24+
variant="solid"
25+
href="https://docs.pyth.network/home/oracle-integrity-staking/publisher-quality-ranking"
26+
target="_blank"
27+
>
28+
Learn more
29+
</Button>
30+
</Explain>
31+
);
32+
};
33+
34+
export const EvaluationTime = ({ scoreTime }: { scoreTime: Date }) => {
35+
const startTime = useMemo(() => {
36+
const date = new Date(scoreTime);
37+
date.setDate(date.getDate() - 1);
38+
return date;
39+
}, [scoreTime]);
40+
41+
return (
42+
<p>
43+
This value is calculated based on feed performance from{" "}
44+
<b>
45+
<FormattedDate
46+
value={startTime}
47+
dateStyle="long"
48+
timeStyle="long"
49+
timeZone="utc"
50+
/>
51+
</b>{" "}
52+
to{" "}
53+
<b>
54+
<FormattedDate
55+
value={scoreTime}
56+
dateStyle="long"
57+
timeStyle="long"
58+
timeZone="utc"
59+
/>
60+
</b>
61+
.
62+
</p>
63+
);
64+
};
65+
66+
export const ExplainActive = () => (
67+
<Explain size="xs" title="Active Feeds">
68+
<p>
69+
This is the number of feeds which the publisher is permissioned for, where
70+
the publisher{"'"}s feed has 50% or better uptime over the last day.
71+
</p>
72+
<NeitherActiveNorInactiveNote />
73+
</Explain>
74+
);
75+
76+
export const ExplainInactive = () => (
77+
<Explain size="xs" title="Inactive Feeds">
78+
<p>
79+
This is the number of feeds which the publisher is permissioned for, but
80+
for which the publisher{"'"}s feed has less than 50% uptime over the last
81+
day.
82+
</p>
83+
<NeitherActiveNorInactiveNote />
84+
</Explain>
85+
);
86+
87+
const NeitherActiveNorInactiveNote = () => (
88+
<p>
89+
Note that a publisher{"'"}s feed may not be considered either active or
90+
inactive if Pyth has not yet calculated quality rankings for it.
91+
</p>
92+
);

apps/insights/src/components/NoResults/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const NoResults = ({ onClearSearch, ...props }: Props) => (
3333
<p className={styles.body}>
3434
{"body" in props
3535
? props.body
36-
: `We couldn't find any results for "${props.query}".`}
36+
: `We couldn't find any results for ${props.query === "" ? "your query" : `"${props.query}"`}.`}
3737
</p>
3838
</div>
3939
{onClearSearch && (

apps/insights/src/components/PriceComponentDrawer/index.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Spinner } from "@pythnetwork/component-library/Spinner";
44
import { StatCard } from "@pythnetwork/component-library/StatCard";
55
import { useRouter } from "next/navigation";
66
import { type ReactNode, useState, useRef, useCallback } from "react";
7+
import { RouterProvider } from "react-aria";
78
import { z } from "zod";
89

910
import styles from "./index.module.scss";
@@ -78,14 +79,11 @@ export const PriceComponentDrawer = ({
7879
<>
7980
{headingExtra}
8081
<StatusComponent status={status} />
81-
<Button
82-
size="sm"
83-
variant="outline"
84-
onPress={handleOpenFeed}
85-
href={navigateHref}
86-
>
87-
{navigateButtonText}
88-
</Button>
82+
<RouterProvider navigate={handleOpenFeed}>
83+
<Button size="sm" variant="outline" href={navigateHref}>
84+
{navigateButtonText}
85+
</Button>
86+
</RouterProvider>
8987
</>
9088
}
9189
isOpen={isFeedDrawerOpen}

apps/insights/src/components/PriceFeed/publishers-card.module.scss renamed to apps/insights/src/components/PriceComponentsCard/index.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@use "@pythnetwork/component-library/theme";
22

3-
.publisherName {
3+
.componentName {
44
display: flex;
55
flex-flow: row nowrap;
66
align-items: center;

0 commit comments

Comments
 (0)