import { useState, useMemo } from "react";
import { useNavigate, useParams } from "react-router-dom";
import {
Box,
Link,
Tabs,
Tab,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography,
useTheme,
useMediaQuery
} from "@mui/material";
import { getBlockNumber } from "@wagmi/core";
import GhostStyledIcon from "../../../components/Icon/GhostIcon";
import ArrowUpIcon from "../../../assets/icons/arrow-up.svg?react";
import { networkAvgBlockSpeed } from "../../../constants";
import { prettifySecondsInDays, prettifySeconds } from "../../../helpers/timeUtil";
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import Chip from "../../../components/Chip/Chip";
import Modal from "../../../components/Modal/Modal";
import Paper from "../../../components/Paper/Paper";
import LinearProgressBar from "../../../components/Progress/LinearProgressBar";
import { PrimaryButton, TertiaryButton } from "../../../components/Button";
import ProposalInfoText from "./ProposalInfoText";
import {
convertStatusToColor,
convertStatusToLabel,
MY_PROPOSALS_PREFIX,
VOTED_PROPOSALS_PREFIX
} from "../helpers";
import { useScreenSize } from "../../../hooks/useScreenSize";
import { useProposals } from "../../../hooks/governance";
import { useLocalStorage } from "../../../hooks/localstorage";
const MAX_PROPOSALS_TO_SHOW = 10;
const ProposalsList = ({ chainId, address, config }) => {
const isSmallScreen = useScreenSize("md");
const navigate = useNavigate();
const theme = useTheme();
const { network } = useParams();
const { getStorageValue, setStorageValue } = useLocalStorage();
const [proposalsFilter, setProposalFilter] = useState("active");
const myStoredProposals = getStorageValue(chainId, address, MY_PROPOSALS_PREFIX, []);
const [myProposals, setMyProposals] = useState(() => myStoredProposals.map(id => BigInt(id)));
const storedVotedProposals = getStorageValue(chainId, address, VOTED_PROPOSALS_PREFIX, []);
const [votedProposals, setVotedProposals] = useState(() => storedVotedProposals.map(id => BigInt(id)));
const searchedIndexes = useMemo(() => {
switch (proposalsFilter) {
case "voted":
return votedProposals;
case "created":
return myProposals;
default:
return undefined;
}
}, [proposalsFilter]);
const [blockNumber, setBlockNumber] = useState(0n);
const { proposals } = useProposals(chainId, MAX_PROPOSALS_TO_SHOW, searchedIndexes);
getBlockNumber(config).then(block => setBlockNumber(block));
if (proposals?.length === 0 && proposalsFilter === "active") {
return (
No proposals yet
);
}
if (isSmallScreen) {
return (
Proposals
}
>
{proposals?.map(proposal => (
navigate(`${network}/governance/${proposal.hashes.full}`)}
/>
))}
{proposalsFilter === "active" &&
}
);
}
return (
Proposals
View Forum
}
>
{proposals?.map(proposal => (
navigate(`/${network}/governance/${proposal.hashes.full}`)}
/>
))}
{proposalsFilter === "active" &&
}
);
}
const ProposalTable = ({ children }) => (
Proposal ID
Status
Vote Ends
Voting Stats
{children}
);
const ProposalRow = ({ proposal, blockNumber, openProposal, chainId }) => {
const theme = useTheme();
return (
GDP-{proposal.hashes.short}
{convertDeadline(
proposal.deadline,
blockNumber,
chainId
)}
{(proposal.state === "Active" || proposal.state === "Succeeded") && openProposal()}
sx={{ maxWidth: "130px" }}
>
{proposal.state === "Succeeded" ? "Execute" : "Vote"}
}
{(proposal.state !== "Active" && proposal.state !== "Succeeded") && openProposal()}
sx={{ alignSelf: "right", maxWidth: "130px" }}
>
View
}
);
}
const ProposalCard = ({ proposal, blockNumber, openProposal, chainId }) => {
const theme = useTheme();
const isSmallScreen = useMediaQuery('(max-width: 450px)');
return (
GIP-{proposal.hashes.short}
{convertDeadline(
proposal.deadline,
blockNumber,
chainId
)}
{(proposal.state === "Active" || proposal.state === "Succeeded") && openProposal()}
>
{proposal.state === "Succeeded" ? "Execute" : "Vote"}
}
{(proposal.state !== "Active" && proposal.state !== "Succeeded") && openProposal()}
>
View
}
);
};
const ProposalFilterTrigger = ({ trigger, setTrigger }) => {
return (
setTrigger(view)}
TabIndicatorProps={{ style: { display: "none" } }}
>
)
}
const convertDeadline = (deadline, blockNumber, chainId) => {
const alreadyHappened = blockNumber > deadline;
const diff = alreadyHappened ? blockNumber - deadline : deadline - blockNumber;
const voteSeconds = Number(diff * networkAvgBlockSpeed(chainId));
const result = prettifySeconds(voteSeconds, "min");
if (result === "now") {
return new Date(Date.now()).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
}
const prefix = alreadyHappened ? "" : "in ";
const postfix = alreadyHappened ? " ago" : "";
return `${prefix}${result}${postfix}`;
}
export default ProposalsList;