{error && (
diff --git a/frontend/src/pages/CreatePollPage/useCreatePollForm.ts b/frontend/src/pages/CreatePollPage/useCreatePollForm.ts
index c0e6622..1254182 100644
--- a/frontend/src/pages/CreatePollPage/useCreatePollForm.ts
+++ b/frontend/src/pages/CreatePollPage/useCreatePollForm.ts
@@ -22,7 +22,7 @@ import { designDecisions, MIN_COMPLETION_TIME_MINUTES, nativeTokenName } from '.
import { useNavigate } from 'react-router-dom'
import { acls } from '../../components/ACLs'
-import { proposalIdToSlug } from '../../utils/slug'
+import { getPollPath } from '../../utils/path.utils'
// The steps / pages of the wizard
const StepTitles = {
@@ -356,8 +356,7 @@ export const useCreatePollForm = () => {
const newId = await doCreatePoll(daoSigner, eth.state.address, pollProps, logger)
if (newId) {
- const slug = proposalIdToSlug(newId);
- navigate(`/${slug}`)
+ navigate(getPollPath(newId))
}
} catch (ex) {
let exString = `${ex}`
diff --git a/frontend/src/pages/DashboardPage/useDashboardData.ts b/frontend/src/pages/DashboardPage/useDashboardData.ts
index 1bbc953..0975032 100644
--- a/frontend/src/pages/DashboardPage/useDashboardData.ts
+++ b/frontend/src/pages/DashboardPage/useDashboardData.ts
@@ -6,7 +6,7 @@ import { useBooleanField, useOneOfField, useTextField } from '../../components/I
import { useNavigate } from 'react-router-dom'
import { dashboard, designDecisions } from '../../constants/config'
import classes from './index.module.css'
-import { proposalIdToSlug } from '../../utils/slug'
+import { getPollPath } from '../../utils/path.utils'
const FETCH_BATCH_SIZE = 100
@@ -241,8 +241,8 @@ export const useDashboardData = () => {
onEnter: () => {
const cards = allVisiblePollIds
if (cards.length !== 1) return // We can only do this is there is exactly one matching card
- const slug = proposalIdToSlug(Array.from(cards.values())[0]);
- navigate(`/${slug}`)
+ const pollId = Array.from(cards.values())[0]
+ navigate(getPollPath(pollId))
},
})
diff --git a/frontend/src/pages/LandingPage/index.tsx b/frontend/src/pages/LandingPage/index.tsx
index de9319e..6d9561c 100644
--- a/frontend/src/pages/LandingPage/index.tsx
+++ b/frontend/src/pages/LandingPage/index.tsx
@@ -6,13 +6,14 @@ import { Button, ButtonSize } from '../../components/Button'
import { useNavigate } from 'react-router-dom'
import { useAppState } from '../../hooks/useAppState'
import { appName } from '../../constants/config'
+import { getPollPath } from '../../utils/path.utils'
export const LandingPage: FC = () => {
const navigate = useNavigate()
const {
state: { isMobileScreen },
} = useAppState()
- const openDemo = useCallback(() => navigate('/demo'), [])
+ const openDemo = useCallback(() => navigate(getPollPath('demo')), [])
const buttonSize: ButtonSize = isMobileScreen ? 'small' : 'medium'
return (
diff --git a/frontend/src/pages/PollPage/index.tsx b/frontend/src/pages/PollPage/index.tsx
index 333338e..63e1ac7 100644
--- a/frontend/src/pages/PollPage/index.tsx
+++ b/frontend/src/pages/PollPage/index.tsx
@@ -8,7 +8,7 @@ import { ActivePoll } from './ActivePoll'
import { ThanksForVote } from './ThanksForVoting'
import { Helmet } from 'react-helmet-async'
import { appName, appNameAndTagline, appRootUrl } from '../../constants/config'
-import { slugToProposalId } from '../../utils/slug'
+import { getPollIdFromRouter, getPollPath } from '../../utils/path.utils'
const PollLoading: FC = () => {
return (
@@ -83,8 +83,8 @@ export const PollUI: FC
= props => {
}
export const PollPage: FC = () => {
- const { pollId: slug } = useParams()
- const pollData = usePollData(slugToProposalId(slug!))
+ const pollId = getPollIdFromRouter(useParams())
+ const pollData = usePollData(pollId)
const { poll } = pollData
const params = poll?.ipfsParams
if (params) {
@@ -96,7 +96,7 @@ export const PollPage: FC = () => {
{title}
,
-
+
{description && (
<>
diff --git a/frontend/src/utils/path.utils.ts b/frontend/src/utils/path.utils.ts
new file mode 100644
index 0000000..53eb7fb
--- /dev/null
+++ b/frontend/src/utils/path.utils.ts
@@ -0,0 +1,16 @@
+import { proposalIdToSlug, slugToProposalId } from './slug'
+import { Params } from 'react-router-dom'
+
+/**
+ * Get the poll path from a poll or proposal id.
+ */
+export const getPollPath = (pollId: string): string => `/${proposalIdToSlug(pollId!)}`
+
+/**
+ * Get the poll ID from the parameters found in the URL, coming from the router.
+ */
+export const getPollIdFromRouter = (params: Params): string => {
+ const { slug } = params
+ if (!slug) throw new Error("Slug should be among router parameters, but it isn't!")
+ return slugToProposalId(slug)
+}
diff --git a/frontend/src/utils/slug.ts b/frontend/src/utils/slug.ts
index 9719840..b6cd41b 100644
--- a/frontend/src/utils/slug.ts
+++ b/frontend/src/utils/slug.ts
@@ -1,4 +1,4 @@
-import { BytesLike, getBytes, hexlify } from 'ethers'
+import { getBytes, hexlify } from 'ethers'
// https://en.wikipedia.org/wiki/Base32#z-base-32
const BASE32_ALPHABET = 'ybndrfg8ejkmcpqxot1uwisza345h769'
@@ -65,8 +65,8 @@ function removeTrailingZeros(arr: Uint8Array): Uint8Array {
return arr.slice(0, lastNonZeroIndex + 1)
}
-export function proposalIdToSlug(proposalId: BytesLike) {
- const bytes = removeTrailingZeros(getBytes(proposalId))
+export function proposalIdToSlug(proposalId: string) {
+ const bytes = removeTrailingZeros(getBytes(proposalId.startsWith('0x') ? proposalId : `0x${proposalId}`))
return base32Encode(ensureMinLength(bytes, SLUG_BYTES))
}