diff --git a/src/pages/proposal-page.tsx b/src/pages/proposal-page.tsx
index cd924e6..0244b79 100644
--- a/src/pages/proposal-page.tsx
+++ b/src/pages/proposal-page.tsx
@@ -1,10 +1,12 @@
+import { useState } from 'react'
import { redirect, useParams } from 'react-router-dom'
+import Long from 'long'
import { VoteOptionType } from 'types'
import { throwError } from 'util/errors'
import { ROUTE_PATH } from 'routes'
-import { voteOnProposal } from 'api/proposal.actions'
+import { executeProposal, voteOnProposal } from 'api/proposal.actions'
import {
useGroup,
useGroupMembers,
@@ -16,12 +18,19 @@ import {
import { useTxToasts } from 'hooks/use-toasts'
import { Button, PageContainer, RouteLink, Stack } from '@/atoms'
+import {
+ FormFooter,
+ FormSubmitHiddenButton,
+ useFormFooter,
+} from '@/molecules/form-footer'
import { Loading } from '@/molecules/loading'
import { ProposalDetails } from '@/organisms/proposal-details'
import { ProposalFinalTallyTable } from '@/organisms/proposal-final-tally-table'
import { ProposalSummary } from '@/organisms/proposal-summary'
import { ProposalVotesTable } from '@/organisms/proposal-votes-table'
+import { ProposalStatus } from '../util/enums'
+
import { BackIcon } from 'assets/tsx'
export default function ProposalPage() {
@@ -32,7 +41,11 @@ export default function ProposalPage() {
const { data: historicalProposal, isLoading: isLoadingHistoricalProposal } =
useHistoricalProposal(proposalId)
- const { data: proposal, isLoading: isLoadingProposal } = useProposal(
+ const {
+ data: proposal,
+ isLoading: isLoadingProposal,
+ refetch: refetchProposal,
+ } = useProposal(
proposalId,
!isLoadingHistoricalProposal && !historicalProposal?.historical,
)
@@ -42,6 +55,13 @@ export default function ProposalPage() {
isLoading: isLoadingVotes,
refetch: refetchVotes,
} = useProposalVotes(proposalId)
+ const [submitting, setSubmitting] = useState(false)
+
+ useFormFooter({
+ onNext: undefined,
+ onPrev: undefined,
+ btnText: 'Execute',
+ })
const {
data: userVotes,
@@ -73,6 +93,22 @@ export default function ProposalPage() {
}
}
+ async function handleExec(event) {
+ event.preventDefault()
+ setSubmitting(true)
+ if (!proposalId) throwError('Proposal ID is required to execute proposal')
+ try {
+ const { transactionHash } = await executeProposal({
+ proposalId: Long.fromString(proposalId),
+ })
+ toastSuccess(transactionHash)
+ refetchProposal()
+ } catch (err) {
+ toastErr(err)
+ }
+ setSubmitting(false)
+ }
+
const userVote = userVotes
? userVotes.find((v) => v.proposalId.toString() === proposalId)
: undefined
@@ -90,50 +126,64 @@ export default function ProposalPage() {
isHistorical ? historicalProposal.votingPeriodEnd : proposal.votingPeriodEnd,
).getTime() < now.getTime()
+ const isExecutable =
+ proposal && proposal.status === ProposalStatus.PROPOSAL_STATUS_ACCEPTED
+
return (
-