Skip to content

Commit

Permalink
Fixes + strip ConfirmModal
Browse files Browse the repository at this point in the history
- now the contents of ConfirmModal are defined by the prompt contents,
  meaning you have to define the buttons yourself
- fix anonymous vote creation passing password instead of signature as
  argument
- moved everything related to sik password and signature from the client
  to the election provider, since it doesn't make sense to have it at
  client level, and it was causing issues with multiple wallets
  connected
- upgrade SDK to 0.6.0
  • Loading branch information
elboletaire committed Nov 28, 2023
1 parent 24b6b5c commit 33152c9
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 124 deletions.
6 changes: 4 additions & 2 deletions packages/chakra-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@
"@chakra-ui/progress": "^2.1.6",
"@chakra-ui/radio": "^2.0.22",
"@chakra-ui/react-use-disclosure": "^2.1.0",
"@chakra-ui/spinner": "^2.1.0",
"@chakra-ui/system": "2.5.5",
"@chakra-ui/table": "^2.0.17",
"@chakra-ui/tag": "^3.0.0",
"@chakra-ui/theme": "^3.0.0",
"@chakra-ui/toast": "^6.1.1",
"@vocdoni/sdk": "~0.5.1",
"@vocdoni/sdk": "~0.6.0",
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0",
"react-markdown": ">= 8.0.0",
Expand All @@ -60,6 +61,7 @@
"@chakra-ui/progress": "^2.1.6",
"@chakra-ui/radio": "^2.0.22",
"@chakra-ui/react-use-disclosure": "^2.1.0",
"@chakra-ui/spinner": "^2.1.0",
"@chakra-ui/system": "2.5.5",
"@chakra-ui/table": "^2.0.17",
"@chakra-ui/tag": "^3.0.0",
Expand All @@ -69,7 +71,7 @@
"@ethersproject/wallet": "^5.7.0",
"@types/react": "^18.0.30",
"@types/react-dom": "^18.0.11",
"@vocdoni/sdk": "~0.5.1",
"@vocdoni/sdk": "~0.6.0",
"clean-package": "^2.2.0",
"date-fns": "^2.29.3",
"eslint": "^8.42.0",
Expand Down
42 changes: 30 additions & 12 deletions packages/chakra-components/src/components/Election/Questions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Alert, AlertDescription, AlertIcon, AlertTitle } from '@chakra-ui/alert'
import { Button } from '@chakra-ui/button'
import { FormControl, FormErrorMessage } from '@chakra-ui/form-control'
import { Box, Link, Stack, Text } from '@chakra-ui/layout'
import { ModalBody, ModalCloseButton, ModalFooter, ModalHeader } from '@chakra-ui/modal'
import { Radio, RadioGroup } from '@chakra-ui/radio'
import { chakra, ChakraProps, omitThemingProps, useMultiStyleConfig } from '@chakra-ui/system'
import { Wallet } from '@ethersproject/wallet'
Expand Down Expand Up @@ -91,23 +93,39 @@ export type QuestionsConfirmationProps = {
}

