Skip to content

Commit

Permalink
Move process modals to their own components
Browse files Browse the repository at this point in the history
  • Loading branch information
elboletaire committed May 23, 2024
1 parent 4c08972 commit d156beb
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 200 deletions.
105 changes: 105 additions & 0 deletions src/components/Process/ConfirmVoteModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Box, Button, Flex, ModalBody, ModalFooter, ModalHeader, Text, useMultiStyleConfig } from '@chakra-ui/react'
import { useConfirm } from '@vocdoni/chakra-components'
import { ElectionResultsTypeNames, PublishedElection } from '@vocdoni/sdk'
import { FieldValues } from 'react-hook-form'
import { Trans, useTranslation } from 'react-i18next'
import { IoWarningOutline } from 'react-icons/io5'
import confirmImg from '/assets/spreadsheet-confirm-modal.jpg'

export const ConfirmVoteModal = ({ election, answers }: { election: PublishedElection; answers: FieldValues }) => {
const { t } = useTranslation()
const styles = useMultiStyleConfig('ConfirmModal')
const { cancel, proceed } = useConfirm()

const canAbstain =
election.resultsType.name === ElectionResultsTypeNames.MULTIPLE_CHOICE && election.resultsType.properties.canAbstain

return (
<>
<ModalHeader>
<Box bgImage={`url(${confirmImg})`} />
</ModalHeader>
<ModalBody display='flex' flexDirection='column' gap={5} p={0} mb={2}>
<Text>{t('process.spreadsheet.confirm.description')}</Text>
<Flex
flexDirection='column'
maxH='200px'
overflowY='scroll'
boxShadow='rgba(128, 128, 128, 0.42) 1px 1px 1px 1px'
px={2}
borderRadius='lg2'
>
{election.questions.map((q, i) => (
<Box key={i}>
<Box py={2}>
<Text display='flex' flexDirection='column' gap={1} mb={1}>
<Trans
i18nKey='process.spreadsheet.confirm.question'
components={{
span: <Text as='span' fontWeight='bold' whiteSpace='nowrap' />,
}}
values={{
answer: q.title.default,
number: i + 1,
}}
/>
</Text>
{election.resultsType.name === ElectionResultsTypeNames.SINGLE_CHOICE_MULTIQUESTION ? (
<Text display='flex' flexDirection='column' gap={1}>
<Trans
i18nKey='process.spreadsheet.confirm.option'
components={{
span: <Text as='span' fontWeight='bold' whiteSpace='nowrap' />,
}}
values={{
answer: q.choices[Number(answers[i])].title.default,
number: i + 1,
}}
/>
</Text>
) : (
<Text display='flex' flexDirection='column' gap={1}>
<Trans
i18nKey='process.spreadsheet.confirm.options'
components={{
span: <Text as='span' fontWeight='bold' whiteSpace='nowrap' />,
}}
values={{
answers:
answers[0].length === 0
? t('process.spreadsheet.confirm.blank_vote')
: answers[0]
.map((a: string) => q.choices[Number(a)].title.default)
.map((a: string) => `- ${a}`)
.join('<br />'),
}}
/>
</Text>
)}
</Box>
{i + 1 !== election.questions.length && <Box h='1px' bgColor='lightgray' />}
</Box>
))}
</Flex>
{canAbstain && answers[0].length < election.voteType.maxCount! && (
<Flex direction={'row'} py={2} gap={2} alignItems={'center'} color={'primary.main'}>
<IoWarningOutline />
<Text display='flex' flexDirection='column' gap={1}>
{t('process.spreadsheet.confirm.abstain_count', {
count: election.voteType.maxCount! - answers[0].length,
})}
</Text>
</Flex>
)}
</ModalBody>
<ModalFooter sx={styles.footer}>
<Button onClick={cancel!} variant='ghost' sx={styles.cancel}>
{t('cc.confirm.cancel')}
</Button>
<Button onClick={proceed!} sx={styles.confirm}>
{t('cc.confirm.confirm')}
</Button>
</ModalFooter>
</>
)
}
92 changes: 92 additions & 0 deletions src/components/Process/SuccessVoteModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {
Box,
Button,
Link,
ListItem,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
UnorderedList,
useDisclosure,
} from '@chakra-ui/react'
import { environment } from '@vocdoni/chakra-components'
import { useClient, useElection } from '@vocdoni/react-providers'
import { InvalidElection } from '@vocdoni/sdk'
import { useEffect, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { FacebookShare, RedditShare, TelegramShare, TwitterShare } from '~components/Share'
import successImg from '/assets/spreadsheet-success-modal.jpg'

export const SuccessVoteModal = () => {
const { t } = useTranslation()
const { isOpen, onOpen, onClose } = useDisclosure()
const { votesLeft, election, voted } = useElection()
const { env } = useClient()

const [vLeft, setVLeft] = useState<number>(0)

useEffect(() => {
if (!vLeft && votesLeft >= 0) {
setVLeft(votesLeft)
}

if (vLeft && votesLeft < vLeft) {
setVLeft(votesLeft)
onOpen()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [votesLeft, vLeft])

if (!election || !voted || election instanceof InvalidElection) return null

const verify = environment.verifyVote(env, voted)
const url = encodeURIComponent(document.location.href)
const caption = t('process.share_caption', { title: election?.title.default })

return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>
<Text>{t('process.success_modal.title')}</Text>
<Box bgImage={successImg} />
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Trans
i18nKey='process.success_modal.text'
components={{
verify: <Link href={verify} target='_blank' />,
p: <Text mb={2} />,
}}
/>
<UnorderedList listStyleType='none' display='flex' justifyContent='center' gap={6} mt={6} mb={2} ml={0}>
<ListItem>
<TwitterShare url={url} caption={caption} />
</ListItem>
<ListItem>
<FacebookShare url={url} caption={caption} />
</ListItem>
<ListItem>
<TelegramShare url={url} caption={caption} />
</ListItem>
<ListItem>
<RedditShare url={url} caption={caption} />
</ListItem>
</UnorderedList>
</ModalBody>

<ModalFooter mt={4}>
<Button onClick={onClose} variant='primary'>
{t('process.success_modal.btn')}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
)
}
Loading

1 comment on commit d156beb

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.