Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pro plan options #555

Merged
merged 31 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8996668
process create added custom plans
gerouvi Feb 15, 2024
a51d888
Added EmailJS to the ModalPro to send a mail to the manager to contac…
jpaulet Feb 15, 2024
3d67673
env variables, error and success messages
gerouvi Feb 20, 2024
3b1711a
env template and public id
gerouvi Feb 20, 2024
d3d71d1
pro label and icons
gerouvi Feb 20, 2024
9b2f151
grid layout cards
gerouvi Feb 22, 2024
50b3eab
voting types breakpoint desktop xl3
gerouvi Feb 22, 2024
ceb21ac
census desktop 4 cards per row
gerouvi Feb 22, 2024
6097a77
fixed issue env.example types object
gerouvi Feb 23, 2024
f2f75f4
fixed issues
gerouvi Feb 28, 2024
be9f6ee
fixed issues
gerouvi Feb 29, 2024
eb9dc99
fixed issue voting types title, removed <p>
gerouvi Mar 1, 2024
9a08185
toggle voting type and census pro plan cards
gerouvi Mar 4, 2024
0d7d72b
removed voting type border
gerouvi Mar 4, 2024
c36ead7
fixed error when sending the form inside a modal causes another form …
gerouvi Mar 4, 2024
7d57726
pr voitng type and pro census grid
gerouvi Mar 5, 2024
d61772d
hide pro plans when select a census
gerouvi Mar 6, 2024
d6ff4e7
render pro plan options via .env and render others card if pro plans …
gerouvi Mar 6, 2024
2bb0347
onvote styles
gerouvi Mar 19, 2024
accf947
calendar link
gerouvi Mar 19, 2024
94fd996
translations
gerouvi Mar 19, 2024
6bde703
Merge remote-tracking branch 'origin/develop' into f/customization-530
gerouvi Mar 19, 2024
95605e5
fixed issue, added process_create question translations
gerouvi Mar 19, 2024
76381e3
Improved copies and texts
jpaulet Mar 21, 2024
0fbe630
Working env example file with new params
jpaulet Mar 22, 2024
4bc1749
fixed issue .env.example and template string in features.ts
gerouvi Apr 2, 2024
8518f45
emailsjs public key condition to render email pro modal
gerouvi Apr 2, 2024
2ca41fb
.env.example
gerouvi Apr 2, 2024
2fb60e9
emailjsEnabled condition
gerouvi Apr 2, 2024
501562d
other setting cards fill width
gerouvi Apr 2, 2024
05b5f07
Merge remote-tracking branch 'origin/develop' into f/customization-530
gerouvi Apr 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
VOCDONI_ENVIRONMENT=prod
FEATURES='{"faucet":true,"vote":{"anonymous":true,"overwrite":true,"secret":true},"login":["web3","web2"],"census":["spreadsheet","token","web3"],"languages":["en","es","ca"]}'
FEATURES='{"faucet":true,"vote":{"anonymous":true,"overwrite":true,"secret":true,"customization":true},"types":["single":true,"multi":true,"approval":true,"participatory":true,"borda":true],"login":["web3","web2"],"census":["spreadsheet","token","web3"],"unimplemented_census":["phone","email","crm","database","digital_certificate","others"],"languages":["en","es","ca"]}'
gerouvi marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@chakra-ui/anatomy": "^2.1.2",
"@chakra-ui/icons": "^2.0.19",
"@chakra-ui/react": "^2.7.1",
"@emailjs/browser": "^4.1.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@ethersproject/abstract-signer": "^5.7.0",
Expand Down
71 changes: 71 additions & 0 deletions src/components/ProcessCreate/Census/UnimplementedTypeSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useTranslation } from 'react-i18next'
import { BiPhone } from 'react-icons/bi'
import { CgMoreO } from 'react-icons/cg'
import { GoDatabase } from 'react-icons/go'
import { LuCircleDotDashed } from 'react-icons/lu'
import { MdOutlineEmail } from 'react-icons/md'
import { PiCertificate } from 'react-icons/pi'

export const CensusTypePhone = 'phone'
export const CensusTypeEmail = 'email'
export const CensusTypeCrm = 'crm'
export const CensusTypeDatabase = 'database'
export const CensusTypeDigitalCerificate = 'digital_certificate'
export const CensusTypeOthers = 'others'

export type UnimplementedCensusType =
| typeof CensusTypePhone
| typeof CensusTypeEmail
| typeof CensusTypeCrm
| typeof CensusTypeDatabase
| typeof CensusTypeDigitalCerificate
| typeof CensusTypeOthers

export const UnimplementedCensusTypes = [
CensusTypePhone as UnimplementedCensusType,
CensusTypeEmail as UnimplementedCensusType,
CensusTypeCrm as UnimplementedCensusType,
CensusTypeDatabase as UnimplementedCensusType,
CensusTypeDigitalCerificate as UnimplementedCensusType,
CensusTypeOthers as UnimplementedCensusType,
]

