diff --git a/components/WalletContainer.tsx b/components/WalletContainer.tsx index b053356..45cbea2 100644 --- a/components/WalletContainer.tsx +++ b/components/WalletContainer.tsx @@ -38,6 +38,17 @@ const WalletContainer = () => { query: { enabled: !!ensName }, }); + if (!isConnected) { + return ( + + ); + } + return ( } ); }; diff --git a/components/nav/navbar.tsx b/components/nav/navbar.tsx index bfa7241..403b2d3 100644 --- a/components/nav/navbar.tsx +++ b/components/nav/navbar.tsx @@ -28,7 +28,7 @@ export const Navbar: React.FC = () => { diff --git a/components/proposalAction/proposalAction.tsx b/components/proposalAction/proposalAction.tsx index 7617322..d21ec17 100644 --- a/components/proposalAction/proposalAction.tsx +++ b/components/proposalAction/proposalAction.tsx @@ -86,7 +86,7 @@ const ActionItem = ({ index, rawAction }: { index: number; rawAction: RawAction - {title} + {title} diff --git a/plugins/maciVoting/components/VoteResultCard.tsx b/plugins/maciVoting/components/VoteResultCard.tsx index dee212b..18b59d9 100644 --- a/plugins/maciVoting/components/VoteResultCard.tsx +++ b/plugins/maciVoting/components/VoteResultCard.tsx @@ -100,7 +100,7 @@ export const VoteResultCard = ({ results }: VoteResultCardProps) => { -
+
= ({ proposal, proposalMetad
{/* Wrapper */} + + + + + Back + {/* Title & description */}
diff --git a/plugins/maciVoting/components/proposal/index.tsx b/plugins/maciVoting/components/proposal/index.tsx index 15a381c..a5880e9 100644 --- a/plugins/maciVoting/components/proposal/index.tsx +++ b/plugins/maciVoting/components/proposal/index.tsx @@ -51,15 +51,7 @@ export default function ProposalCard(props: ProposalInputs) { const winningOption = getWinningOption(proposal?.tally as Tally); if (!proposal && showLoading) { - return ( -
- - - - - -
- ); + return ; } else if (!proposalMetadata?.title && !proposalMetadata?.summary) { // We have the proposal but no metadata yet return ( diff --git a/plugins/maciVoting/pages/new.tsx b/plugins/maciVoting/pages/new.tsx index f6d1efe..92eb77a 100644 --- a/plugins/maciVoting/pages/new.tsx +++ b/plugins/maciVoting/pages/new.tsx @@ -15,6 +15,7 @@ import { NEXT_MINIMUM_START_DELAY_IN_SECONDS, PUBLIC_CHAIN, PUBLIC_MACI_VOTING_P import { ActionCard } from "@/components/actions/action"; import { useMutation } from "@tanstack/react-query"; import classNames from "classnames"; +import Link from "next/link"; enum ActionType { Signaling, @@ -38,6 +39,15 @@ export default function Create() { const { writeContract: createProposalWrite, data: createTxHash, status, error } = useWriteContract(); const { isLoading: isConfirming, isSuccess: isConfirmed } = useWaitForTransactionReceipt({ hash: createTxHash }); const [actionType, setActionType] = useState(ActionType.Signaling); + const [errors, setErrors] = useState<{ + title?: string; + summary?: string; + description?: string; + startDate?: string; + endDate?: string; + withdrawal?: string; + custom?: string; + }>({}); const changeActionType = (actionType: ActionType) => { setActions([]); @@ -82,20 +92,21 @@ export default function Create() { }, [status, createTxHash, isConfirming, isConfirmed, error, push]); const submitProposal = async () => { + let formErrors = {}; try { // Check metadata if (!title.trim()) { - return addAlert("Invalid proposal details", { - description: "Please, enter a title", - type: "error", - }); + formErrors = { + ...formErrors, + title: "Please, enter a title", + }; } if (!summary.trim()) { - return addAlert("Invalid proposal details", { - description: "Please, enter a summary of what the proposal is about", - type: "error", - }); + formErrors = { + ...formErrors, + summary: "Please, enter a summary of what the proposal is about", + }; } // Check the action @@ -104,18 +115,18 @@ export default function Create() { break; case ActionType.Withdrawal: if (!actions.length) { - return addAlert("Invalid proposal details", { - description: "Please ensure that the withdrawal address and the amount to transfer are valid", - type: "error", - }); + formErrors = { + ...formErrors, + withdrawal: "Please ensure that the withdrawal address and the amount to transfer are valid", + }; } break; default: if (!actions.length || !actions[0].data || actions[0].data === "0x") { - return addAlert("Invalid proposal details", { - description: "Please ensure that the values of the action to execute are complete and correct", - type: "error", - }); + formErrors = { + ...formErrors, + custom: "Please ensure that the values of the action to execute are complete and correct", + }; } } @@ -132,21 +143,20 @@ export default function Create() { const ipfsPin = await uploadToPinata(blob); if (!startDate || !endDate) { - addAlert("You need to specify the start date and end date of the voting period", { - timeout: 4 * 1000, - }); - return null; + formErrors = { + ...formErrors, + startDate: "You need to specify the start date and end date of the voting period", + }; } const currentTime = Math.floor(Date.now() / 1000); const startDateTime = Math.floor(new Date(`${startDate}T${startTime ? startTime : "00:00:00"}`).getTime() / 1000); if (startDateTime - currentTime < NEXT_MINIMUM_START_DELAY_IN_SECONDS) { - addAlert(`The start date must be at least ${NEXT_MINIMUM_START_DELAY_IN_SECONDS} seconds in the future`, { - timeout: 4 * 1000, - type: "error", - }); - return null; + formErrors = { + ...formErrors, + startDate: `The start date must be at least ${NEXT_MINIMUM_START_DELAY_IN_SECONDS} seconds in the future`, + }; } const endDateTime = Math.floor(new Date(`${endDate}T${endTime ? endTime : "00:00:00"}`).getTime() / 1000); @@ -160,6 +170,11 @@ export default function Create() { tryEarlyExecution, ]); + if (Object.keys(formErrors).length > 0) { + setErrors(formErrors); + return; + } + if (chainId !== PUBLIC_CHAIN.id) await switchChainAsync({ chainId: PUBLIC_CHAIN.id }); createProposalWrite({ chainId: PUBLIC_CHAIN.id, @@ -199,11 +214,20 @@ export default function Create() { const isDisabled = submitProposalMutation.isPending || isConfirming; return (
+ + + + + Back +

Create Proposal

setStartDate(e.target.value)} @@ -260,7 +284,7 @@ export default function Create() { setEndDate(e.target.value)} @@ -341,6 +365,14 @@ export default function Create() {
+
+ {Object.entries(errors).map(([key, value]) => ( +
+ {value} +
+ ))} +
+
diff --git a/plugins/maciVoting/pages/proposal.tsx b/plugins/maciVoting/pages/proposal.tsx index 0c0f50c..18cbf2a 100644 --- a/plugins/maciVoting/pages/proposal.tsx +++ b/plugins/maciVoting/pages/proposal.tsx @@ -23,9 +23,20 @@ export default function ProposalDetail({ id: proposalId }: { id: string }) { if (!proposal || !proposalMetadata || !creator || showProposalLoading) { return ( -
- -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
); } @@ -41,7 +52,7 @@ export default function ProposalDetail({ id: proposalId }: { id: string }) { />
-
+
diff --git a/tailwind.config.ts b/tailwind.config.ts index e76f491..87a316e 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -11,6 +11,8 @@ const config: Config = { theme: { extend: { colors: { + slate: "#CBD5E1", + danger: "#e7000b", voting: { yes: "#10b981", no: "#dc2626",