From daa56dba9a8f7f9c318b5c1e2bc9239df64e5d74 Mon Sep 17 00:00:00 2001 From: Mohammad <mcfarhat@gmail.com> Date: Thu, 25 Jul 2024 19:22:24 +0300 Subject: [PATCH] implement RC delegations box related to issue 285 --- api/common/useRcDelegations.ts | 18 ++++ components/account/AccountDetailsSection.tsx | 5 + .../account/AccountRcDelegationsCard.tsx | 95 +++++++++++++++++++ services/FetchingService.ts | 10 ++ 4 files changed, 128 insertions(+) create mode 100644 api/common/useRcDelegations.ts create mode 100644 components/account/AccountRcDelegationsCard.tsx diff --git a/api/common/useRcDelegations.ts b/api/common/useRcDelegations.ts new file mode 100644 index 00000000..c735b540 --- /dev/null +++ b/api/common/useRcDelegations.ts @@ -0,0 +1,18 @@ +import { useQuery } from "@tanstack/react-query"; +import fetchingService from "@/services/FetchingService"; + +const useRcDelegations = (delegatorAccount: string, limit: number) => { + const { + data: rcDelegationsData, + isLoading: isRcDelegationsLoading, + isError: isRcDelegationsError, + } = useQuery({ + queryKey: ["RcDelegations", delegatorAccount, limit], + queryFn: () => fetchingService.getRcDelegations(delegatorAccount, limit), + refetchOnWindowFocus: false, + }); + + return { rcDelegationsData, isRcDelegationsLoading, isRcDelegationsError }; +}; + +export default useRcDelegations; \ No newline at end of file diff --git a/components/account/AccountDetailsSection.tsx b/components/account/AccountDetailsSection.tsx index 6df8401e..013d5fdb 100644 --- a/components/account/AccountDetailsSection.tsx +++ b/components/account/AccountDetailsSection.tsx @@ -10,6 +10,7 @@ import VotersDialog from "../Witnesses/VotersDialog"; import VotesHistoryDialog from "../Witnesses/VotesHistoryDialog"; import useWitnessDetails from "@/api/common/useWitnessDetails"; import AccountVestingDelegationsCard from "./AccountVestingDelegationsCard"; +import AccountRcDelegationsCard from "./AccountRcDelegationsCard"; import { config } from "@/Config"; interface AccountDetailsSectionProps { @@ -74,6 +75,10 @@ const AccountDetailsSection: React.FC<AccountDetailsSectionProps> = ({ startAccount={null} limit={config.maxDelegatorsCount} /> + <AccountRcDelegationsCard + delegatorAccount={accountName} + limit={config.maxDelegatorsCount} + /> <VotersDialog accountName={accountName} isVotersOpen={isVotersModalOpen} diff --git a/components/account/AccountRcDelegationsCard.tsx b/components/account/AccountRcDelegationsCard.tsx new file mode 100644 index 00000000..0f09e138 --- /dev/null +++ b/components/account/AccountRcDelegationsCard.tsx @@ -0,0 +1,95 @@ +import React, { useState, Fragment } from "react"; +import { ArrowDown, ArrowUp } from "lucide-react"; +import Link from "next/link"; +import { Card, CardContent, CardHeader } from "../ui/card"; +import { Table, TableBody, TableRow, TableCell } from "../ui/table"; +import { cn } from "@/lib/utils"; +import useRcDelegations from "@/api/common/useRcDelegations"; +type RcDelegation = { + to: string; + delegated_rc: number; +}; + +type AccountRcDelegationsCardProps = { + delegatorAccount: string; + limit: number; +}; + +const buildTableBody = (delegations: RcDelegation[]) => { + return delegations.map((delegation: RcDelegation, index: number) => { + const isLast = index === delegations.length - 1; + return ( + <Fragment key={index}> + <TableRow + className={cn( + { + "border-t border-gray-700": index !== 0, + "border-b border-gray-700": !isLast, + }, + "hover:bg-inherit" + )} + > + <TableCell>{index + 1}</TableCell> + <TableCell className="text-right"> + <Link className="text-blue-400" href={`/@${delegation.to}`}> + {delegation.to} + </Link> + </TableCell> + <TableCell className="text-right">{delegation.delegated_rc}</TableCell> + </TableRow> + </Fragment> + ); + }); +}; + +const AccountRcDelegationsCard: React.FC<AccountRcDelegationsCardProps> = ({ + delegatorAccount, + limit, +}) => { + const [isPropertiesHidden, setIsPropertiesHidden] = useState(true); + const { + rcDelegationsData, + isRcDelegationsLoading, + isRcDelegationsError, + } = useRcDelegations(delegatorAccount, limit); + + if (isRcDelegationsLoading) { + return <div></div>; + } + + if (isRcDelegationsError) { + return <div></div>; + } + + const delegations = rcDelegationsData?.result || []; + if (!delegations.length) return <div className="text-black"></div>; + + delegations.sort((a: RcDelegation, b: RcDelegation) => + a.to.toLowerCase().localeCompare(b.to.toLowerCase()) + ); + + const handlePropertiesVisibility = () => { + setIsPropertiesHidden(!isPropertiesHidden); + }; + + return ( + <Card data-testid="rc-delegations-dropdown" className="overflow-hidden"> + <CardHeader className="p-0"> + <div + onClick={handlePropertiesVisibility} + className="h-full flex justify-between align-center p-2 hover:bg-slate-600 cursor-pointer px-4" + > + <div className="text-lg">RC Delegations</div> + {isPropertiesHidden ? <ArrowDown /> : <ArrowUp />} + </div> + </CardHeader> + <CardContent hidden={isPropertiesHidden}> + <Table> + <TableBody>{buildTableBody(delegations)}</TableBody> + </Table> + </CardContent> + </Card> + ); +}; + +export default AccountRcDelegationsCard; \ No newline at end of file diff --git a/services/FetchingService.ts b/services/FetchingService.ts index 9b6feabf..cc335954 100644 --- a/services/FetchingService.ts +++ b/services/FetchingService.ts @@ -240,6 +240,16 @@ class FetchingService { return await this.makePostRequest(this.nodeUrl!, requestBody); } + async getRcDelegations (delegatorAccount: string, limit: number): Promise<any> { + const requestBody ={ + jsonrpc: "2.0", + method: "condenser_api.list_rc_direct_delegations", + params: [[delegatorAccount, ""], limit], + id: 1 + }; + return await this.makePostRequest(this.nodeUrl!, requestBody); + } + async getBlockByTime(date: Date): Promise<number> { const requestBody: Hive.GetBlockByTimeProps = { _timestamp: date, -- GitLab