export const useUnimplementedCensusTypes = () => {
const { t } = useTranslation()
return {
list: UnimplementedCensusTypes,
defined: import.meta.env.features.unimplemented_census as UnimplementedCensusType[],
details: {
[CensusTypePhone]: {
title: t('process_create.census.phone_title'),
description: t('process_create.census.phone_description'),
icon: BiPhone,
},
[CensusTypeEmail]: {
title: t('process_create.census.email_title'),
description: t('process_create.census.email_description'),
icon: MdOutlineEmail,
},
[CensusTypeCrm]: {
title: t('process_create.census.crm_title'),
description: t('process_create.census.crm_description'),
icon: LuCircleDotDashed,
},
[CensusTypeDatabase]: {
title: t('process_create.census.database_title'),
description: t('process_create.census.database_description'),
icon: GoDatabase,
},
[CensusTypeDigitalCerificate]: {
title: t('process_create.census.digital_certificate_title'),
description: t('process_create.census.digital_certificate_description'),
icon: PiCertificate,
},
[CensusTypeOthers]: {
title: t('process_create.census.others_title'),
description: t('process_create.census.others_description'),
icon: CgMoreO,
},
},
}
}
167 changes: 167 additions & 0 deletions src/components/ProcessCreate/ModalPro.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { CalendarIcon } from '@chakra-ui/icons'
import {
Box,
Button,
Flex,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalHeader,
ModalOverlay,
Text,
} from '@chakra-ui/react'
import emailjs from '@emailjs/browser'
import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { Trans, useTranslation } from 'react-i18next'
import { AiFillGooglePlusCircle } from 'react-icons/ai'
import { FaRegCalendarAlt } from 'react-icons/fa'

const ModalPro = ({ isOpen, onClose, reason }: { isOpen: boolean; onClose: () => void; reason: string }) => {
const { t } = useTranslation()
const [success, setSuccess] = useState(false)
const [error, setError] = useState(false)
const {
register,
handleSubmit,
formState: { errors },
setValue,
} = useForm({
defaultValues: {
name: '',
email: '',
reason: reason,
},
})

const required = {
value: true,
message: t('form.error.field_is_required'),
}

useEffect(() => {
setValue('reason', reason)
}, [reason])

useEffect(() => {
setSuccess(false)
setError(false)
}, [])

const sendEmail = (form: any) => {
emailjs

.sendForm(import.meta.env.EMAILJS_SERVICE_ID, import.meta.env.EMAILJS_TEMPLATE_ID, form, {
publicKey: import.meta.env.EMAILJS_PUBLIC_ID,
})
.then(
() => {
setSuccess(true)
},
(error: any) => {
setError(true)
}
)
}

return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent minW={{ lg: '700px' }}>
<ModalHeader>{t('process_create.modal_pro.title')}</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Box mb={6}>
<Trans
i18nKey='process_create.modal_pro.description'
components={{
p: <Text />,
bold: <Text as='span' fontWeight='bold' />,
}}
/>
</Box>

<Flex flexDirection={{ base: 'column', lg: 'row' }} gap={{ base: 10, lg: 0 }}>
<Flex
as='form'
id='modal-pro'
flex='1 1 50%'
flexDirection='column'
justifyContent='space-between'
pr={{ lg: 5 }}
onSubmit={handleSubmit(sendEmail)}
>
<Text color='process_create.modal_pro.description' mb={0} fontSize='sm'>
{t('process_create.modal_pro.form_description')}
</Text>
<Flex flexDirection='column' gap={3}>
<FormControl isInvalid={!!errors.name}>
<FormLabel fontSize='xs'>{t('process_create.modal_pro.form_name_label')}</FormLabel>
<Input
{...register('name', { required })}
placeholder={t('process_create.modal_pro.form_name_placeholder')}
/>
{!!errors.name && <FormErrorMessage>{errors.name?.message?.toString()}</FormErrorMessage>}
</FormControl>
<FormControl isInvalid={!!errors.email}>
<FormLabel fontSize='xs'>{t('process_create.modal_pro.form_email_label')}</FormLabel>
<Input
{...register('email', { required })}
type='email'
placeholder={t('process_create.modal_pro.form_email_placeholder')}
/>
{!!errors.email && <FormErrorMessage>{errors.email?.message?.toString()}</FormErrorMessage>}
</FormControl>
</Flex>
<Box>
{success && (
<Text my={3} color='success'>
{t('process_create.modal_pro.success')}
</Text>
)}
{error && (
<Text my={3} color='error'>
{t('process_create.modal_pro.error')}
</Text>
)}
<Button type='submit' form='modal-pro' w='full' fontSize='14px'>
{t('process_create.modal_pro.form_btn')}
</Button>
</Box>
</Flex>
<Box w={{ lg: '1px' }} h={{ base: '1px', lg: 'auto' }} bgColor='process_create.modal_pro.border'></Box>
<Flex flex='1 1 50%' flexDirection='column' justifyContent='space-between' gap={10} pl={{ lg: 5 }}>
<Text color='process_create.modal_pro.description' fontSize='sm'>
{t('process_create.modal_pro.scheudle_description')}
</Text>
<Flex justifyContent='center' mb='10px'>
<Box position='relative' width='100px'>
<FaRegCalendarAlt size={100} />
<Box position='absolute' top='65px' left='70px' bgColor='white' borderRadius='full'>
<AiFillGooglePlusCircle size={50} />
</Box>
</Box>
</Flex>
<Button
as='a'
href='https://calendar.google.com/calendar/appointments/schedules/AcZssZ29VUbJIqlHtdY32eVUd2OhbjfQLoiHhTAk34Ct6PianaFnwediCb6K021zcX5RaKDdd76eZS-O?gv=true'
target='_blank'
leftIcon={<CalendarIcon />}
fontSize='14px'
>
{t('process_create.modal_pro.scheudle_btn')}
</Button>
</Flex>
</Flex>
</ModalBody>
</ModalContent>
</Modal>
)
}

