generated from scaffold-eth/scaffold-eth-2
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
dad3627
commit 66fff58
Showing
6 changed files
with
298 additions
and
28 deletions.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
packages/nextjs/app/admin/_components/BatchActionModal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { forwardRef, useRef } from "react"; | ||
import { useBatchReviewGrants } from "../hooks/useBatchReviewGrants"; | ||
import { PROPOSAL_STATUS } from "~~/utils/grants"; | ||
|
||
type BatchActionModalProps = { | ||
selectedGrants: string[]; | ||
initialTxLink?: string; | ||
btnLabel: "Approve" | "Complete"; | ||
closeModal: () => void; | ||
}; | ||
|
||
export const BatchActionModal = forwardRef<HTMLDialogElement, BatchActionModalProps>( | ||
({ selectedGrants, initialTxLink, closeModal, btnLabel }, ref) => { | ||
const inputRef = useRef<HTMLInputElement>(null); | ||
|
||
const { handleBatchReview, isLoading } = useBatchReviewGrants(); | ||
|
||
return ( | ||
<dialog id="action_modal" className="modal" ref={ref}> | ||
<div className="modal-box flex flex-col space-y-3"> | ||
<form method="dialog"> | ||
{/* if there is a button in form, it will close the modal */} | ||
<button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button> | ||
</form> | ||
<p className="font-bold text-lg m-0">{btnLabel} this grant</p> | ||
<input | ||
type="text" | ||
ref={inputRef} | ||
defaultValue={initialTxLink ?? ""} | ||
placeholder="Transaction hash" | ||
className="input input-bordered" | ||
/> | ||
<button | ||
className={`btn btn-sm btn-success ${isLoading ? "opacity-50" : ""}`} | ||
onClick={async () => { | ||
await handleBatchReview( | ||
selectedGrants, | ||
btnLabel === "Approve" ? PROPOSAL_STATUS.APPROVED : PROPOSAL_STATUS.COMPLETED, | ||
inputRef.current?.value, | ||
); | ||
closeModal(); | ||
}} | ||
disabled={isLoading} | ||
> | ||
{isLoading && <span className="loading loading-spinner"></span>} | ||
{btnLabel} | ||
</button> | ||
</div> | ||
</dialog> | ||
); | ||
}, | ||
); | ||
|
||
BatchActionModal.displayName = "BatchActionModal"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { useSWRConfig } from "swr"; | ||
import useSWRMutation from "swr/mutation"; | ||
import { useAccount, useSignTypedData } from "wagmi"; | ||
import { EIP_712_DOMAIN, EIP_712_TYPES__REVIEW_GRANT_BATCH } from "~~/utils/eip712"; | ||
import { ProposalStatusType } from "~~/utils/grants"; | ||
import { getParsedError, notification } from "~~/utils/scaffold-eth"; | ||
import { postMutationFetcher } from "~~/utils/swr"; | ||
|
||
type BatchReqBody = { | ||
signer: string; | ||
signature: `0x${string}`; | ||
reviews: { | ||
grantId: string; | ||
action: ProposalStatusType; | ||
txHash: string; | ||
}[]; | ||
}; | ||
|
||
export const useBatchReviewGrants = () => { | ||
const { signTypedDataAsync, isLoading: isSigningMessage } = useSignTypedData(); | ||
const { mutate } = useSWRConfig(); | ||
const { address: connectedAddress } = useAccount(); | ||
const { trigger: postBatchReviewGrant, isMutating: isPostingBatchReviewGrant } = useSWRMutation( | ||
`/api/grants/review`, | ||
postMutationFetcher<BatchReqBody>, | ||
); | ||
|
||
const handleBatchReview = async (selectedGrants: string[], action: ProposalStatusType, txHash = "") => { | ||
if (!connectedAddress) { | ||
notification.error("No connected address"); | ||
return; | ||
} | ||
|
||
const grantReviews = selectedGrants.map(grantId => { | ||
return { | ||
grantId, | ||
action, | ||
txHash, | ||
}; | ||
}); | ||
|
||
try { | ||
const message = { reviews: grantReviews }; | ||
const signature = await signTypedDataAsync({ | ||
domain: EIP_712_DOMAIN, | ||
types: EIP_712_TYPES__REVIEW_GRANT_BATCH, | ||
primaryType: "Message", | ||
message: message, | ||
}); | ||
|
||
await postBatchReviewGrant({ | ||
signature: signature, | ||
reviews: grantReviews, | ||
signer: connectedAddress, | ||
}); | ||
await mutate("/api/grants/review"); | ||
notification.success(`Grants reviews successfully submitted!`); | ||
} catch (error) { | ||
const parsedError = getParsedError(error); | ||
notification.error(parsedError); | ||
} | ||
}; | ||
|
||
return { | ||
handleBatchReview, | ||
isLoading: isSigningMessage || isPostingBatchReviewGrant, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters