-
Notifications
You must be signed in to change notification settings - Fork 22
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
Showing
16 changed files
with
428 additions
and
30 deletions.
There are no files selected for viewing
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
1 change: 1 addition & 0 deletions
1
packages/interface/src/features/admin/components/DeployContracts.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 @@ | ||
export const DeployContracts = (): JSX.Element => <div>This is Deploy Contracts</div>; |
147 changes: 147 additions & 0 deletions
147
packages/interface/src/features/admin/components/DeployRounds.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,147 @@ | ||
import { useRouter } from "next/router"; | ||
import { useState, useCallback } from "react"; | ||
import { toast } from "sonner"; | ||
import { useAccount } from "wagmi"; | ||
|
||
import { ImageUpload } from "~/components/ImageUpload"; | ||
import { Steps } from "~/components/Steps"; | ||
import { Form, FormSection, FormControl, Textarea, Select, DateInput } from "~/components/ui/Form"; | ||
import { Heading } from "~/components/ui/Heading"; | ||
import { Input } from "~/components/ui/Input"; | ||
import { RoundSchema, votingStrategyTypes } from "~/features/rounds/types"; | ||
import { useIsCorrectNetwork } from "~/hooks/useIsCorrectNetwork"; | ||
|
||
import { useDeployRound } from "../hooks/useDeployRound"; | ||
|
||
import { DeployRoundsButtons, EDeployRoundsStep } from "./DeployRoundsButtons"; | ||
import { ReviewDeployRoundDetails } from "./ReviewDeployRoundDetails"; | ||
|
||
export const DeployRounds = (): JSX.Element => { | ||
const router = useRouter(); | ||
|
||
const { isCorrectNetwork, correctNetwork } = useIsCorrectNetwork(); | ||
|
||
const { address } = useAccount(); | ||
|
||
const [step, setStep] = useState<EDeployRoundsStep>(EDeployRoundsStep.CONFIGURE); | ||
|
||
const handleNextStep = useCallback(() => { | ||
if (step === EDeployRoundsStep.CONFIGURE) { | ||
setStep(EDeployRoundsStep.REVIEW); | ||
} | ||
}, [step, setStep]); | ||
|
||
const handleBackStep = useCallback(() => { | ||
if (step === EDeployRoundsStep.REVIEW) { | ||
setStep(EDeployRoundsStep.CONFIGURE); | ||
} | ||
}, [step, setStep]); | ||
|
||
const create = useDeployRound({ | ||
onSuccess: () => { | ||
router.push(`/`); | ||
}, | ||
onError: (err: Error) => | ||
toast.error("Round deploy error", { | ||
description: err.message, | ||
}), | ||
}); | ||
|
||
const { error: createError } = create; | ||
|
||
return ( | ||
<div> | ||
<Heading size="4xl">Deploy Round Contracts</Heading> | ||
|
||
<p className="text-gray-400">These round contracts specify the features for this round.</p> | ||
|
||
<div className="dark:border-lighterBlack rounded-lg border border-gray-200 p-4"> | ||
<Steps step={step} stepNames={["Configure Contracts", "Review & Deploy"]} /> | ||
|
||
<Form | ||
defaultValues={{}} | ||
schema={RoundSchema} | ||
onSubmit={(round) => { | ||
create.mutate(round); | ||
}} | ||
> | ||
<FormSection | ||
className={step === EDeployRoundsStep.CONFIGURE ? "block" : "hidden"} | ||
description="Please select from the available options to configure the deployment of this round." | ||
title="Configure Contracts" | ||
> | ||
<FormControl required hint="This is the name of your round" label="Round Name" name="roundId"> | ||
<Input placeholder="Type the name of your round" /> | ||
</FormControl> | ||
|
||
<div className="w-full gap-4 md:flex"> | ||
<FormControl required className="w-full" label="Round Description" name="description"> | ||
<Textarea | ||
className="h-48" | ||
placeholder="Briefly describe your round in a sentence or two (200 characters max)" | ||
/> | ||
</FormControl> | ||
|
||
<FormControl required hint="png or jpg file size 500x500 px" label="Round Logo" name="roundLogo"> | ||
<ImageUpload className="h-48 w-48" /> | ||
</FormControl> | ||
</div> | ||
|
||
<div className="gap-4 md:flex"> | ||
<FormControl required label="Round Starts At" name="startsAt"> | ||
<DateInput /> | ||
</FormControl> | ||
|
||
<FormControl required label="Registration Ends At" name="registrationEndsAt"> | ||
<DateInput /> | ||
</FormControl> | ||
|
||
<FormControl required label="Poll Starts At" name="votingStartsAt"> | ||
<DateInput /> | ||
</FormControl> | ||
|
||
<FormControl required label="Poll Ends At" name="votingEndsAt"> | ||
<DateInput /> | ||
</FormControl> | ||
</div> | ||
|
||
<FormControl required hint="Choose a voting strategy" label="Voting Strategy" name="votingStrategy"> | ||
<Select> | ||
{Object.entries(votingStrategyTypes).map(([value, label]) => ( | ||
<option key={value} value={value}> | ||
{label} | ||
</option> | ||
))} | ||
</Select> | ||
</FormControl> | ||
</FormSection> | ||
|
||
{step === EDeployRoundsStep.REVIEW && <ReviewDeployRoundDetails />} | ||
|
||
{step === EDeployRoundsStep.REVIEW && ( | ||
<div className="mb-2 w-full text-right text-sm italic text-blue-400"> | ||
{!address && <p>You must connect wallet to create an application</p>} | ||
|
||
{!isCorrectNetwork && <p className="gap-2">You must be connected to {correctNetwork.name}</p>} | ||
|
||
{createError && ( | ||
<p> | ||
Make sure you're not connected to a VPN since this can cause problems with the RPC and your | ||
wallet. | ||
</p> | ||
)} | ||
</div> | ||
)} | ||
|
||
<DeployRoundsButtons | ||
isPending={create.isPending} | ||
isUploading={create.isPending} | ||
step={step} | ||
onBackStep={handleBackStep} | ||
onNextStep={handleNextStep} | ||
/> | ||
</Form> | ||
</div> | ||
</div> | ||
); | ||
}; |
104 changes: 104 additions & 0 deletions
104
packages/interface/src/features/admin/components/DeployRoundsButtons.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,104 @@ | ||
import { useMemo, useCallback, useState } from "react"; | ||
import { useAccount } from "wagmi"; | ||
|
||
import { Button, IconButton } from "~/components/ui/Button"; | ||
import { Dialog } from "~/components/ui/Dialog"; | ||
import { Spinner } from "~/components/ui/Spinner"; | ||
import { useIsCorrectNetwork } from "~/hooks/useIsCorrectNetwork"; | ||
|
||
export enum EDeployRoundsStep { | ||
CONFIGURE, | ||
REVIEW, | ||
} | ||
|
||
interface IDeployRoundsButtonsProps { | ||
step: EDeployRoundsStep; | ||
isUploading: boolean; | ||
isPending: boolean; | ||
onNextStep: () => void; | ||
onBackStep: () => void; | ||
} | ||
|
||
export const DeployRoundsButtons = ({ | ||
step, | ||
isUploading, | ||
isPending, | ||
onNextStep, | ||
onBackStep, | ||
}: IDeployRoundsButtonsProps): JSX.Element => { | ||
const { isCorrectNetwork } = useIsCorrectNetwork(); | ||
|
||
const { address } = useAccount(); | ||
|
||
const [showDialog, setShowDialog] = useState<boolean>(false); | ||
|
||
const stepComplete = useMemo((): boolean => { | ||
if (step === EDeployRoundsStep.CONFIGURE) { | ||
return true; | ||
} | ||
|
||
return true; | ||
}, []); | ||
|
||
const handleOnClickNextStep = useCallback( | ||
(event: UIEvent) => { | ||
event.preventDefault(); | ||
|
||
if (stepComplete) { | ||
onNextStep(); | ||
} else { | ||
setShowDialog(true); | ||
} | ||
}, | ||
[onNextStep, setShowDialog, stepComplete], | ||
); | ||
|
||
const handleOnClickBackStep = useCallback( | ||
(event: UIEvent) => { | ||
event.preventDefault(); | ||
onBackStep(); | ||
}, | ||
[onBackStep], | ||
); | ||
|
||
const handleOnOpenChange = useCallback(() => { | ||
setShowDialog(false); | ||
}, [setShowDialog]); | ||
|
||
return ( | ||
<div className="flex justify-end gap-2"> | ||
<Dialog | ||
description="There are still some inputs not fulfilled, please complete all the required information." | ||
isOpen={showDialog} | ||
size="sm" | ||
title="Please complete all the required information" | ||
onOpenChange={handleOnOpenChange} | ||
/> | ||
|
||
{step !== EDeployRoundsStep.CONFIGURE && ( | ||
<Button className="text-gray-300 underline" size="auto" variant="ghost" onClick={handleOnClickBackStep}> | ||
Back | ||
</Button> | ||
)} | ||
|
||
{step !== EDeployRoundsStep.REVIEW && ( | ||
<Button size="auto" variant="primary" onClick={handleOnClickNextStep}> | ||
Next | ||
</Button> | ||
)} | ||
|
||
{step === EDeployRoundsStep.REVIEW && ( | ||
<IconButton | ||
disabled={isPending || !address || !isCorrectNetwork} | ||
icon={isPending ? Spinner : null} | ||
isLoading={isPending} | ||
size="auto" | ||
type="submit" | ||
variant="primary" | ||
> | ||
{isUploading ? "Uploading..." : "Submit"} | ||
</IconButton> | ||
)} | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.