Skip to content

Commit

Permalink
Fazle/vote timeline chart (#303)
Browse files Browse the repository at this point in the history
* Merge

* working

* feat:Vote Timeline graph style interface

* WIP:voting timeline summary extended version ui

* feat:Implemented live data display in timeline chart

* fixes timeline chart

* Formatting and updates to sci notation functions

* A few minor bugfixes and empty vote display

* Reverted tenant-specific avatar changes

* wip

* Fixed quorum and threshold values

* Removed info icons

* Misc fixes

* Fixed hover issues and a few misc css bugs

* Quorum calc

---------

Co-authored-by: Andrei Taraschuk <[email protected]>
Co-authored-by: andrei <[email protected]>
  • Loading branch information
3 people authored Jun 12, 2024
1 parent 34302b4 commit 9780cf8
Show file tree
Hide file tree
Showing 18 changed files with 734 additions and 104 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"react-is": "^18.2.0",
"react-markdown": "^8.0.7",
"react-responsive": "^9.0.2",
"recharts": "^2.12.6",
"siwe": "^2.3.2",
"swagger-ui-react": "5.16.2",
"tailwind-merge": "^1.13.2",
Expand Down Expand Up @@ -109,4 +110,4 @@
"typechain": "^8.3.2",
"typescript": "5.0.4"
}
}
}
6 changes: 3 additions & 3 deletions src/app/api/common/quorum/getQuorum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ async function getQuorumForProposal(proposal: ProposalPayload) {

switch (namespace) {
case "optimism": {
const contractQuorum = contracts.governor.contract.quorum(
proposal.proposal_id
const contractQuorum = await contracts.governor.contract.quorum(
proposal.proposal_id,
);

// If no quorum is set, calculate it based on votable supply
if (!contractQuorum) {
const votableSupply = await prisma[
`${namespace}VotableSupply`
].findFirst({});
].findFirst({});
return (BigInt(Number(votableSupply?.votable_supply)) * 30n) / 100n;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ async function fetchAllForVoting(
return await apiFetchAllForVoting(address, blockNumber, proposal_id);
}

async function fetchDelegate(addressOrENSName: string | `0x${string}`) {
"use server";

return await apiFetchDelegate(addressOrENSName);
}

async function fetchUserVotesForProposal(
proposal_id: string,
address: string | `0x${string}`
Expand Down Expand Up @@ -63,7 +57,7 @@ export default async function OPProposalApprovalPage({
alignItems="items-start"
className={styles.proposal_container}
>
<ProposalDescription proposal={proposal} />
<ProposalDescription proposalVotes={proposalVotes} proposal={proposal} />
<div>
<OpManagerDeleteProposal proposal={proposal} />
<VStack
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default async function OPProposalPage({ proposal }) {
alignItems="items-start"
className={styles.proposal_container}
>
<ProposalDescription proposal={proposal} />
<ProposalDescription proposalVotes={proposalVotes} proposal={proposal} />
<div>
<OpManagerDeleteProposal proposal={proposal} />
<OptimisticProposalVotesCard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default async function OPProposalPage({
alignItems="items-start"
className={styles.proposal_container}
>
<ProposalDescription proposal={proposal} />
<ProposalDescription proposalVotes={proposalVotes} proposal={proposal} />
<div>
<OpManagerDeleteProposal proposal={proposal} />
<ProposalVotesCard proposal={proposal} proposalVotes={proposalVotes} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,16 @@
import { HStack } from "@/components/Layout/Stack";
import styles from "./proposalVotesBar.module.scss";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { TokenAmountDisplay, generateBarsForVote } from "@/lib/utils";
import { generateBarsForVote } from "@/lib/utils";

export default function ProposalVotesBar({ proposal }) {
return (
<div>
<TooltipProvider delayDuration={10}>
<Tooltip>
<TooltipTrigger asChild>
<HStack
justifyContent="justify-around"
className={styles.vote_bar_ticks}
>
{generateBarsForVote(
proposal.proposalResults.for,
proposal.proposalResults.abstain,
proposal.proposalResults.against
).map((value, idx) => {
return <div key={`${idx}`} className={styles[value]} />;
})}
</HStack>
</TooltipTrigger>
<TooltipContent>
<p>
{TokenAmountDisplay({
amount: proposal.proposalResults.abstain,
})}{" "}
abstained
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<div className={`flex flex-row justify-around ${styles.vote_bar_ticks}`}>
{generateBarsForVote(
proposal.proposalResults.for,
proposal.proposalResults.abstain,
proposal.proposalResults.against,
).map((value, idx) => {
return <div key={`${idx}`} className={styles[value]} />;
})}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@import "@/styles/variables.scss";

.vote_bar_ticks {
cursor: help;
.for {
background: #06ab34;
border-radius: $border-radius-full;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";

import { useState } from "react";
import { HStack, VStack } from "@/components/Layout/Stack";
import ProposalVotesSummary from "../ProposalVotesSummary/ProposalVotesSummary";
import ProposalVotesList from "@/components/Votes/ProposalVotesList/ProposalVotesList";
import CastVoteInput from "@/components/Votes/CastVoteInput/CastVoteInput";
Expand All @@ -25,19 +24,17 @@ const ProposalVotesCard = ({
};

return (
<VStack
gap={4}
justifyContent="justify-between"
className={`${styles.proposal_votes_container} transition-all ${isClicked ? "bottom-[60px]" : "bottom-[calc(-100%+350px)]"}`}
<div
className={`flex flex-col gap-4 justify-between ${styles.proposal_votes_container} transition-all ${isClicked ? "bottom-[60px]" : "bottom-[calc(-100%+350px)]"}`}
>
<VStack gap={4} className={styles.proposal_actions_panel}>
<div className={`flex flex-col gap-4 ${styles.proposal_actions_panel}`}>
<button
onClick={handleClick}
className="border w-10 h-10 rounded-full bg-white absolute top-[-20px] left-[calc(50%-20px)] shadow-newDefault block sm:hidden"
>
<HStack justifyContent="justify-center">
<div className="flex flex-col justify-center">
<img className="opacity-60" src={icons.expand.src} alt="expand" />
</HStack>
</div>
</button>
<div>
<div className={styles.proposal_header}>Proposal votes</div>
Expand All @@ -51,8 +48,8 @@ const ProposalVotesCard = ({
/>
{/* Show the input for the user to vote on a proposal if allowed */}
<CastVoteInput proposal={proposal} />
</VStack>
</VStack>
</div >
</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,77 @@
import { VStack, HStack } from "@/components/Layout/Stack";
"use client";
import { useState } from "react";
import styles from "./proposalVotesSummary.module.scss";
import ProposalVotesBar from "../ProposalVotesBar/ProposalVotesBar";
import { Proposal } from "@/app/api/common/proposals/proposal";
import TokenAmountDisplay from "@/components/shared/TokenAmountDisplay";
import { ParsedProposalResults } from "@/lib/proposalUtils";
import ProposalStatusDetail from "@/components/Proposals/ProposalStatus/ProposalStatusDetail";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";
import ProposalVotesSummaryDetails from "../ProposalVotesSummaryDetails/ProposalVotesSummaryDetails";

export default function ProposalVotesSummary({
proposal,
}: {
proposal,
}: {
proposal: Proposal;
}) {
const [showDetails, setShowDetails] = useState(false);
const results =
proposal.proposalResults as ParsedProposalResults["STANDARD"]["kind"];

return (
<VStack gap={2} className={styles.proposal_votes_summary_container}>
<HStack justifyContent="justify-between" className="mt-2">
<div className="gl_votes_for">
FOR <TokenAmountDisplay amount={results.for} />
</div>
<div className="gl_votes_against">
AGAINST <TokenAmountDisplay amount={results.against} />
</div>
</HStack>
<ProposalVotesBar proposal={proposal} />
<VStack className="font-medium">
<HStack justifyContent="justify-between" className="text-gray-4f pb-2">
<>
{proposal.quorum && (
<div>
Quorum <TokenAmountDisplay amount={proposal.quorum} />
<HoverCard
open={showDetails}
onOpenChange={setShowDetails}
openDelay={0}
closeDelay={0}
>
<div style={{ position: "relative" }}>

<HoverCardTrigger className="w-full cursor-pointer block">
<div className={`flex flex-col gap-2 ${styles.proposal_votes_summary_container}`}>
<div className="flex flex-row justify-between mt-2">
<div className="gl_votes_for">
FOR <TokenAmountDisplay amount={results.for} />
</div>
)}
</>
<>
{proposal.quorum && (
<div>
<p>{`Threshold ${
Number(proposal.approvalThreshold) / 100
}%`}</p>
<div className="gl_votes_against">
AGAINST <TokenAmountDisplay amount={results.against} />
</div>
)}
</>
</HStack>
<ProposalStatusDetail
proposalStartTime={proposal.start_time}
proposalEndTime={proposal.end_time}
proposalStatus={proposal.status}
proposalCancelledTime={proposal.cancelled_time}
cancelledTransactionHash={proposal.cancelled_transaction_hash}
/>
</VStack>
</VStack>
</div>
<ProposalVotesBar proposal={proposal} />
<div className="flex flex-col font-medium">
<div className="flex flex-row text-gray-4f pb-2 justify-between">
<>
{proposal.quorum && (
<div>
Quorum <TokenAmountDisplay amount={proposal.quorum} />
</div>
)}
</>
<>
{proposal.quorum && (
<div>
<p>{`Threshold ${
Number(proposal.approvalThreshold) / 100
}%`}</p>
</div>
)}
</>
</div>
<ProposalStatusDetail
proposalStartTime={proposal.start_time}
proposalEndTime={proposal.end_time}
proposalStatus={proposal.status}
proposalCancelledTime={proposal.cancelled_time}
cancelledTransactionHash={proposal.cancelled_transaction_hash}
/>
</div>
</div>

<HoverCardContent className="pb-0 absolute w-auto ml-4 mt-1" side="top" align={"start"}>
<ProposalVotesSummaryDetails proposal={proposal} />
</HoverCardContent>
</HoverCardTrigger>
</div>
</HoverCard>
);
}
Loading

0 comments on commit 9780cf8

Please sign in to comment.