export default ModalPro
116 changes: 116 additions & 0 deletions src/components/ProcessCreate/Questions/VotingTypes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { Box, Checkbox, Flex, Icon, Text, useDisclosure } from '@chakra-ui/react'
import { useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { GiChoice } from 'react-icons/gi'
import { GoNumber } from 'react-icons/go'
import { HiCheckBadge } from 'react-icons/hi2'
import { ImListNumbered } from 'react-icons/im'
import { MdOutlineLibraryAddCheck } from 'react-icons/md'
import ModalPro from '../ModalPro'

const VotingTypes = () => {
const { t } = useTranslation()
const { isOpen, onOpen, onClose } = useDisclosure()

const [reason, setReason] = useState('')

return (
<>
<ModalPro isOpen={isOpen} onClose={onClose} reason={reason} />
<Box>
<Text className='process-create-title'>{t('process_create.question.voting_type.title')}</Text>
<Text fontSize='sm' color='process_create.description' mb={5}>
{t('process_create.question.voting_type.description')}
</Text>
<Flex flexWrap='wrap' gap={5}>
<Checkbox variant='radiobox' flex='0 0 30%' isChecked={true}>
<Box>
<Icon as={GiChoice} />
<Box>
<Trans
i18nKey='process_create.question.single_choice.title'
components={{
p: <Text />,
}}
/>
</Box>
</Box>
<Text>{t('process_create.question.single_choice.description')}</Text>
</Checkbox>
<Checkbox variant='radiobox' flex='0 0 30%'>
<Box>
<Icon as={MdOutlineLibraryAddCheck} />
<Box>
<Trans
i18nKey='process_create.question.multi_choice.title'
components={{
p: <Text />,
}}
/>
</Box>
</Box>
<Text as='span'>Pro</Text>
<Text>{t('process_create.question.multi_choice.description')}</Text>
<Box
onClick={() => {
setReason('multiple choice')
onOpen()
}}
/>
</Checkbox>
<Checkbox variant='radiobox' flex='0 0 30%'>
<Box>
<Icon as={HiCheckBadge} />
<Text>{t('process_create.question.approval_voting.title')}</Text>
</Box>
<Text as='span'>Pro</Text>
<Text>{t('process_create.question.approval_voting.description')}</Text>
<Box
onClick={() => {
setReason('approval voting')
onOpen()
}}
/>
</Checkbox>
<Checkbox variant='radiobox' flex='0 0 30%'>
<Box>
<Icon as={GoNumber} />
<Text>{t('process_create.question.participation_budgeting.title')}</Text>
</Box>
<Text as='span'>Pro</Text>
<Text>{t('process_create.question.participation_budgeting.description')}</Text>
<Box
onClick={() => {
setReason('participatory budgeting')
onOpen()
}}
/>
</Checkbox>
<Checkbox variant='radiobox' flex='0 0 30%'>
<Box>
<Icon as={ImListNumbered} />
<Box>
<Trans
i18nKey='process_create.question.borda_count.title'
components={{
p: <Text />,
}}
/>
</Box>
</Box>
<Text as='span'>Pro</Text>
<Text>{t('process_create.question.borda_count.description')}</Text>
<Box
onClick={() => {
setReason('borda count')
onOpen()
}}
/>
</Checkbox>
</Flex>
</Box>
</>
)
}

export default VotingTypes
3 changes: 3 additions & 0 deletions src/components/ProcessCreate/Questions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { useEffect, useState } from 'react'
import { FieldError, FieldErrors, useFieldArray, useFormContext } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import Question from './Question'
import VotingTypes from './VotingTypes'

interface CustomFieldError extends FieldError {
index: number
}

const CreateProcessQuestions = () => {
const { t } = useTranslation()

const {
watch,
formState: { errors },
Expand Down Expand Up @@ -55,6 +57,7 @@ const CreateProcessQuestions = () => {

return (
<Flex flexDirection='column' gap={5}>
<VotingTypes />
<Box>
<Text className='process-create-title'>{t('form.process_create.question.title')}</Text>
<Text fontSize='sm' color='process_create.description'>
Expand Down