Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show court payouts #2387 #2403

Merged
merged 21 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/court/CourtExitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const CourtExitButton = ({ className }: { className?: string }) => {
<>
<button
className={`rounded-md ${
canExit ? "bg-[#DC056C]" : "bg-gray-400"
canExit ? "bg-[#670031]" : "bg-gray-400"
} px-4 py-2 text-white ${className}`}
onClick={() => setIsOpen(true)}
disabled={!canExit}
Expand Down
2 changes: 1 addition & 1 deletion components/court/CourtUnstakeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const CourtUnstakeButton = ({ className }: { className?: string }) => {
return (
<>
<button
className={`rounded-md bg-[#DC056C] px-4 py-2 text-white ${className}`}
className={`rounded-md bg-[#670031] px-4 py-2 text-white ${className}`}
onClick={() => setIsOpen(true)}
>
Unstake
Expand Down
2 changes: 1 addition & 1 deletion components/court/JoinCourtAsJurorButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const JoinCourtAsJurorButton = ({ className }: { className?: string }) => {
<div className="relative">
<button
disabled={isLoading}
className={`rounded-md bg-[#670031] px-4 py-2 text-white transition-all ${
className={`rounded-md bg-[#DC056C] px-4 py-2 text-white transition-all ${
connectedParticipant?.type === "Delegator" &&
"ring-2 ring-orange-500"
} ${className}`}
Expand Down
2 changes: 1 addition & 1 deletion components/court/ManageDelegationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ManageDelegationButton = ({ className }: { className?: string }) => {
<>
<div className="relative">
<button
className={`rounded-md bg-[#670031] px-4 py-2 text-white transition-all ${
className={`rounded-md bg-[#DC056C] px-4 py-2 text-white transition-all ${
connectedParticipant?.type === "Juror" && "ring-2 ring-orange-500"
} ${className}`}
onClick={() => setIsOpen(true)}
Expand Down
96 changes: 96 additions & 0 deletions components/portfolio/CourtRewardsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import SubScanIcon from "components/icons/SubScanIcon";
import Table, { TableColumn, TableData } from "components/ui/Table";
import Decimal from "decimal.js";
import { ZTG } from "lib/constants";
import { useChainConstants } from "lib/hooks/queries/useChainConstants";
import { useMintedInCourt } from "lib/hooks/queries/useMintedInCourt";
import { useZtgPrice } from "lib/hooks/queries/useZtgPrice";
import { formatNumberLocalized } from "lib/util";
import EmptyPortfolio from "./EmptyPortfolio";

const columns: TableColumn[] = [
{
header: "Time",
accessor: "timestamp",
type: "text",
},
{
header: "Amount",
accessor: "amount",
type: "component",
alignment: "right",
},
{
header: "Subscan",
accessor: "subscan",
type: "component",
width: "100px",
},
];

const CourtRewardsTable = ({ address }: { address: string }) => {
const { data: mintedInCourt, isLoading } = useMintedInCourt({
account: address,
});
const { data: ztgPrice } = useZtgPrice();
const { data: constants } = useChainConstants();

const tableData: TableData[] | undefined = mintedInCourt?.map((mint) => {
return {
timestamp: new Intl.DateTimeFormat("default", {
dateStyle: "medium",
timeStyle: "medium",
}).format(new Date(mint?.timestamp)),
amount: (
<div>
<div>
{formatNumberLocalized(
new Decimal(mint?.dBalance ?? 0).div(ZTG).toNumber(),
)}{" "}
<b>{constants?.tokenSymbol}</b>
</div>
<div className="text-gray-400">
${" "}
{formatNumberLocalized(
ztgPrice
?.mul(mint?.dBalance ?? 0)
.div(ZTG)
.toNumber() ?? 0,
)}
</div>
</div>
),
subscan: (
<a
className="center text-sm"
target="_blank"
referrerPolicy="no-referrer"
rel="noopener"
href={`https://zeitgeist.subscan.io/block/${mint?.blockNumber}?tab=event`}
>
<div className="">
<SubScanIcon />
</div>
</a>
),
};
});

return (
<div>
{isLoading === false &&
(mintedInCourt == null || mintedInCourt?.length === 0) ? (
<EmptyPortfolio
headerText="No Court Rewards"
bodyText=""
buttonText="Go To Court"
buttonLink="/court"
/>
) : (
<Table columns={columns} data={tableData} />
)}
</div>
);
};

export default CourtRewardsTable;
32 changes: 32 additions & 0 deletions components/portfolio/CourtTabGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Tab } from "@headlessui/react";
import SubTabsList from "components/ui/SubTabsList";
import { useQueryParamState } from "lib/hooks/useQueryParamState";
import CourtRewardsTable from "./CourtRewardsTable";

type CourtGroupItem = "Rewards";
const courtTabItems: CourtGroupItem[] = ["Rewards"];

const CourtTabGroup = ({ address }: { address: string }) => {
const [historyTabSelection, setHistoryTabSelection] =
useQueryParamState<CourtGroupItem>("courtTab");

const courtTabIndex = courtTabItems.indexOf(historyTabSelection);
const selectedIndex = courtTabIndex !== -1 ? courtTabIndex : 0;

return (
<Tab.Group
defaultIndex={0}
selectedIndex={selectedIndex}
onChange={(index) => setHistoryTabSelection(courtTabItems[index])}
>
<SubTabsList titles={courtTabItems} />
<Tab.Panels>
<Tab.Panel>
<CourtRewardsTable address={address} />
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
);
};

export default CourtTabGroup;
43 changes: 43 additions & 0 deletions lib/hooks/queries/useMintedInCourt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useQuery } from "@tanstack/react-query";
import type { HistoricalAccountBalanceWhereInput } from "@zeitgeistpm/indexer";
import { HistoricalAccountBalanceOrderByInput } from "@zeitgeistpm/indexer";
import { isIndexedSdk } from "@zeitgeistpm/sdk";
import { useSdkv2 } from "../useSdkv2";

export const mintedInCourtRootKey = "minted-in-court";

export const useMintedInCourt = (
filter: Partial<{
account: string;
limit: number;
offset: number;
}>,
) => {
const [sdk, id] = useSdkv2();

const enabled = sdk && isIndexedSdk(sdk) && filter.account;

const query = useQuery(
[id, mintedInCourtRootKey, filter],
async () => {
if (enabled) {
const response = await sdk.indexer.historicalAccountBalances({
where: {
event_eq: "MintedInCourt",
accountId_eq: filter.account,
},
order: HistoricalAccountBalanceOrderByInput.TimestampDesc,
limit: filter.limit,
offset: filter.offset,
});

return response.historicalAccountBalances;
}
},
{
enabled: Boolean(enabled),
staleTime: 30_000,
},
);
return query;
};
Loading
Loading