import { useEffect, useState, useMemo } from "react"; import ReactGA from "react-ga4"; import { useParams } from 'react-router-dom'; import { Box, Container, Typography, useMediaQuery, useTheme } from "@mui/material"; import Paper from "../../components/Paper/Paper"; import PageTitle from "../../components/PageTitle/PageTitle"; import LinearProgressBar from "../../components/Progress/LinearProgressBar"; import InfoTooltip from "../../components/Tooltip/InfoTooltip"; import Chip from "../../components/Chip/Chip"; import { SecondaryButton } from "../../components/Button"; import { formatNumber } from "../../helpers"; import { prettifySecondsInDays } from "../../helpers/timeUtil"; import { DecimalBigNumber } from "../../helpers/DecimalBigNumber"; import ProposalDiscussionModal from "./components/ProposalDiscussionModal"; import ProposalDiscussion from "./components/ProposalDiscussion"; import { convertStatusToTemplate } from "./helpers"; import { useTokenSymbol, useTotalSupply, useBalance } from "../../hooks/tokens"; import { useProposalStatus, useProposalProposer, useProposalLocked, useProposalQuorum, useProposalVotes, useProposalSnapshot, useProposalDeadline, useProposalVotingDelay } from "../../hooks/governance"; /////////////////////////////////////////////////////// import Timeline from '@mui/lab/Timeline'; import TimelineItem from '@mui/lab/TimelineItem'; import TimelineSeparator from '@mui/lab/TimelineSeparator'; import TimelineConnector from '@mui/lab/TimelineConnector'; import TimelineContent from '@mui/lab/TimelineContent'; import TimelineOppositeContent from '@mui/lab/TimelineOppositeContent'; import TimelineDot from '@mui/lab/TimelineDot'; /////////////////////////// import FastfoodIcon from '@mui/icons-material/Fastfood'; import LaptopMacIcon from '@mui/icons-material/LaptopMac'; import HotelIcon from '@mui/icons-material/Hotel'; import RepeatIcon from '@mui/icons-material/Repeat'; const HUNDRED = new DecimalBigNumber(100n, 0); const ProposalDetails = ({ chainId, address }) => { const { id } = useParams(); const [selectedDiscussionUrl, setSelectedDiscussionUrl] = useState(undefined); const isSemiSmallScreen = useMediaQuery("(max-width: 745px)"); const isSmallScreen = useMediaQuery("(max-width: 650px)"); const isVerySmallScreen = useMediaQuery("(max-width: 379px)"); const theme = useTheme(); const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST"); const { balance } = useBalance(chainId, "GHST", address); const { totalSupply } = useTotalSupply(chainId, "GHST"); // TODO: revisit const { status: proposalStatus } = useProposalStatus(chainId, id); const { proposer: proposalProposer } = useProposalProposer(chainId, id); const { locked: proposalLocked } = useProposalLocked(chainId, id); const { quorum: proposalQuorum } = useProposalQuorum(chainId, id); const { forVotes, againstVotes } = useProposalVotes(chainId, id); useEffect(() => { ReactGA.send({ hitType: "pageview", page: `/governance/${id}` }); }, []); const isDiscussionModalOpened = useMemo(() => { return selectedDiscussionUrl !== undefined; }, [selectedDiscussionUrl]); return ( <> setSelectedDiscussionUrl(undefined)} /> Progress } topRight={ setSelectedDiscussionUrl("dicks")} /> } > For: {formatNumber(forVotes.toString(), 2)} ({formatNumber(forVotes * HUNDRED / proposalQuorum, 1)}%) Against: {formatNumber(againstVotes.toString(), 2)} ({formatNumber(againstVotes * HUNDRED / proposalQuorum, 1)}%) Quorum {formatNumber(proposalQuorum.toString(), 4)} Total {formatNumber(totalSupply.toString(), 4)} Votes {formatNumber(balance.toString(), 4)} alert("For vote casted")}>For alert("Against vote casted")}>Against Timeline } > Executable Code } > Here will be a list of decoded calldatas ) } const VotingTimeline = ({ proposalId, chainId }) => { const { delay: propsalVotingDelay } = useProposalVotingDelay(chainId, proposalId); const { snapshot: proposalSnapshot } = useProposalSnapshot(chainId, proposalId); const { deadline: proposalDeadline } = useProposalDeadline(chainId, proposalId); const voteStarted = useMemo(() => { if (proposalSnapshot && propsalVotingDelay) { return proposalSnapshot > propsalVotingDelay ? proposalSnapshot - propsalVotingDelay : 0; } return 0; }, [proposalSnapshot, propsalVotingDelay]); return ( ) } const VotingTimelineItem = ({ isFirst, isLast, time, message }) => { return ( {!isFirst && } {!isLast && } {message} {new Date(time * 1000).toLocaleString()} ) } export default ProposalDetails;