export const QuestionsConfirmation = ({ answers, questions, ...rest }: QuestionsConfirmationProps) => {
const mstyles = useMultiStyleConfig('ConfirmModal')
const styles = useMultiStyleConfig('QuestionsConfirmation', rest)
const { cancel, proceed } = useConfirm()
const props = omitThemingProps(rest)
const { localize } = useClient()

return (
<Box {...props} sx={styles.box}>
<Text sx={styles.description}>{localize('vote.confirm')}</Text>
{questions.map((q, k) => {
const choice = q.choices.find((v) => v.value === parseInt(answers[k.toString()], 10))
return (
<chakra.div key={k} __css={styles.question}>
<chakra.div __css={styles.title}>{q.title.default}</chakra.div>
<chakra.div __css={styles.answer}>{choice?.title.default}</chakra.div>
</chakra.div>
)
})}
</Box>
<>
<ModalHeader sx={mstyles.header}>{localize('confirm.title')}</ModalHeader>
<ModalCloseButton sx={mstyles.close} />
<ModalBody sx={mstyles.body}>
<Box {...props} sx={styles.box}>
<Text sx={styles.description}>{localize('vote.confirm')}</Text>
{questions.map((q, k) => {
const choice = q.choices.find((v) => v.value === parseInt(answers[k.toString()], 10))
return (
<chakra.div key={k} __css={styles.question}>
<chakra.div __css={styles.title}>{q.title.default}</chakra.div>
<chakra.div __css={styles.answer}>{choice?.title.default}</chakra.div>
</chakra.div>
)
})}
</Box>
</ModalBody>
<ModalFooter sx={mstyles.footer}>
<Button onClick={cancel!} variant='ghost' sx={mstyles.cancel}>
{localize('confirm.cancel')}
</Button>
<Button onClick={proceed!} sx={mstyles.confirm}>
{localize('confirm.confirm')}
</Button>
</ModalFooter>
</>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export const SpreadsheetAccess = (rest: ChakraProps) => {
const { connected, clearClient } = useElection()
const [loading, setLoading] = useState<boolean>(false)
const toast = useToast()
const { env, setSikPassword, setSikSignature } = useClient()
const { election, setClient, localize, fetchCensus } = useElection()
const { env, client: cl } = useClient()
const { election, setClient, localize, fetchCensus, sikPassword, sikSignature } = useElection()
const fields: string[] = dotobject(election, 'meta.census.fields')
const {
register,
Expand All @@ -45,7 +45,9 @@ export const SpreadsheetAccess = (rest: ChakraProps) => {
}

// create wallet and client
const wallet = walletFromRow(election!.organizationId, Object.values(vals))
const hid = await cl.electionService.getNumericElectionId(election!.id)
const salt = await cl.electionService.getElectionSalt(election!.organizationId, hid)
const wallet = walletFromRow(salt, Object.values(vals))
const client = new VocdoniSDKClient({
env,
wallet,
Expand All @@ -63,8 +65,8 @@ export const SpreadsheetAccess = (rest: ChakraProps) => {
fetchCensus()
// store SIK requirements to client on anon elections
if (election?.electionType.anonymous && sikp) {
setSikPassword(sikp)
setSikSignature(await client.anonymousService.signSIKPayload(wallet))
sikPassword(sikp)
sikSignature(await client.anonymousService.signSIKPayload(wallet))
}
// in case of success, set current client
setClient(client)
Expand Down
19 changes: 12 additions & 7 deletions packages/chakra-components/src/components/Election/VoteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ import { Button, ButtonProps } from '@chakra-ui/button'
import { Signer } from '@ethersproject/abstract-signer'
import { useClient, useElection } from '@vocdoni/react-providers'
import { ArchivedElection, ElectionStatus, InvalidElection } from '@vocdoni/sdk'
import { useState } from 'react'
import { SpreadsheetAccess } from './SpreadsheetAccess'

export const VoteButton = (props: ButtonProps) => {
const {
connected,
sik: { signature },
setSikSignature,
} = useClient()
const { connected } = useClient()
const {
client,
loading: { voting },
Expand All @@ -19,7 +16,10 @@ export const VoteButton = (props: ButtonProps) => {
election,
voted,
localize,
sik: { signature },
sikSignature,
} = useElection()
const [loading, setLoading] = useState<boolean>(false)
const isDisabled = !client.wallet || !isAbleToVote || election?.status !== ElectionStatus.ONGOING

if (election instanceof InvalidElection || election instanceof ArchivedElection) return null
Expand All @@ -42,10 +42,15 @@ export const VoteButton = (props: ButtonProps) => {
}

if (connected && election?.electionType.anonymous && !signature) {
button.isLoading = loading
button.type = 'button'
button.children = localize('vote.identify')
button.children = localize('vote.sign')
button.onClick = async () => {
setSikSignature(await client.anonymousService.signSIKPayload(client.wallet as Signer))
setLoading(true)
try {
sikSignature(await client.anonymousService.signSIKPayload(client.wallet as Signer))
} catch (e) {}
setLoading(false)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,15 @@
import { Button } from '@chakra-ui/button'
import {
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
} from '@chakra-ui/modal'
import { Modal, ModalContent, ModalOverlay } from '@chakra-ui/modal'
import { useMultiStyleConfig } from '@chakra-ui/system'
import { useClient } from '@vocdoni/react-providers'
import { useConfirm } from './ConfirmProvider'

export const ConfirmModal = () => {
const styles = useMultiStyleConfig('ConfirmModal')
const { prompt, isOpen, proceed, cancel } = useConfirm()
const { localize } = useClient()
const { prompt, isOpen, cancel } = useConfirm()

return (
<Modal isOpen={isOpen} onClose={cancel!}>
<ModalOverlay sx={styles.overlay} />
<ModalContent sx={styles.content}>
<ModalHeader sx={styles.header}>{localize('confirm.title')}</ModalHeader>
<ModalCloseButton sx={styles.close} />
<ModalBody sx={styles.body}>{prompt}</ModalBody>
<ModalFooter sx={styles.footer}>
<Button onClick={cancel!} variant='ghost' sx={styles.cancel}>
{localize('confirm.cancel')}
</Button>
<Button onClick={proceed!} sx={styles.confirm}>
{localize('confirm.confirm')}
</Button>
</ModalFooter>
</ModalContent>
<ModalContent sx={styles.content}>{prompt}</ModalContent>
</Modal>
)
}
17 changes: 9 additions & 8 deletions packages/chakra-components/src/i18n/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,6 @@ export const locales = {
cancel: 'Cancel',
confirm: 'Confirm',
},
// questions and vote button
vote: {
button_update: 'Re-submit vote',
button: 'Vote',
confirm: 'Please confirm your choices:',
voted_description: 'Your vote id is {{ id }}. You can use it to verify your vote.',
voted_title: 'Your vote was successfully cast!',
},
empty: 'Apparently this process has no questions 🤔',
errors: {
wrong_data_title: 'Wrong data',
Expand Down Expand Up @@ -66,6 +58,15 @@ export const locales = {
required: 'This field is required',
min_length: 'This field must be at least {{ min }} characters long',
},
// questions and vote button
vote: {
button_update: 'Re-submit vote',
button: 'Vote',
confirm: 'Please confirm your choices:',
sign: 'Sign first',
voted_description: 'Your vote id is {{ id }}. You can use it to verify your vote.',
voted_title: 'Your vote was successfully cast!',
},
}

export type Locale = RecursivePartial<typeof locales>
2 changes: 2 additions & 0 deletions packages/chakra-components/src/theme/confirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const confirmAnatomy = [
'close',
]

export const signModalAnatomy = ['body', 'description', 'footer', 'button']

const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(confirmAnatomy)

const baseStyle = definePartsStyle({
Expand Down
4 changes: 2 additions & 2 deletions packages/react-providers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
},
"main": "src/index.ts",
"peerDependencies": {
"@vocdoni/sdk": "~0.5.3",
"@vocdoni/sdk": "~0.6.0",
"react": ">= 16.8.0"
},
"devDependencies": {
"@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/wallet": "^5.7.0",
"@types/latinize": "^0.2.15",
"@types/react": "^18.0.30",
"@vocdoni/sdk": "^0.5.3",
"@vocdoni/sdk": "~0.6.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-react-app": "^7.0.1",
Expand Down
4 changes: 1 addition & 3 deletions packages/react-providers/src/client/use-client-provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Wallet } from '@ethersproject/wallet'
import { Account, AccountData, EnvOptions, VocdoniSDKClient } from '@vocdoni/sdk'
import { Account, EnvOptions, VocdoniSDKClient } from '@vocdoni/sdk'
import { useEffect } from 'react'
import { useLocalize } from '../i18n/localize'
import { ClientReducerProps, newVocdoniSDKClient, useClientReducer } from './use-client-reducer'
Expand Down Expand Up @@ -105,8 +105,6 @@ export const useClientProvider = ({ client: c, env: e, signer: s, options: o }:
clear: actions.clear,
setClient: actions.setClient,
setSigner: actions.setSigner,
setSikPassword: actions.setSikPassword,
setSikSignature: actions.setSikSignature,
createAccount,
fetchAccount,
generateSigner,
Expand Down
42 changes: 0 additions & 42 deletions packages/react-providers/src/client/use-client-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,19 @@ export const ClientClear = 'client:clear'
export const ClientEnvSet = 'client:env:set'
export const ClientSet = 'client:set'
export const ClientSignerSet = 'client:signer:set'
export const ClientSikPasswordSet = 'client:sikpassword:set'
export const ClientSikSignatureSet = 'client:siksignature:set'

export type ClientAccountErrorPayload = ErrorPayload
export type ClientAccountSetPayload = AccountData
export type ClientEnvSetPayload = ClientEnv
export type ClientSetPayload = VocdoniSDKClient
export type ClientSignerSetPayload = Signer | Wallet
export type ClientSikPayload = string | null

export type ClientActionPayload =
| ClientAccountErrorPayload
| ClientAccountSetPayload
| ClientEnvSetPayload
| ClientSetPayload
| ClientSignerSetPayload
| ClientSikPayload

export type ClientActionType =
| typeof ClientAccountCreate
Expand All @@ -60,8 +56,6 @@ export type ClientActionType =
| typeof ClientEnvSet
| typeof ClientSet
| typeof ClientSignerSet
| typeof ClientSikPasswordSet
| typeof ClientSikSignatureSet

export interface ClientAction {
type: ClientActionType
Expand Down Expand Up @@ -104,10 +98,6 @@ export interface ClientState {
api_url?: string
faucet_url?: string
}
sik: {
password: string | null
signature: string | null
}
}

export const clientStateEmpty = (
Expand Down Expand Up @@ -139,10 +129,6 @@ export const clientStateEmpty = (
fetch: null,
},
options,
sik: {
password: null,
signature: null,
},
})

const clientReducer: Reducer<ClientState, ClientAction> = (state: ClientState, action: ClientAction) => {
Expand Down Expand Up @@ -212,10 +198,6 @@ const clientReducer: Reducer<ClientState, ClientAction> = (state: ClientState, a
create: null,
fetch: null,
},
sik: {
password: null,
signature: null,
},
}
}
case ClientClear: {
Expand Down Expand Up @@ -254,26 +236,6 @@ const clientReducer: Reducer<ClientState, ClientAction> = (state: ClientState, a
connected: !!client.wallet,
}
}
case ClientSikPasswordSet: {
const password = action.payload as ClientSikPayload
return {
...state,
sik: {
...state.sik,
password,
},
}
}
case ClientSikSignatureSet: {
const signature = action.payload as ClientSikPayload
return {
...state,
sik: {
...state.sik,
signature,
},
}
}
default:
return state
}
Expand Down Expand Up @@ -310,8 +272,6 @@ export const useClientReducer = ({ env, client, signer, options }: ClientReducer
const setClient = (client: VocdoniSDKClient) => dispatch({ type: ClientSet, payload: client })
const setEnv = (env: ClientEnvSetPayload) => dispatch({ type: ClientEnvSet, payload: env })
const setSigner = (signer: Wallet | Signer) => dispatch({ type: ClientSignerSet, payload: signer })
const setSikPassword = (password: string | null) => dispatch({ type: ClientSikPasswordSet, payload: password })
const setSikSignature = (signature: string | null) => dispatch({ type: ClientSikSignatureSet, payload: signature })

return {
state,
Expand All @@ -327,8 +287,6 @@ export const useClientReducer = ({ env, client, signer, options }: ClientReducer
setClient,
setEnv,
setSigner,
setSikPassword,
setSikSignature,
},
}
}
Loading

0 comments on commit 33152c9

Please sign in to comment.