Skip to content

Commit 782a3b9

Browse files
committed
Merge branch '595-recovery-dashboard' into beta-ui-mvp
2 parents 5758dd0 + a9e6069 commit 782a3b9

File tree

14 files changed

+1629
-0
lines changed

14 files changed

+1629
-0
lines changed

public/ogs/pages/recovery.png

1.14 MB
Loading
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { DashboardCardData } from "../../types";
2+
3+
interface IProps {
4+
card: DashboardCardData;
5+
averageBurnRate: number | null;
6+
totalBurnPercent: number | null;
7+
}
8+
9+
const Card = ({
10+
card,
11+
averageBurnRate,
12+
totalBurnPercent,
13+
}: IProps): JSX.Element => {
14+
return (
15+
<div className="bg-[#101012] backdrop-blur-md border border-[#23252A] rounded-lg p-6 hover:bg-[#23252A] flex flex-col gap-2">
16+
<h3 className="text-[#9798A4] text-base">{card.title}</h3>
17+
18+
<p className="text-white text-[32px] font-bold">
19+
{card.specialType === "averageBurnRate"
20+
? averageBurnRate !== null
21+
? averageBurnRate.toFixed(2) + "%"
22+
: "—"
23+
: card.value}
24+
</p>
25+
26+
{card.subtitle && (
27+
<p className="text-[#9798A4] text-base">{card.subtitle}</p>
28+
)}
29+
30+
{card.specialType === "averageBurnRate" ? (
31+
<p className="text-green-500 text-sm">
32+
{totalBurnPercent !== null &&
33+
totalBurnPercent.toFixed(2) + "% burned across all tokens"}
34+
</p>
35+
) : (
36+
card.change && (
37+
<p
38+
className={`text-sm ${
39+
card.changeType === "positive"
40+
? "text-green-500"
41+
: card.changeType === "negative"
42+
? "text-red-500"
43+
: "text-gray-400"
44+
}`}
45+
>
46+
{card.change}
47+
</p>
48+
)
49+
)}
50+
</div>
51+
);
52+
};
53+
54+
export { Card };
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Card } from "./Card";
2+
3+
import type { DashboardCardData } from "../../types";
4+
5+
interface IProps {
6+
cards: DashboardCardData[];
7+
averageBurnRate: number | null;
8+
totalBurnPercent: number | null;
9+
}
10+
11+
const Dashboard = ({
12+
cards,
13+
averageBurnRate,
14+
totalBurnPercent,
15+
}: IProps): JSX.Element => {
16+
return (
17+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-8">
18+
{cards.map((card, index) => (
19+
<Card
20+
key={index}
21+
card={card}
22+
averageBurnRate={averageBurnRate}
23+
totalBurnPercent={totalBurnPercent}
24+
/>
25+
))}
26+
</div>
27+
);
28+
};
29+
30+
export { Dashboard };
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { PriceCellProps } from "../types";
2+
3+
const PriceCell: React.FC<PriceCellProps> = ({ price }) => {
4+
if (!price) {
5+
return <div className="text-[#97979A] text-sm"></div>;
6+
}
7+
8+
return (
9+
<div className="min-w-0">
10+
<span className="text-[#EAECEF] font-medium text-sm text-balance leading-tight break-words">
11+
1 {price.sym0} ={" "}
12+
{price.price_token1_per_token0.toLocaleString("en-US", {
13+
minimumFractionDigits: 2,
14+
maximumFractionDigits: 4,
15+
})}{" "}
16+
{price.sym1}
17+
</span>
18+
</div>
19+
);
20+
};
21+
22+
export { PriceCell };
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { ArrowIcon } from "@ui";
2+
3+
interface Props {
4+
currentPage: number;
5+
totalPages: number;
6+
itemsPerPage: number;
7+
totalItems: number;
8+
startIndex: number;
9+
endIndex: number;
10+
onPageChange: (page: number) => void;
11+
onItemsPerPageChange: (value: number) => void;
12+
}
13+
14+
const TablePagination = ({
15+
currentPage,
16+
totalPages,
17+
itemsPerPage,
18+
totalItems,
19+
startIndex,
20+
endIndex,
21+
onPageChange,
22+
onItemsPerPageChange,
23+
}: Props): JSX.Element => {
24+
return (
25+
<div className="flex items-center justify-between text-sm md:px-6 bg-[#151618] border-t border-[#23252A]">
26+
<div className="flex items-center gap-2">
27+
<div className="hidden md:flex items-center gap-2 py-3">
28+
<span className="text-[#97979A]">Items per page:</span>
29+
<select
30+
value={itemsPerPage}
31+
onChange={(e) => onItemsPerPageChange(Number(e.target.value))}
32+
className="text-white bg-[#151618] cursor-pointer"
33+
>
34+
<option value={5}>5</option>
35+
<option value={10}>10</option>
36+
<option value={15}>15</option>
37+
<option value={20}>20</option>
38+
<option value={30}>30</option>
39+
</select>
40+
</div>
41+
<span className="text-[#97979A] border-r md:border-l border-[#23252a] px-4 py-3">
42+
{startIndex + 1}-{Math.min(endIndex, totalItems)} of {totalItems}{" "}
43+
items
44+
</span>
45+
</div>
46+
<div className="flex items-center gap-2">
47+
<div className="hidden md:flex items-center gap-2">
48+
<button
49+
onClick={() => onPageChange(Math.max(currentPage - 1, 1))}
50+
disabled={currentPage === 1}
51+
className="px-3 text-white disabled:text-[#97979A] cursor-pointer disabled:cursor-not-allowed"
52+
>
53+
&lt; Previous
54+
</button>
55+
<span className="text-[#97979A]">
56+
{currentPage} of {totalPages} pages
57+
</span>
58+
<button
59+
onClick={() => onPageChange(Math.min(currentPage + 1, totalPages))}
60+
disabled={currentPage === totalPages}
61+
className="px-3 text-white disabled:text-[#97979A] cursor-pointer disabled:cursor-not-allowed"
62+
>
63+
Next &gt;
64+
</button>
65+
</div>
66+
<div className="flex items-center gap-4 md:hidden">
67+
<button
68+
onClick={() => onPageChange(Math.max(currentPage - 1, 1))}
69+
disabled={currentPage === 1}
70+
className="border-r border-l border-[#23252a] py-3 px-4 text-white disabled:text-[#97979A] cursor-pointer disabled:cursor-not-allowed"
71+
>
72+
<ArrowIcon isActive={currentPage !== 1} rotate={90} />
73+
</button>
74+
<button
75+
onClick={() => onPageChange(Math.min(currentPage + 1, totalPages))}
76+
disabled={currentPage === totalPages}
77+
className="py-3 pr-4 text-white disabled:text-[#97979A] cursor-pointer disabled:cursor-not-allowed"
78+
>
79+
<ArrowIcon isActive={currentPage !== totalPages} rotate={270} />
80+
</button>
81+
</div>
82+
</div>
83+
</div>
84+
);
85+
};
86+
87+
export { TablePagination };
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Dashboard } from "./Dashboard";
2+
import { PriceCell } from "./PriceCell";
3+
import { TablePagination } from "./TablePagination";
4+
5+
export { Dashboard, PriceCell, TablePagination };
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import type { Column, DashboardCardData } from "../types";
2+
3+
const tokenColumns: Column[] = [
4+
{ label: "Token", sortable: true },
5+
{ label: "Token Address", sortable: false },
6+
{ label: "Recovery Progress", sortable: true },
7+
];
8+
9+
const tokenData = [
10+
{
11+
name: "Recovery Stability USD",
12+
symbol: "RECmetaUSD",
13+
address: "0x000078392f3cF4262500FFeB7d803F90477ECC11" as `0x${string}`,
14+
initialSupply: 300836932902619695422070n,
15+
decimals: 18,
16+
},
17+
{
18+
name: "Recovery Wrapped Stability USD",
19+
symbol: "RECwmetaUSD",
20+
address: "0x00001b2c60cD041a478521008CE6efeC475bb9Aa" as `0x${string}`,
21+
initialSupply: 1571426158089874911823524n,
22+
decimals: 18,
23+
},
24+
{
25+
name: "Recovery Wrapped Stability USDC",
26+
symbol: "RECwmetaUSDC",
27+
address: "0x0000a59C549b4250a2931ac6054e1426a87DA0EE" as `0x${string}`,
28+
initialSupply: BigInt(101603724905),
29+
decimals: 6,
30+
},
31+
{
32+
name: "Recovery Wrapped Stability scUSD",
33+
symbol: "RECwmetascUSD",
34+
address: "0x0000c3b22bbD290588361E4B5C424F3AB0d0a3cc" as `0x${string}`,
35+
initialSupply: BigInt(1033496932628),
36+
decimals: 6,
37+
},
38+
{
39+
name: "Recovery Stability S",
40+
symbol: "RECmetaS",
41+
address: "0x000006539BA0B4f5452186Af40aAB959bDEa4344" as `0x${string}`,
42+
initialSupply: 1101293369505074707160718n,
43+
decimals: 18,
44+
},
45+
{
46+
name: "Recovery Wrapped Stability S",
47+
symbol: "RECwmetaS",
48+
address: "0x0000Dd8cEa00EA3336f5849590d69bbfc93A85bb" as `0x${string}`,
49+
initialSupply: 3166187266373775158998584n,
50+
decimals: 18,
51+
},
52+
];
53+
54+
const poolColumns: Column[] = [
55+
{ label: "Pair", sortable: true },
56+
{ label: "Pool Address", sortable: false },
57+
{ label: "Price", sortable: true },
58+
];
59+
60+
const poolData = [
61+
{
62+
name: "Shadow RECmetaUSD/wmetaUSD",
63+
url: "https://www.shadow.so/liquidity/manage/0x1e2edba99efd08578460bd9a66f4f521ec861eb9",
64+
pair: "RECmetaUSD/wmetaUSD",
65+
address: "0x1e2edBa99efd08578460BD9A66f4f521EC861eb9" as `0x${string}`,
66+
},
67+
{
68+
name: "Shadow RECwmetaUSD/wmetaUSD",
69+
url: "https://www.shadow.so/liquidity/manage/0xd473a0f23f61f63f4e736b16f6133317f0ae4c0a",
70+
pair: "RECwmetaUSD/wmetaUSD",
71+
address: "0xd473A0F23f61F63F4e736b16f6133317F0ae4c0a" as `0x${string}`,
72+
},
73+
{
74+
name: "Shadow RECwmetaUSDC/wmetaUSD",
75+
url: "https://www.shadow.so/liquidity/manage/0x41fc91524e97678f81362f3703b16b07ace0ae23",
76+
pair: "RECwmetaUSDC/wmetaUSD",
77+
address: "0x41FC91524E97678F81362f3703B16b07Ace0ae23" as `0x${string}`,
78+
},
79+
{
80+
name: "Shadow RECwmetascUSD/wmetaUSD",
81+
url: "https://www.shadow.so/liquidity/manage/0x64c52e6c35c77150b58dc947672c4da606528f85",
82+
pair: "RECwmetascUSD/wmetaUSD",
83+
address: "0x64c52E6C35C77150B58DC947672c4dA606528F85" as `0x${string}`,
84+
},
85+
{
86+
name: "Shadow RECmetaS/wmetaS",
87+
url: "https://www.shadow.so/liquidity/manage/0xb7b6a318621eb0fda0893549ea4ee5da4cecf19e",
88+
pair: "RECmetaS/wmetaS",
89+
address: "0xB7B6A318621eb0FDA0893549Ea4eE5DA4CecF19E" as `0x${string}`,
90+
},
91+
{
92+
name: "Shadow RECwmetaS/wmetaS",
93+
url: "https://www.shadow.so/liquidity/manage/0xc68fac41bfc940fb5126ba1e790456ae273de9e7",
94+
pair: "RECwmetaS/wmetaS",
95+
address: "0xc68FaC41Bfc940FB5126Ba1E790456ae273de9E7" as `0x${string}`,
96+
},
97+
];
98+
99+
const dashboardData: DashboardCardData[] = [
100+
{
101+
title: "Total Tokens",
102+
value: tokenData.length,
103+
subtitle: "Recovery tokens",
104+
specialType: null,
105+
},
106+
{
107+
title: "Average Burn Rate",
108+
value: null,
109+
subtitle: null,
110+
specialType: "averageBurnRate",
111+
},
112+
{
113+
title: "Total Pools",
114+
value: poolData.length,
115+
subtitle: "Recovery pools",
116+
specialType: null,
117+
},
118+
];
119+
120+
export { tokenColumns, tokenData, poolColumns, poolData, dashboardData };

0 commit comments

Comments
 (0)