diff --git a/components/hypercert/contributors.tsx b/components/hypercert/contributors.tsx index f0ecda1b..55b6d3a0 100644 --- a/components/hypercert/contributors.tsx +++ b/components/hypercert/contributors.tsx @@ -11,15 +11,60 @@ import { } from "@/components/ui/command"; import { UserCircle2 } from "lucide-react"; import { useState } from "react"; -import { isAddress } from "viem"; +import { getAddress, isAddress } from "viem"; import { HypercertState } from "@/hypercerts/fragments/hypercert-state.fragment"; +import { useGetUser } from "@/users/hooks"; +import { UserIcon } from "../user-icon"; +import { ImageIcon } from "../user-icon/ImageIcon"; +import { SvgIcon } from "../user-icon/SvgIcon"; +import { Skeleton } from "../ui/skeleton"; +import { UserName } from "../user-name"; const MAX_CONTRIBUTORS_DISPLAYED = 10; function Contributor({ contributor }: { contributor: string }) { - return isAddress(contributor) ? ( - + const address = isAddress(contributor.trim()) + ? getAddress(contributor.trim()) + : undefined; + + const { data: userData, isFetching } = useGetUser({ + address: address, + }); + + if (isFetching) { + return ( +
+ + +
+ ); + } + + return userData?.user ? ( +
+ {userData.user.avatar ? ( + + ) : ( + + )} +
+ +
+
+ ) : address ? ( +
+ +
+ +
+
) : ( -
{contributor}
+
+ + {contributor} +
); } @@ -58,7 +103,6 @@ export default function Contributors({ {hypercert.metadata?.contributors.map((contributor) => ( - ))} diff --git a/components/hypercert/fractions.tsx b/components/hypercert/fractions.tsx index 23a33421..c72898d7 100644 --- a/components/hypercert/fractions.tsx +++ b/components/hypercert/fractions.tsx @@ -8,26 +8,82 @@ import { CommandItem, CommandList, } from "@/components/ui/command"; -import { truncateEthereumAddress } from "@/lib/utils"; -import { UserCircle2 } from "lucide-react"; import { useState } from "react"; import { FormattedUnits } from "../formatted-units"; import { HypercertState } from "@/hypercerts/fragments/hypercert-state.fragment"; - +import { getAddress, isAddress } from "viem"; +import { useGetUser } from "@/users/hooks"; +import { Skeleton } from "../ui/skeleton"; +import { UserIcon } from "../user-icon"; +import { ImageIcon } from "../user-icon/ImageIcon"; +import { SvgIcon } from "../user-icon/SvgIcon"; +import EthAddress from "../eth-address"; +import { UserName } from "../user-name"; +import { calculateBigIntPercentage } from "@/lib/calculateBigIntPercentage"; const MAX_FRACTIONS_DISPLAYED = 5; function Fraction({ ownerAddress, + totalUnits, units, }: { - ownerAddress: string | null; - units: unknown; + ownerAddress: string; + totalUnits: string | null | undefined; + units: string | null | undefined; }) { + const address = isAddress(ownerAddress.trim()) + ? getAddress(ownerAddress.trim()) + : undefined; + + const { data: userData, isFetching } = useGetUser({ + address: address, + }); + + const calculatedPercentage = calculateBigIntPercentage( + units as string, + totalUnits as string, + ); + + const roundedPercentage = + calculatedPercentage! < 1 + ? "<1" + : Math.round(calculatedPercentage!).toString(); + + if (isFetching) { + return ( +
+ + +
+ ); + } return ( -
- {truncateEthereumAddress(ownerAddress as `0x${string}`)} —{" "} - {units as string} -
+ <> + {userData?.user ? ( +
+ {userData?.user?.avatar ? ( + + ) : ( + + )} +
+ +
+
+ ) : ( +
+ + +
+ )} +
+ — {units as string} + {`(${roundedPercentage}%)`} +
+ ); } @@ -77,10 +133,9 @@ export default function Fractions({ key={fraction.fraction_id} title={fraction.owner_address || ""} > - - {fraction.owner_address} diff --git a/components/user-name.tsx b/components/user-name.tsx new file mode 100644 index 00000000..88ecf7bc --- /dev/null +++ b/components/user-name.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import { CopyButton } from "./copy-button"; + +export function UserName({ + address, + userName, +}: { + address: string | undefined | null; + userName: string | undefined | null; +}) { + const copyAddress = (event: React.MouseEvent) => { + event.stopPropagation(); + void navigator.clipboard.writeText(address as string); + }; + + if (!address) { + return
Unknown
; + } + return ( +
+
+

{userName}

+
+ +
+ ); +}