import { useState, useMemo, useCallback, useEffect } from "react"; import ReactGA from "react-ga4"; import { Box, Container, TableContainer, Table, TableRow, TableBody, TableHead, TableCell, Typography, Link, OutlinedInput, InputLabel, FormControl, useMediaQuery, useTheme } from "@mui/material"; import GhostStyledIcon from "../../components/Icon/GhostIcon"; import ArrowUpIcon from "../../assets/icons/arrow-up.svg?react"; import { GHOST_GOVERNANCE_ADDRESSES, GHST_ADDRESSES } from "../../constants/addresses"; import Paper from "../../components/Paper/Paper"; import PageTitle from "../../components/PageTitle/PageTitle"; import { PrimaryButton, TertiaryButton } from "../../components/Button"; import { TokenAllowanceGuard } from "../../components/TokenAllowanceGuard/TokenAllowanceGuard"; import { useTokenSymbol, useBalance } from "../../hooks/tokens"; import { useProposalThreshold, useProposalHash, propose } from "../../hooks/governance"; import { DecimalBigNumber } from "../../helpers/DecimalBigNumber"; import ProposalModal from "./components/ProposalModal"; import { parseFunctionCalldata } from "./components/functions/index"; import { MY_PROPOSALS_PREFIX } from "./helpers"; const NewProposal = ({ config, address, connect, chainId }) => { const isSemiSmallScreen = useMediaQuery("(max-width: 745px)"); const isSmallScreen = useMediaQuery("(max-width: 650px)"); const isVerySmallScreen = useMediaQuery("(max-width: 379px)"); const theme = useTheme(); const myStoredProposals = localStorage.getItem(`${MY_PROPOSALS_PREFIX}-${address}`); const [myProposals, setMyProposals] = useState( myStoredProposals ? JSON.parse(myStoredProposals).map(id => BigInt(id)) : [] ); const [isPending, setIsPending] = useState(false); const [isModalOpened, setIsModalOpened] = useState(false); const [proposalFunctions, setProposalFunctions] = useState([]); const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO"); const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST"); const { balance: ghstBalance } = useBalance(chainId, ghstSymbol, address) const { threshold } = useProposalThreshold(chainId, ghstSymbol); const { proposalHash, proposalDescription } = useProposalHash(chainId, proposalFunctions); useEffect(() => { const toStore = JSON.stringify(myProposals.map(id => id.toString())); localStorage.setItem(`${MY_PROPOSALS_PREFIX}-${address}`, toStore); }, [myProposals]); useEffect(() => { ReactGA.send({ hitType: "pageview", page: "/governance/create" }); }, []); const addCalldata = (calldata) => setProposalFunctions(prev => [...prev, calldata]); const removeCalldata = (index) => setProposalFunctions(prev => prev.filter((_, i) => i !== index)); const storeProposal = (proposalId) => setMyProposals(prev => [...prev, proposalId]); const removeProposal = (proposalId) => setMyProposals(prev => prev.filter(item => item !== proposalId)); const nativeCurrency = useMemo(() => { const client = config?.getClient(); return client?.chain?.nativeCurrency?.symbol; }, [config]); const submitProposal = useCallback(async () => { setIsPending(true); const result = await propose(chainId, address, proposalFunctions, proposalDescription); if (result) { storeProposal(proposalHash); setProposalFunctions([]); } setIsPending(false); }, [chainId, address, proposalHash, proposalFunctions, proposalDescription]); return ( <> setIsModalOpened(false)} /> Proposal Functions } topRight={ Explore Governance } > {proposalFunctions.length === 0 && Create new proposal by adding one or more of the functions below. } setIsModalOpened(true)} > Add New Function submitProposal()} > {isPending ? "Submitting..." : "Submit Proposal"} {proposalFunctions.length > 0 && Proposal Functions } > Function Target Calldata Value {proposalFunctions.map((metadata, index) => { return parseFunctionCalldata(metadata, index, chainId, nativeCurrency, removeCalldata); })}
} ) } export default NewProposal;