"use client"; import React, { useState } from "react"; import { QuestionMarkCircleIcon } from "@heroicons/react/24/outline"; import { Dnum } from "dnum"; import { Address, useAccount } from "wagmi"; import { CVStrategy, CVStrategyConfig, getMembersStrategyQuery, TokenGarden, } from "#/subgraph/.graphclient"; import { ActivatePoints, Badge, DisplayNumber, CheckSybil, InfoBox, Button, EthAddress, DataTable, InfoWrapper, } from "@/components/"; import { Column, PointSystems } from "@/types"; import { calculatePercentageBigInt } from "@/utils/numbers"; export type PoolGovernanceProps = { memberPoolWeight: number | undefined; tokenDecimals: number; strategy: Pick< CVStrategy, "id" | "sybil" | "poolId" | "totalEffectiveActivePoints" > & { registryCommunity: { garden: Pick }; config: Pick; }; communityAddress: Address; memberTokensInCommunity: bigint; memberPower?: bigint | null; isMemberCommunity: boolean; memberActivatedStrategy: boolean; membersStrategyData: getMembersStrategyQuery | undefined; supportSnapshot?: { proposalId?: string; proposalNumber: string; amount: string; }[]; }; export const PoolGovernance: React.FC = ({ memberPoolWeight, tokenDecimals, strategy, communityAddress, memberTokensInCommunity, memberPower, isMemberCommunity, memberActivatedStrategy, membersStrategyData, supportSnapshot, }) => { const { address } = useAccount(); const showVotingPowerBox = isMemberCommunity && memberActivatedStrategy && !!address; const poolSystem = strategy.config.pointSystem; const [triggerSybilCheckModalClose, setTriggerSybilCheckModalClose] = useState(false); const [openGovernanceDetailsModal, setOpenGovernanceDetailsModal] = useState(false); const poolSystemDefinition: { label: string; description: string }[] = [ { label: "Fixed", description: "Every member has the same voting power, limited to their registration stake.", }, { label: "Capped", description: "Your voting power increases with more tokens staked, but only up to a limit.", }, { label: "Unlimited", description: "Your voting power is equal to your total staked tokens in the community.", }, { label: "Quadratic", description: "Your voting power is equal to the square root of your total staked tokens in the community.", }, ]; return ( <>
{showVotingPowerBox && (

Your Voting Power

{memberPoolWeight?.toFixed(2)} VP

Your share of the pool’s 100 VP
{address && (

Your stake:

0 ? "Stake more tokens to \nincrease your voting \npower in this pool." : "Fixed voting power"}`} className="hidden md:block text-black" size="sm" />
{/* TODO: add this section data */} {/*

Allocated

{} 55% (18.3 VP)

Available

45% (13.3 VP)

*/}
)}
)} {/* Activate-Deactivate Button */}

Governance

{isMemberCommunity && memberActivatedStrategy && ( <>

You have activated governance in this pool. Deactivate to leave the pool and remove all your voting power.

setTriggerSybilCheckModalClose(true)} memberPower={memberPower} activate={false} supportSnapshot={supportSnapshot} /> )}
); }; type MemberColumn = Column; const PoolGovernanceDetails: React.FC<{ membersStrategyData: getMembersStrategyQuery | undefined; totalEffectiveActivePoints: bigint | number | string; currentMemberAddress?: Address; currentMemberActivatedStrategy?: boolean; openGovernanceDetailsModal: boolean; setOpenGovernanceDetailsModal: (open: boolean) => void; }> = ({ membersStrategyData, totalEffectiveActivePoints, currentMemberAddress, currentMemberActivatedStrategy, openGovernanceDetailsModal, setOpenGovernanceDetailsModal, }) => { const totalPoolActivePoints = BigInt(totalEffectiveActivePoints ?? 0); const activeMemberStrategies = membersStrategyData?.memberStrategies.filter( (memberStrategy) => { if (BigInt(memberStrategy.activatedPoints) <= 0n) return false; if (currentMemberActivatedStrategy !== false || !currentMemberAddress) { return true; } const memberAddress = memberStrategy.member.memberCommunity?.[0]?.memberAddress; return ( memberAddress?.toLowerCase() !== currentMemberAddress.toLowerCase() ); }, ) ?? []; const columns: MemberColumn[] = [ { header: "Member", render: (member) => ( ), }, { header: ( Voting power in pool ), render: (member) => ( {totalPoolActivePoints > 0n ? `${calculatePercentageBigInt(BigInt(member.activatedPoints), totalPoolActivePoints)} VP` : "0 VP"} ), className: "text-right min-w-[9rem]", }, { header: ( Voting power used ), render: (member) => { // Calculate total staked points from active (1) and disputed (5) proposals only const activeStakedPoints = member?.member.stakes?.reduce((sum, stake) => { return sum + BigInt(stake.amount); }, 0n) ?? 0n; return ( {calculatePercentageBigInt( activeStakedPoints, BigInt(member.activatedPoints), )}{" "} % ); }, className: "text-right min-w-[8rem]", }, ]; return ( ); };