Skip to content

Commit

Permalink
Merge pull request #532 from privacy-scaling-explorations/chore/ballo…
Browse files Browse the repository at this point in the history
…t-submission

chore: improve the ballot submission process
  • Loading branch information
crisgarner authored Dec 11, 2024
2 parents 6d9d6d9 + 4a8e00a commit ccaa683
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 45 deletions.
14 changes: 13 additions & 1 deletion packages/interface/src/components/BallotOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Link from "next/link";
import { useRouter } from "next/router";
import { useMemo } from "react";

import { Button } from "~/components/ui/Button";
import { Heading } from "~/components/ui/Heading";
import { useBallot } from "~/contexts/Ballot";
import { useRoundState } from "~/utils/state";
Expand All @@ -21,6 +23,10 @@ export const BallotOverview = ({ title = undefined, pollId }: IBallotOverviewPro

const roundState = useRoundState({ pollId });

const { asPath } = useRouter();

const showButton = useMemo(() => !asPath.includes("ballot"), [asPath]);

return (
<Link
href={
Expand All @@ -29,14 +35,20 @@ export const BallotOverview = ({ title = undefined, pollId }: IBallotOverviewPro
: `/rounds/${pollId}/ballot`
}
>
<div className="dark:bg-lightBlack my-8 flex-col items-center gap-2 rounded-lg bg-white p-5 uppercase shadow-lg dark:text-white">
<div className="dark:bg-lightBlack w-64 flex-col items-center gap-2 bg-white uppercase dark:text-white">
<Heading as="h3" size="3xl">
{title}
</Heading>

<AddedProjects pollId={pollId} />

<VotingUsage pollId={pollId} />

{showButton && (
<Button className="mt-2" variant="secondary">
Check My Ballot
</Button>
)}
</div>
</Link>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/interface/src/components/Info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const Info = ({
];

return (
<div className="flex w-full justify-center">
<div className="flex w-full justify-center pb-3">
<InfoContainer size={size}>
{showRoundInfo && <RoundInfo roundId={round?.roundId ?? ""} />}

Expand Down
11 changes: 8 additions & 3 deletions packages/interface/src/contexts/Maci.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,19 @@ export const MaciProvider: React.FC<MaciProviderProps> = ({ children }: MaciProv

// function to be used to vote on a poll
const onVote = useCallback(
async (votes: IVoteArgs[], pollId: string, onError: () => Promise<void>, onSuccess: () => Promise<void>) => {
async (
votes: IVoteArgs[],
pollId: string,
onError: (err: string) => Promise<void>,
onSuccess: () => Promise<void>,
) => {
if (!signer || !stateIndex) {
return;
}

if (!votes.length) {
onError();
setError("No votes provided");
onError("No votes provided");
return;
}

Expand All @@ -307,7 +312,7 @@ export const MaciProvider: React.FC<MaciProviderProps> = ({ children }: MaciProv
.then(() => onSuccess())
.catch((err: Error) => {
setError(err.message);
return onError();
return onError(err.message);
})
.finally(() => {
setIsLoading(false);
Expand Down
2 changes: 1 addition & 1 deletion packages/interface/src/contexts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface MaciContextType {
onVote: (
args: IVoteArgs[],
pollId: string,
onError: () => void | Promise<void>,
onError: (err: string) => void | Promise<void>,
onSuccess: () => void | Promise<void>,
) => Promise<void>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useRouter } from "next/router";
import { useState, useCallback, useMemo } from "react";
import { useCallback, useMemo } from "react";
import { toast } from "sonner";

import { Button } from "~/components/ui/Button";
import { Dialog } from "~/components/ui/Dialog";
import { Spinner } from "~/components/ui/Spinner";
import { useBallot } from "~/contexts/Ballot";
import { useMaci } from "~/contexts/Maci";

Expand All @@ -13,21 +13,22 @@ interface ISubmitBallotButtonProps {

export const SubmitBallotButton = ({ pollId }: ISubmitBallotButtonProps): JSX.Element => {
const router = useRouter();
const [isOpen, setOpen] = useState(false);
const { onVote, isLoading, initialVoiceCredits } = useMaci();
const { getBallot, publishBallot, sumBallot } = useBallot();

const onVotingError = useCallback(() => {
toast.error("Voting error");
const onVotingError = useCallback((err: string) => {
toast.error(`Voting error: ${err}`);
}, []);

const ballot = useMemo(() => getBallot(pollId), [pollId, getBallot]);
const ableToSubmit = useMemo(
() => sumBallot(ballot.votes) <= initialVoiceCredits,
[sumBallot, ballot, initialVoiceCredits],
);
const sum = useMemo(() => sumBallot(ballot.votes), [ballot, sumBallot]);
const ableToSubmit = useMemo(() => sum <= initialVoiceCredits && sum > 0, [sum, initialVoiceCredits]);

const handleSubmitBallot = useCallback(async () => {
if (isLoading || !ableToSubmit) {
return;
}

const votes = ballot.votes.map(({ amount, projectId, projectIndex }) => ({
projectId,
voteOptionIndex: BigInt(projectIndex),
Expand All @@ -42,38 +43,17 @@ export const SubmitBallotButton = ({ pollId }: ISubmitBallotButtonProps): JSX.El
publishBallot(pollId);
router.push(`/rounds/${pollId}/ballot/confirmation`);
});
}, [ballot, router, onVote, publishBallot, onVotingError, pollId, pollId]);

const handleOpenDialog = useCallback(() => {
setOpen(true);
}, [setOpen]);
}, [ballot, router, onVote, publishBallot, onVotingError, pollId, isLoading, ableToSubmit]);

return (
<>
<Button variant={ableToSubmit ? "primary" : "disabled"} onClick={handleOpenDialog}>
{ableToSubmit ? "submit your ballot" : "Exceed initial voice credits"}
</Button>
<Button variant={ableToSubmit && !isLoading ? "primary" : "disabled"} onClick={handleSubmitBallot}>
{ableToSubmit && !isLoading && "submit your ballot"}

{sum > initialVoiceCredits && !isLoading && "Exceed initial voice credits"}

<Dialog
button="primary"
buttonAction={handleSubmitBallot}
buttonName="submit"
description="This is not the final submission. Once you submit your ballot, you can change it during the voting period."
isLoading={isLoading}
isOpen={ableToSubmit && isOpen}
size="sm"
title="submit your ballot"
onOpenChange={setOpen}
/>
{sum <= 0 && !isLoading && "Add you vote first"}

<Dialog
description="You cannot submit this ballot, since the sum of votes exceeds the initial voice credits. Please edit your ballot."
isLoading={isLoading}
isOpen={!ableToSubmit && isOpen}
size="sm"
title="exceed initial voice credits"
onOpenChange={setOpen}
/>
</>
{isLoading && <Spinner className="h-4 w-4" />}
</Button>
);
};
1 change: 0 additions & 1 deletion packages/interface/src/layouts/DefaultLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export const LayoutWithSidebar = ({ ...props }: ILayoutProps): JSX.Element => {

return (
<Layout
sidebar="left"
sidebarComponent={
<div>
<Info
Expand Down

0 comments on commit ccaa683

Please sign in to comment.