11"use client" ;
22
3- import { useState , useCallback } from "react" ;
3+ import { useState , useCallback , useMemo } from "react" ;
44import { TokenBalance } from "@/components/reusables/BalanceDisplay" ;
55import { Button } from "@/components/ui/button" ;
66import { RefreshCw , AlertCircle } from "lucide-react" ;
77import { useProposalVote } from "@/hooks/useProposalVote" ;
8+ import { safeNumberFromBigInt } from "@/utils/proposal" ;
89import type { Proposal , ProposalWithDAO } from "@/types" ;
910
1011interface VoteStatusChartProps {
@@ -112,6 +113,44 @@ const VoteStatusChart = ({
112113
113114 // const isRefreshingAny = localRefreshing || refreshing;
114115
116+ // Calculate progress bar size based on quorum
117+ const progressBarCalculations = useMemo ( ( ) => {
118+ if ( ! proposal || ! calculations ) return null ;
119+
120+ const quorumPercentage = safeNumberFromBigInt ( proposal . voting_quorum ) ;
121+ const liquidTokensNum = calculations . liquidTokensNum ;
122+
123+ // Calculate quorum amount in tokens
124+ const quorumAmount = ( liquidTokensNum * quorumPercentage ) / 100 ;
125+
126+ // Bar width is quorum + 10%, or total votes if exceeded
127+ const barWidth = Math . max ( quorumAmount * 1.1 , calculations . totalVotes ) ;
128+
129+ // Calculate percentages based on the bar width
130+ const votesForPercentage = ( calculations . votesForNum / barWidth ) * 100 ;
131+ const votesAgainstPercentage =
132+ ( calculations . votesAgainstNum / barWidth ) * 100 ;
133+ const quorumLinePercentage = ( quorumAmount / barWidth ) * 100 ;
134+
135+ return {
136+ votesForPercentage,
137+ votesAgainstPercentage,
138+ quorumLinePercentage,
139+ quorumAmount,
140+ barWidth,
141+ } ;
142+ } , [ proposal , calculations ] ) ;
143+
144+ if ( ! progressBarCalculations ) {
145+ return (
146+ < div className = "flex items-center justify-center p-4" >
147+ < span className = "text-sm text-muted-foreground" >
148+ No vote data available
149+ </ span >
150+ </ div >
151+ ) ;
152+ }
153+
115154 // Main vote display
116155 return (
117156 < div className = "space-y-2" >
@@ -122,17 +161,29 @@ const VoteStatusChart = ({
122161 < div
123162 className = "absolute left-0 top-0 h-full bg-green-500/80 transition-all duration-500 ease-out rounded-l-full"
124163 style = { {
125- width : `${ Math . min ( calculations . barPercentageFor , 100 ) } %` ,
164+ width : `${ Math . min ( progressBarCalculations . votesForPercentage , 100 ) } %` ,
126165 } }
127166 />
128167 { /* Votes against (red) */ }
129168 < div
130169 className = "absolute top-0 h-full bg-red-500/80 transition-all duration-500 ease-out"
131170 style = { {
132- width : `${ Math . min ( calculations . barPercentageAgainst , 100 ) } %` ,
133- left : `${ Math . min ( calculations . barPercentageFor , 100 ) } %` ,
171+ width : `${ Math . min ( progressBarCalculations . votesAgainstPercentage , 100 ) } %` ,
172+ left : `${ Math . min ( progressBarCalculations . votesForPercentage , 100 ) } %` ,
134173 } }
135174 />
175+ { /* Quorum line indicator */ }
176+ < div
177+ className = "absolute top-0 bottom-0 w-0.5 bg-primary z-10"
178+ style = { {
179+ left : `${ Math . min ( progressBarCalculations . quorumLinePercentage , 100 ) } %` ,
180+ } }
181+ >
182+ < div
183+ className = "absolute -top-1 w-3 h-3 bg-primary rounded-sm border-2 border-background"
184+ style = { { left : "-5px" } }
185+ />
186+ </ div >
136187 </ div >
137188 </ div >
138189
0 commit comments