diff --git a/apps/web/app/home/accept-or-reject-editor.tsx b/apps/web/app/home/accept-or-reject-editor.tsx index decdadd75..a77f49ccd 100644 --- a/apps/web/app/home/accept-or-reject-editor.tsx +++ b/apps/web/app/home/accept-or-reject-editor.tsx @@ -1,11 +1,16 @@ 'use client'; +import cx from 'classnames'; + +import { useState } from 'react'; + import { useSmartAccount } from '~/core/hooks/use-smart-account'; import { useVote } from '~/core/hooks/use-vote'; import { Proposal } from '~/core/io/dto/proposals'; import { SubstreamVote } from '~/core/io/schema'; import { SmallButton } from '~/design-system/button'; +import { Pending } from '~/design-system/pending'; import { Execute } from '~/partials/active-proposal/execute'; @@ -29,13 +34,30 @@ export function AcceptOrRejectEditor({ onchainProposalId, votingContractAddress, }: Props) { - const { vote } = useVote({ + const { vote, status: voteStatus } = useVote({ address: votingContractAddress, onchainProposalId, }); + const [hasApproved, setHasApproved] = useState(false); + const [hasRejected, setHasRejected] = useState(false); + + const hasVoted = voteStatus === 'success'; + const isPendingApproval = hasApproved && voteStatus === 'pending'; + const isPendingRejection = hasRejected && voteStatus === 'pending'; + const smartAccount = useSmartAccount(); + const onApprove = () => { + setHasApproved(true); + vote('ACCEPT'); + }; + + const onReject = () => { + setHasRejected(true); + vote('REJECT'); + }; + if (isProposalExecutable) { return ( @@ -44,8 +66,8 @@ export function AcceptOrRejectEditor({ ); } - if (userVote) { - if (userVote.vote === 'ACCEPT') { + if (userVote || hasVoted) { + if (userVote?.vote === 'ACCEPT' || hasApproved) { return
You accepted
; } @@ -62,13 +84,15 @@ export function AcceptOrRejectEditor({ if (!isProposalEnded && smartAccount) { return ( -
- vote('REJECT')}> - Reject - - vote('ACCEPT')}> - Approve - +
+
+ + Reject + + + Approve + +
); } diff --git a/apps/web/app/home/accept-or-reject-member.tsx b/apps/web/app/home/accept-or-reject-member.tsx index dec232dfe..af7a5c452 100644 --- a/apps/web/app/home/accept-or-reject-member.tsx +++ b/apps/web/app/home/accept-or-reject-member.tsx @@ -1,12 +1,16 @@ 'use client'; import { MemberAccessAbi } from '@geogenesis/sdk/abis'; +import cx from 'classnames'; import { Effect, Either } from 'effect'; import { encodeFunctionData } from 'viem'; +import { useState } from 'react'; + import { useSmartAccountTransaction } from '~/core/hooks/use-smart-account-transaction'; import { SmallButton } from '~/design-system/button'; +import { Pending } from '~/design-system/pending'; function useApproveOrReject(membershipContractAddress: string | null) { const tx = useSmartAccountTransaction({ @@ -36,40 +40,67 @@ interface Props { } export function AcceptOrRejectMember(props: Props) { + const [isPendingApproval, setIsPendingApproval] = useState(false); + const [isPendingRejection, setIsPendingRejection] = useState(false); + const [hasVoted, setHasVoted] = useState(false); + const approveOrReject = useApproveOrReject(props.membershipContractAddress); const onApprove = async () => { - const hash = await approveOrReject( - encodeFunctionData({ - abi: MemberAccessAbi, - functionName: 'approve', - args: [BigInt(props.onchainProposalId)], - }) - ); - - console.log('transaction successful', hash); + try { + setIsPendingApproval(true); + const hash = await approveOrReject( + encodeFunctionData({ + abi: MemberAccessAbi, + functionName: 'approve', + args: [BigInt(props.onchainProposalId)], + }) + ); + console.log('transaction successful', hash); + setHasVoted(true); + setIsPendingApproval(false); + } catch (error) { + console.error(error); + setHasVoted(false); + setIsPendingApproval(false); + } }; const onReject = async () => { - const hash = await approveOrReject( - encodeFunctionData({ - abi: MemberAccessAbi, - functionName: 'reject', - args: [BigInt(props.onchainProposalId)], - }) - ); - - console.log('transaction successful', hash); + try { + setIsPendingRejection(true); + const hash = await approveOrReject( + encodeFunctionData({ + abi: MemberAccessAbi, + functionName: 'reject', + args: [BigInt(props.onchainProposalId)], + }) + ); + console.log('transaction successful', hash); + setHasVoted(true); + setIsPendingRejection(false); + } catch (error) { + console.error(error); + setHasVoted(false); + setIsPendingRejection(false); + } }; return ( -
- - Reject - - - Approve - +
+
+ + Reject + + + Approve + +
+ {hasVoted && ( +
+
Vote registered
+
+ )}
); } diff --git a/apps/web/partials/active-proposal/accept-or-reject.tsx b/apps/web/partials/active-proposal/accept-or-reject.tsx index 135cb8789..bcee6ba1e 100644 --- a/apps/web/partials/active-proposal/accept-or-reject.tsx +++ b/apps/web/partials/active-proposal/accept-or-reject.tsx @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; +import { useState } from 'react'; import { useSmartAccount } from '~/core/hooks/use-smart-account'; import { useVote } from '~/core/hooks/use-vote'; @@ -8,6 +9,7 @@ import { Proposal } from '~/core/io/dto/proposals'; import { SubstreamVote } from '~/core/io/schema'; import { Button } from '~/design-system/button'; +import { Pending } from '~/design-system/pending'; import { Execute } from './execute'; @@ -31,13 +33,30 @@ export function AcceptOrReject({ onchainProposalId, votingContractAddress, }: Props) { - const { vote } = useVote({ + const { vote, status: voteStatus } = useVote({ address: votingContractAddress, onchainProposalId, }); + const [hasApproved, setHasApproved] = useState(false); + const [hasRejected, setHasRejected] = useState(false); + + const hasVoted = voteStatus === 'success'; + const isPendingApproval = hasApproved && voteStatus === 'pending'; + const isPendingRejection = hasRejected && voteStatus === 'pending'; + const smartAccount = useSmartAccount(); + const onApprove = () => { + setHasApproved(true); + vote('ACCEPT'); + }; + + const onReject = () => { + setHasRejected(true); + vote('REJECT'); + }; + if (isProposalExecutable) { return ( @@ -46,8 +65,8 @@ export function AcceptOrReject({ ); } - if (userVote) { - if (userVote.vote === 'ACCEPT') { + if (userVote || hasVoted) { + if (userVote?.vote === 'ACCEPT' || hasApproved) { return
You accepted
; } @@ -64,14 +83,16 @@ export function AcceptOrReject({ if (!isProposalEnded && smartAccount) { return ( -
- - or - +
+
+ + or + +
); }