From ac0f78dcd18d0c97845610d9074964d97e59835d Mon Sep 17 00:00:00 2001 From: Justin Schreiner Date: Mon, 25 Nov 2024 11:58:04 -0700 Subject: [PATCH 1/8] add hash on poll id page --- src/pages/polls/[pollId]/index.tsx | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/pages/polls/[pollId]/index.tsx b/src/pages/polls/[pollId]/index.tsx index e931e64..7cfd067 100644 --- a/src/pages/polls/[pollId]/index.tsx +++ b/src/pages/polls/[pollId]/index.tsx @@ -185,15 +185,27 @@ export default function ViewPoll(props: Props): JSX.Element { {poll ? ( - - + + + + + + + The linked text document has the Blake2b-256 hash of:{' '} + {poll.hashedText} + {poll.summary_tx_id && !isTxUploading && ( From 21b1a5826606be5143ad2353fd9fca2ebcb4c502 Mon Sep 17 00:00:00 2001 From: Justin Schreiner Date: Mon, 25 Nov 2024 13:54:06 -0700 Subject: [PATCH 2/8] add fallback background color --- src/providers/themeProvider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/providers/themeProvider.tsx b/src/providers/themeProvider.tsx index 5840029..e44d460 100644 --- a/src/providers/themeProvider.tsx +++ b/src/providers/themeProvider.tsx @@ -244,6 +244,7 @@ export function ColorModeProvider({ <> Date: Mon, 25 Nov 2024 15:16:11 -0600 Subject: [PATCH 3/8] Change poll page isActiveVoter check to CSR --- src/components/buttons/voteOnPollButtons.tsx | 28 +++++++++++++++----- src/pages/polls/[pollId]/index.tsx | 28 +------------------- 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/components/buttons/voteOnPollButtons.tsx b/src/components/buttons/voteOnPollButtons.tsx index 2520f34..cfe109a 100644 --- a/src/components/buttons/voteOnPollButtons.tsx +++ b/src/components/buttons/voteOnPollButtons.tsx @@ -9,12 +9,12 @@ import { useSession } from 'next-auth/react'; import toast from 'react-hot-toast'; import { castVote } from '@/lib/helpers/castVote'; +import { getActiveVoterFromUserId } from '@/lib/helpers/getActiveVoterFromUserId'; import { getPollVote } from '@/lib/helpers/getPollVote'; interface Props { pollName: string; pollId: string; - isActiveVoter: boolean; hashedText: string; link: string; } @@ -23,17 +23,33 @@ interface Props { * Yes, No, Abstain buttons to vote on a poll * @param pollName - The name of the poll * @param pollId - The ID of the poll - * @param isActiveVoter - Whether the user is the active voter + * @param hashedText - The hashed text of the poll + * @param link - The link to the poll * @returns Vote on Poll Buttons */ export function VoteOnPollButtons(props: Props): JSX.Element { - const { pollName, pollId, isActiveVoter, hashedText, link } = props; - const [vote, setVote] = useState(''); - const [disabled, setDisabled] = useState(false); + const { pollName, pollId, hashedText, link } = props; const session = useSession(); const theme = useTheme(); + const [vote, setVote] = useState(''); + const [disabled, setDisabled] = useState(false); + const [isActiveVoter, setIsActiveVoter] = useState(false); + const [fetching, setIsFetching] = useState( + session.status === 'authenticated' ? false : true, + ); + + useEffect(() => { + if (session.data?.user.id) { + setIsFetching(true); + getActiveVoterFromUserId(session.data.user.id).then((result) => { + setIsActiveVoter(result.activeVoterId === session.data.user.id); + setIsFetching(false); + }); + } + }, [session.data?.user.id]); + async function handleVote(vote: string): Promise { setDisabled(true); const result = await castVote( @@ -91,7 +107,7 @@ export function VoteOnPollButtons(props: Props): JSX.Element { )} - {!isActiveVoter && !session.data?.user.isCoordinator && ( + {!isActiveVoter && !session.data?.user.isCoordinator && !fetching && ( You are not the active voter for your workshop. Only the active voter can vote. diff --git a/src/pages/polls/[pollId]/index.tsx b/src/pages/polls/[pollId]/index.tsx index e931e64..6b5b5e3 100644 --- a/src/pages/polls/[pollId]/index.tsx +++ b/src/pages/polls/[pollId]/index.tsx @@ -4,19 +4,16 @@ import type { GetServerSidePropsContext } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; import { pollPhases } from '@/constants/pollPhases'; -import { authOptions } from '@/pages/api/auth/[...nextauth]'; import LaunchRounded from '@mui/icons-material/LaunchRounded'; import { Button, CircularProgress, Modal, useTheme } from '@mui/material'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid2'; import Typography from '@mui/material/Typography'; import { useQuery } from '@tanstack/react-query'; -import { getServerSession } from 'next-auth'; import { useSession } from 'next-auth/react'; import toast from 'react-hot-toast'; import type { Poll, User, Workshop } from '@/types'; -import { activeVoterDto } from '@/data/activeVoterDto'; import { pollDto } from '@/data/pollDto'; import { pollResultsDto } from '@/data/pollResultsDto'; import { pollsDto } from '@/data/pollsDto'; @@ -58,17 +55,10 @@ interface Props { }[]; }; polls: Poll[]; - workshopActiveVoterId: string; } export default function ViewPoll(props: Props): JSX.Element { - const { - representatives, - workshops, - pollResultsSSR, - polls, - workshopActiveVoterId, - } = props; + const { representatives, workshops, pollResultsSSR, polls } = props; let { poll } = props; const [isSubmitting, setIsSubmitting] = useState(false); const [pollResults, setPollResults] = useState(pollResultsSSR); @@ -289,9 +279,6 @@ export default function ViewPoll(props: Props): JSX.Element { @@ -384,7 +371,6 @@ export const getServerSideProps = async ( }[]; }; polls: Poll[]; - workshopActiveVoterId: string; }; }> => { if (!context.params) { @@ -395,23 +381,12 @@ export const getServerSideProps = async ( workshops: [], pollResultsSSR: {}, polls: [], - workshopActiveVoterId: '', }, }; } const { pollId } = context.params; - const session = await getServerSession(context.req, context.res, authOptions); - - let workshopActiveVoterId = ''; - if (session) { - const activeVoterId = await activeVoterDto(session.user.id); - if (activeVoterId) { - workshopActiveVoterId = activeVoterId; - } - } - const poll = await pollDto(pollId); const representatives = await representativesDto(); const workshops = await workshopsDto(); @@ -425,7 +400,6 @@ export const getServerSideProps = async ( workshops: workshops, pollResultsSSR: pollResultsSSR, polls: polls, - workshopActiveVoterId: workshopActiveVoterId, }, }; }; From b90a1f71b87385a564ac4d15f30cbc754853e3c5 Mon Sep 17 00:00:00 2001 From: Matthew Laux Date: Mon, 25 Nov 2024 15:51:33 -0600 Subject: [PATCH 4/8] Update voteOnPoll tests --- .../alertsUserWhenPollHasFinishedVoting.test.tsx | 4 +++- .../alertsUserWhenPollIdIsNotProvided.test.tsx | 4 +++- .../voteOnPollButton/alertsUserWhenPollIsArchived.test.tsx | 4 +++- .../voteOnPollButton/alertsUserWhenPollIsNotFound.test.tsx | 4 +++- .../alertsUserWhenPollIsNotOpenForVotingYet.test.tsx | 4 +++- .../voteOnPollButton/alertsUserWhenVoteFailsToCast.test.tsx | 4 +++- .../voteOnPollButton/alertsUserWhenVoteIsInvalid.test.tsx | 4 +++- .../voteOnPollButton/alertsUserWhenVoteIsNotProvided.test.tsx | 4 +++- .../voteOnPollButton/successfullyVotesAbstainOnAPoll.test.tsx | 4 +++- .../voteOnPollButton/successfullyVotesNoAPoll.test.tsx | 4 +++- .../voteOnPollButton/successfullyVotesYesOnAPoll.test.tsx | 4 +++- 11 files changed, 33 insertions(+), 11 deletions(-) diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollHasFinishedVoting.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollHasFinishedVoting.test.tsx index a8175c7..f2d44d5 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollHasFinishedVoting.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollHasFinishedVoting.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when poll has finished voting', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when poll has finished voting', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIdIsNotProvided.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIdIsNotProvided.test.tsx index cded9a4..f13d46d 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIdIsNotProvided.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIdIsNotProvided.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when poll ID is not provided', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when poll ID is not provided', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsArchived.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsArchived.test.tsx index 55b96b5..beb7b23 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsArchived.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsArchived.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when poll is archived', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when poll is archived', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotFound.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotFound.test.tsx index 5230585..187930c 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotFound.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotFound.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when poll is not found', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when poll is not found', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotOpenForVotingYet.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotOpenForVotingYet.test.tsx index 439d675..aefde1c 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotOpenForVotingYet.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenPollIsNotOpenForVotingYet.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when poll is not open for voting yet', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when poll is not open for voting yet', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteFailsToCast.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteFailsToCast.test.tsx index 8f6d9b2..24051da 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteFailsToCast.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteFailsToCast.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when poll has finished voting', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when poll has finished voting', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsInvalid.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsInvalid.test.tsx index 088d3df..ccefb64 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsInvalid.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsInvalid.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when vote is invalid', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when vote is invalid', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsNotProvided.test.tsx b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsNotProvided.test.tsx index b0ace13..3ce9c46 100644 --- a/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsNotProvided.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/alertsUserWhenVoteIsNotProvided.test.tsx @@ -19,6 +19,9 @@ test.skip('alerts user when vote is not provided', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -26,7 +29,6 @@ test.skip('alerts user when vote is not provided', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/successfullyVotesAbstainOnAPoll.test.tsx b/__tests__/components/buttons/voteOnPollButton/successfullyVotesAbstainOnAPoll.test.tsx index 191531a..914e858 100644 --- a/__tests__/components/buttons/voteOnPollButton/successfullyVotesAbstainOnAPoll.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/successfullyVotesAbstainOnAPoll.test.tsx @@ -16,6 +16,9 @@ test.skip('successfully votes abstain on a poll', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -23,7 +26,6 @@ test.skip('successfully votes abstain on a poll', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/successfullyVotesNoAPoll.test.tsx b/__tests__/components/buttons/voteOnPollButton/successfullyVotesNoAPoll.test.tsx index 0049ae4..94ca4c0 100644 --- a/__tests__/components/buttons/voteOnPollButton/successfullyVotesNoAPoll.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/successfullyVotesNoAPoll.test.tsx @@ -16,6 +16,9 @@ test.skip('successfully votes no on a poll', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -23,7 +26,6 @@ test.skip('successfully votes no on a poll', async () => { diff --git a/__tests__/components/buttons/voteOnPollButton/successfullyVotesYesOnAPoll.test.tsx b/__tests__/components/buttons/voteOnPollButton/successfullyVotesYesOnAPoll.test.tsx index 571bd5a..c83f329 100644 --- a/__tests__/components/buttons/voteOnPollButton/successfullyVotesYesOnAPoll.test.tsx +++ b/__tests__/components/buttons/voteOnPollButton/successfullyVotesYesOnAPoll.test.tsx @@ -16,6 +16,9 @@ test.skip('successfully votes yes on a poll', async () => { id: '1', stakeAddress: 'stakeAddress', walletName: 'walletName', + isCoordinator: false, + isDelegate: true, + isAlternate: false, }, }} > @@ -23,7 +26,6 @@ test.skip('successfully votes yes on a poll', async () => { From 1825055fc5d03269967f271860e725a47ea4e346 Mon Sep 17 00:00:00 2001 From: Matthew Laux Date: Mon, 25 Nov 2024 17:17:43 -0600 Subject: [PATCH 5/8] Add user name 64 byte check --- src/lib/getStringBytes.ts | 9 +++++++++ src/pages/api/updateUser.ts | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/lib/getStringBytes.ts diff --git a/src/lib/getStringBytes.ts b/src/lib/getStringBytes.ts new file mode 100644 index 0000000..5446347 --- /dev/null +++ b/src/lib/getStringBytes.ts @@ -0,0 +1,9 @@ +/** + * Gets the byte size of a string + * @param str - The string to get the byte size of + * @returns Number of bytes + */ +export function getStringBytes(str: string): number { + const byteSize = new Blob([str]).size; + return byteSize; +} diff --git a/src/pages/api/updateUser.ts b/src/pages/api/updateUser.ts index b1b9fec..85c52f5 100644 --- a/src/pages/api/updateUser.ts +++ b/src/pages/api/updateUser.ts @@ -7,6 +7,7 @@ import { getServerSession } from 'next-auth'; import { checkIfCO } from '@/lib/checkIfCO'; import { checkIfVoting } from '@/lib/checkIfVoting'; +import { getStringBytes } from '@/lib/getStringBytes'; type Data = { userId: string; @@ -66,10 +67,10 @@ export default async function updateUser( message: 'Name must be provided.', }); } - if (name.length > 100) { + if (getStringBytes(name) > 64) { return res.status(400).json({ userId: BigInt(-1).toString(), - message: 'Name must be less than 100 characters.', + message: 'Name must be less than 64 characters.', }); } // validate email From fddb921d09932c451a5db345e1f2b08de6e6692b Mon Sep 17 00:00:00 2001 From: Matthew Laux Date: Mon, 25 Nov 2024 17:40:55 -0600 Subject: [PATCH 6/8] Update active voter table when delegate info changes --- .../coordinator/manageActivePowerTable.tsx | 22 ++++++++++++++++--- .../manageRepresentativesTable.tsx | 9 +++++++- src/pages/representatives/manage/index.tsx | 15 +++++++++---- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/components/coordinator/manageActivePowerTable.tsx b/src/components/coordinator/manageActivePowerTable.tsx index f49d6b6..cd5f0af 100644 --- a/src/components/coordinator/manageActivePowerTable.tsx +++ b/src/components/coordinator/manageActivePowerTable.tsx @@ -27,11 +27,19 @@ import { getRepresentatives } from '@/lib/helpers/getRepresentatives'; import { getWorkshops } from '@/lib/helpers/getWorkshops'; import { updateActiveVoter } from '@/lib/helpers/updateActiveVoter'; +interface Props { + refresh: boolean; + toggleRefresh: () => void; +} + /** * Allows a workshop coordinator to manage if delegates or alternates have active power from each workhsop + * @param refresh - boolean to refresh the table + * @param toggleRefresh - function to toggle the refresh boolean * @returns Admin Manage Active Power Table */ -export function ManageActivePowerTable(): JSX.Element { +export function ManageActivePowerTable(props: Props): JSX.Element { + const { refresh, toggleRefresh } = props; const [representatives, setRepresentatives] = useState([]); const [workshops, setWorkshops] = useState([]); const [rowModesModel, setRowModesModel] = useState({}); @@ -47,7 +55,7 @@ export function ManageActivePowerTable(): JSX.Element { setRepresentatives(reps); } fetchData(); - }, [reload]); + }, [reload, refresh]); function handleRowEditStop( // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -69,6 +77,7 @@ export function ManageActivePowerTable(): JSX.Element { toast.error(data.message); } setReload(!reload); + toggleRefresh(); return newRow; } @@ -271,7 +280,14 @@ export function ManageActivePowerTable(): JSX.Element { }, }, ]; - }, [representatives, rowModesModel, theme.palette.text.primary, reload]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + representatives, + rowModesModel, + theme.palette.text.primary, + reload, + refresh, // TS is not recognizing refresh as a dependency but it is required to properly refresh the table when info in representatives table changes + ]); return ( diff --git a/src/components/coordinator/manageRepresentativesTable.tsx b/src/components/coordinator/manageRepresentativesTable.tsx index 9cc9862..27cd91a 100644 --- a/src/components/coordinator/manageRepresentativesTable.tsx +++ b/src/components/coordinator/manageRepresentativesTable.tsx @@ -22,11 +22,17 @@ import { User } from '@/types'; import { getRepresentatives } from '@/lib/helpers/getRepresentatives'; import { updateUser } from '@/lib/helpers/updateUser'; +interface Props { + toggleRefresh: () => void; +} + /** * Table for admin to manage representative information + * @param toggleRefresh - function to toggle the refresh boolean * @returns Admin Manage Representatives Table */ -export function ManageRepresentativesTable(): JSX.Element { +export function ManageRepresentativesTable(props: Props): JSX.Element { + const { toggleRefresh } = props; const [representatives, setRepresentatives] = useState([]); const [rowModesModel, setRowModesModel] = useState({}); const [reload, setReload] = useState(false); @@ -64,6 +70,7 @@ export function ManageRepresentativesTable(): JSX.Element { toast.error(data.message); } setReload(!reload); + toggleRefresh(); return newRow; } diff --git a/src/pages/representatives/manage/index.tsx b/src/pages/representatives/manage/index.tsx index df4d9c7..daf9b76 100644 --- a/src/pages/representatives/manage/index.tsx +++ b/src/pages/representatives/manage/index.tsx @@ -1,3 +1,4 @@ +import { useCallback, useState } from 'react'; import type { GetServerSidePropsContext } from 'next'; import Head from 'next/head'; import { authOptions } from '@/pages/api/auth/[...nextauth]'; @@ -12,6 +13,11 @@ import { ManageRepresentativesTable } from '@/components/coordinator/manageRepre export default function ManageRepresentatives(): JSX.Element { useCheckAddressChange(); + const [refresh, setRefresh] = useState(false); + + const toggleRefresh = useCallback((): void => { + setRefresh((prev) => !prev); + }, []); return ( <> @@ -29,10 +35,11 @@ export default function ManageRepresentatives(): JSX.Element { Coordinator Dashboard - - - - + + From 24951ac0945d95799b3a7a1ada916d7aeef29ada Mon Sep 17 00:00:00 2001 From: Matthew Laux Date: Mon, 25 Nov 2024 21:08:47 -0600 Subject: [PATCH 7/8] Add in progress option to voting history table --- src/components/representatives/votingHistoryTable.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/representatives/votingHistoryTable.tsx b/src/components/representatives/votingHistoryTable.tsx index 25ce03a..f1ab3c2 100644 --- a/src/components/representatives/votingHistoryTable.tsx +++ b/src/components/representatives/votingHistoryTable.tsx @@ -1,3 +1,4 @@ +import { pollPhases } from '@/constants/pollPhases'; import DoDisturbRounded from '@mui/icons-material/DoDisturbRounded'; import ThumbDownRounded from '@mui/icons-material/ThumbDownRounded'; import ThumbUpRounded from '@mui/icons-material/ThumbUpRounded'; @@ -42,6 +43,7 @@ export function VotingHistoryTable(props: Props): JSX.Element { const userVoteData = votes.find( (vote) => vote.poll_id === params.row.id, ); + const poll = polls.find((poll) => poll.id === params.row.id); const userVote = userVoteData?.vote; return ( )} - {!userVote && ( + {poll?.status === pollPhases.pending || + (poll?.status === pollPhases.voting && ( + + In Progress + + ))} + {poll?.status === pollPhases.concluded && !userVote && ( None From 0f0e9d4cb716e89942f6ed097b08c720db5c6900 Mon Sep 17 00:00:00 2001 From: Justin Schreiner Date: Mon, 25 Nov 2024 20:09:22 -0700 Subject: [PATCH 8/8] wrap text --- package-lock.json | 1 + src/pages/polls/[pollId]/index.tsx | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 03f548b..d691661 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "cardano-constitution-voting-app", "version": "0.1.0", "hasInstallScript": true, + "license": "AGPL-3.0-or-later", "dependencies": { "@claritydao/clarity-backend": "^0.4.0-dev-512cc333547522c7d53ffe0ecddacd3de3958dd1", "@emotion/react": "^11.13.3", diff --git a/src/pages/polls/[pollId]/index.tsx b/src/pages/polls/[pollId]/index.tsx index 7cfd067..dbc49d5 100644 --- a/src/pages/polls/[pollId]/index.tsx +++ b/src/pages/polls/[pollId]/index.tsx @@ -202,7 +202,13 @@ export default function ViewPoll(props: Props): JSX.Element { - + The linked text document has the Blake2b-256 hash of:{' '} {poll.hashedText}