11"use client" ;
22
3- import { useDisclosure } from "@chakra-ui/react" ;
3+ import {
4+ Sheet ,
5+ SheetContent ,
6+ SheetHeader ,
7+ SheetTitle ,
8+ SheetTrigger ,
9+ } from "@/components/ui/sheet" ;
10+ import { FormControl , Textarea } from "@chakra-ui/react" ;
411import { TransactionButton } from "components/buttons/TransactionButton" ;
12+ import { useTrack } from "hooks/analytics/useTrack" ;
513import { PlusIcon } from "lucide-react" ;
14+ import { useState } from "react" ;
15+ import { useForm } from "react-hook-form" ;
16+ import { toast } from "sonner" ;
617import type { ThirdwebContract } from "thirdweb" ;
18+ import * as VoteExt from "thirdweb/extensions/vote" ;
719import { useSendAndConfirmTransaction } from "thirdweb/react" ;
8- import { Button , Drawer } from "tw-components" ;
9- import { CreateProposalForm } from "./proposal-form" ;
20+ import { Button , FormErrorMessage , FormLabel } from "tw-components" ;
1021
1122interface VoteButtonProps {
1223 contract : ThirdwebContract ;
@@ -15,55 +26,93 @@ interface VoteButtonProps {
1526const PROPOSAL_FORM_ID = "proposal-form-id" ;
1627
1728export const ProposalButton : React . FC < VoteButtonProps > = ( { contract } ) => {
18- const { isOpen, onOpen, onClose } = useDisclosure ( ) ;
19-
29+ const [ open , setOpen ] = useState ( false ) ;
2030 const sendTx = useSendAndConfirmTransaction ( ) ;
21-
31+ const {
32+ register,
33+ handleSubmit,
34+ formState : { errors } ,
35+ } = useForm < { description : string } > ( ) ;
36+ const trackEvent = useTrack ( ) ;
2237 return (
23- < >
24- < Drawer
25- size = "md"
26- isOpen = { isOpen }
27- onClose = { onClose }
28- header = { { children : < > Create new proposal</ > } }
29- footer = { {
30- children : (
31- < >
32- < Button
33- isDisabled = { sendTx . isPending }
34- variant = "outline"
35- mr = { 3 }
36- onClick = { onClose }
37- >
38- Cancel
39- </ Button >
40- < TransactionButton
41- txChainID = { contract . chain . id }
42- transactionCount = { 1 }
43- isLoading = { sendTx . isPending }
44- form = { PROPOSAL_FORM_ID }
45- type = "submit"
46- colorScheme = "primary"
47- >
48- Submit Proposal
49- </ TransactionButton >
50- </ >
51- ) ,
52- } }
53- >
54- < CreateProposalForm
55- formId = { PROPOSAL_FORM_ID }
56- contract = { contract }
57- sendTx = { sendTx }
58- />
59- </ Drawer >
60- < Button
61- colorScheme = "primary"
62- onClick = { onOpen }
63- leftIcon = { < PlusIcon className = "size-5" /> }
64- >
65- Create Proposal
66- </ Button >
67- </ >
38+ < Sheet open = { open } onOpenChange = { setOpen } >
39+ < SheetTrigger asChild >
40+ < Button
41+ colorScheme = "primary"
42+ leftIcon = { < PlusIcon className = "size-5" /> }
43+ >
44+ Create Proposal
45+ </ Button >
46+ </ SheetTrigger >
47+ < SheetContent className = "z-[10000] w-full sm:w-[540px] sm:max-w-[90%] lg:w-[700px]" >
48+ < SheetHeader >
49+ < SheetTitle > Create new proposal</ SheetTitle >
50+ </ SheetHeader >
51+ < form
52+ className = "mt-10 flex flex-col gap-6"
53+ id = { PROPOSAL_FORM_ID }
54+ onSubmit = { handleSubmit ( ( data ) => {
55+ const tx = VoteExt . propose ( {
56+ contract,
57+ calldatas : [ "0x" ] ,
58+ values : [ 0n ] ,
59+ targets : [ contract . address ] ,
60+ description : data . description ,
61+ } ) ;
62+ toast . promise (
63+ sendTx . mutateAsync ( tx , {
64+ onSuccess : ( ) => {
65+ trackEvent ( {
66+ category : "vote" ,
67+ action : "create-proposal" ,
68+ label : "success" ,
69+ } ) ;
70+ setOpen ( false ) ;
71+ } ,
72+ onError : ( error ) => {
73+ console . error ( error ) ;
74+ trackEvent ( {
75+ category : "vote" ,
76+ action : "create-proposal" ,
77+ label : "error" ,
78+ error,
79+ } ) ;
80+ } ,
81+ } ) ,
82+ {
83+ loading : "Creating proposal..." ,
84+ success : "Proposal created successfully" ,
85+ error : "Failed to create proposal" ,
86+ } ,
87+ ) ;
88+ } ) }
89+ >
90+ < FormControl isRequired isInvalid = { ! ! errors . description } >
91+ < FormLabel > Description</ FormLabel >
92+ < Textarea { ...register ( "description" ) } />
93+ < FormErrorMessage > { errors ?. description ?. message } </ FormErrorMessage >
94+ </ FormControl >
95+ </ form >
96+ < div className = "mt-6 flex flex-row justify-end gap-3" >
97+ < Button
98+ isDisabled = { sendTx . isPending }
99+ variant = "outline"
100+ onClick = { ( ) => setOpen ( false ) }
101+ >
102+ Cancel
103+ </ Button >
104+ < TransactionButton
105+ txChainID = { contract . chain . id }
106+ transactionCount = { 1 }
107+ isLoading = { sendTx . isPending }
108+ form = { PROPOSAL_FORM_ID }
109+ type = "submit"
110+ colorScheme = "primary"
111+ >
112+ Submit
113+ </ TransactionButton >
114+ </ div >
115+ </ SheetContent >
116+ </ Sheet >
68117 ) ;
69118} ;
0 commit comments