From 71868f8fc2aa385df41314de704abd407837b6f2 Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 25 Dec 2024 12:23:34 +0100 Subject: [PATCH 1/2] Add resource filter for contributions --- .../hyperstructures/ContributionSummary.tsx | 83 +++++++++++++------ client/src/ui/elements/SelectResource.tsx | 5 +- client/src/ui/utils/utils.tsx | 4 +- 3 files changed, 63 insertions(+), 29 deletions(-) diff --git a/client/src/ui/components/hyperstructures/ContributionSummary.tsx b/client/src/ui/components/hyperstructures/ContributionSummary.tsx index 71ef6a9cb..9e16b7f89 100644 --- a/client/src/ui/components/hyperstructures/ContributionSummary.tsx +++ b/client/src/ui/components/hyperstructures/ContributionSummary.tsx @@ -1,9 +1,10 @@ import { useContributions } from "@/hooks/helpers/useContributions"; import { useRealm } from "@/hooks/helpers/useRealm"; import { ResourceIcon } from "@/ui/elements/ResourceIcon"; -import { currencyIntlFormat, divideByPrecision, formatNumber } from "@/ui/utils/utils"; +import { SelectResource } from "@/ui/elements/SelectResource"; +import { copyPlayerAddressToClipboard, currencyIntlFormat, divideByPrecision, formatNumber } from "@/ui/utils/utils"; import { ContractAddress, ID, ResourcesIds } from "@bibliothecadao/eternum"; -import { useState } from "react"; +import { useMemo, useState } from "react"; export const ContributionSummary = ({ hyperstructureEntityId, @@ -46,15 +47,31 @@ export const ContributionSummary = ({ ); const [showContributions, setShowContributions] = useState(false); + const [selectedResource, setSelectedResource] = useState(null); // Calculate percentages and sort contributors - const sortedContributors = Object.entries(groupedContributions) - .map(([playerAddress, resources]) => ({ - playerAddress, - resources, - percentage: getContributionsTotalPercentage(hyperstructureEntityId, resourceContributions[playerAddress]) * 100, - })) - .sort((a, b) => b.percentage - a.percentage); + const sortedContributors = useMemo( + () => + Object.entries(groupedContributions) + .map(([playerAddress, resources]) => ({ + playerAddress, + resources, + percentage: + getContributionsTotalPercentage(hyperstructureEntityId, resourceContributions[playerAddress]) * 100, + })) + .filter(({ resources }) => + selectedResource ? resources[selectedResource] > 0n : Object.values(resources).some((amount) => amount > 0n), + ) + .sort((a, b) => { + if (selectedResource) { + const amountA = a.resources[selectedResource] || 0n; + const amountB = b.resources[selectedResource] || 0n; + return amountA > amountB ? -1 : amountA < amountB ? 1 : 0; + } + return b.percentage - a.percentage; + }), + [groupedContributions, selectedResource], + ); return (
@@ -66,24 +83,38 @@ export const ContributionSummary = ({
{showContributions && ( -
- {sortedContributors.map(({ playerAddress, resources, percentage }) => ( -
-
-
{getAddressName(ContractAddress(playerAddress))}
-
{formatNumber(percentage, 2)}%
-
-
- {Object.entries(resources).map(([resourceType, amount]) => ( -
- - {currencyIntlFormat(divideByPrecision(Number(amount)))} + <> + setSelectedResource(resourceId)} /> +
+ {sortedContributors.map(({ playerAddress, resources, percentage }) => { + const addressName = getAddressName(ContractAddress(playerAddress)) || "Unknown"; + + return ( +
+
+
copyPlayerAddressToClipboard(ContractAddress(playerAddress), addressName, true)} + className="text-sm font-bold cursor-pointer hover:text-gold/50" + > + {addressName} +
+
{formatNumber(percentage, 2)}%
+
+
+ {Object.entries(resources) + .filter(([resourceType]) => (selectedResource ? Number(resourceType) === selectedResource : true)) + .map(([resourceType, amount]) => ( +
+ + {currencyIntlFormat(divideByPrecision(Number(amount)))} +
+ ))}
- ))} -
-
- ))} -
+
+ ); + })} +
+ )}
); diff --git a/client/src/ui/elements/SelectResource.tsx b/client/src/ui/elements/SelectResource.tsx index e551bf468..7d6b7c21c 100644 --- a/client/src/ui/elements/SelectResource.tsx +++ b/client/src/ui/elements/SelectResource.tsx @@ -76,7 +76,10 @@ export const SelectResource: React.FC = ({ onSelect, classN "my-auto w-8 mx-auto hover:fill-gold/50 fill-gold hover:scale-125 hover:animate-pulse duration-300 transition-all", { "pointer-events-none fill-gold/50": !selectedResource }, )} - onClick={() => setSelectedResource("")} + onClick={() => { + setSelectedResource(""); + onSelect(null); + }} />