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

hotfix: make Country/Region mandatory in project creation flow #1632

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/modules/project/forms/ProjectRegion.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useQuery } from '@apollo/client'
import { HStack, IconButton, StackProps, useDisclosure, VStack } from '@chakra-ui/react'
import { useAtom } from 'jotai'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { PiX } from 'react-icons/pi'
Expand All @@ -15,6 +16,7 @@ import { FieldContainer } from '../../../shared/components/form/FieldContainer'
import { SkeletonLayout } from '../../../shared/components/layouts'
import { Country, Location, Maybe, Project, ProjectCountriesGetResult, ProjectRegionsGetResult } from '../../../types'
import { ProjectState } from '../state/projectAtom'
import { projectFormErrorAtom } from '../state/projectFormAtom'

const useStyles = createUseStyles(({ colors }: AppTheme) => ({
container: {
Expand Down Expand Up @@ -51,6 +53,8 @@ export const ProjectRegion = ({ location, updateProject, ...rest }: ProjectRegio
const { t } = useTranslation()
const classes = useStyles()

const [projectFormError, setProjectFormError] = useAtom(projectFormErrorAtom)

const [inputValue, setInputValue] = useState('')
const { isOpen, onOpen, onClose } = useDisclosure()

Expand Down Expand Up @@ -98,7 +102,12 @@ export const ProjectRegion = ({ location, updateProject, ...rest }: ProjectRegio
}
}

const clearLocationError = () => {
setProjectFormError((prev) => ({ ...prev, location: undefined }))
}

const removeRegion = () => {
clearLocationError()
updateProject({
location: { region: '', country: { code: '', name: '' } },
})
Expand All @@ -114,7 +123,7 @@ export const ProjectRegion = ({ location, updateProject, ...rest }: ProjectRegio

return (
<FieldContainer
title={t('Region')}
title={`${t('Region')}*`}
subtitle={
<span>{t('Get found more easily by putting your project on the map. Select a country or region')}</span>
}
Expand All @@ -139,8 +148,11 @@ export const ProjectRegion = ({ location, updateProject, ...rest }: ProjectRegio
inputValue={inputValue}
onMenuOpen={onOpen}
onMenuClose={onClose}
isInvalid={Boolean(projectFormError.location)}
onFocus={clearLocationError}
/>
)}

<HStack width="100%" spacing="10px" flexWrap={'wrap'}>
{displayLocation && (
<HStack borderRadius="4px" paddingLeft="8px" backgroundColor="neutral1.2">
Expand All @@ -160,6 +172,11 @@ export const ProjectRegion = ({ location, updateProject, ...rest }: ProjectRegio
)}
</HStack>
</VStack>
{projectFormError.location && (
<Body size="xs" color="error.9" w="full" textAlign={'start'}>
{projectFormError.location}
</Body>
)}
</FieldContainer>
)
}
2 changes: 2 additions & 0 deletions src/modules/project/pages1/projectCreation/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,5 @@ export const tagToRewardCategoryMapping: { [key: string]: RewardCategory[] } = {
homeschooling: [RewardCategory.Shoutout, RewardCategory.Course, RewardCategory.Experience],
minecraft: [RewardCategory.Game],
}

export const ProjectCountryCodesThatAreRestricted = ['UA', 'PSE', 'YE', 'IL']
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is missing the sanctioned countries. Russia, North Korea, etc.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useEffect } from 'react'
import { useNavigate } from 'react-router'

import { useProjectAtom } from '@/modules/project/hooks/useProjectAtom'
import { getPath } from '@/shared/constants'

export const useLocationMandatoryRedirect = () => {
const navigate = useNavigate()
const { project, loading } = useProjectAtom()

useEffect(() => {
if (project && !loading && !project.location?.country?.code) {
navigate(getPath('launchProjectDetails', project?.id))
}
}, [loading, project, navigate])
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { dimensions, getPath } from '../../../../../shared/constants'
import { ProjectStoryForm } from '../../../forms/ProjectStoryForm'
import { FormContinueButton } from '../components/FormContinueButton'
import { ProjectCreateLayout } from '../components/ProjectCreateLayout'
import { useLocationMandatoryRedirect } from '../hooks/useLocationMandatoryRedirect'
import { useProjectStoryForm } from '../hooks/useProjectStoryForm'

export const ProjectCreateStory = () => {
Expand All @@ -25,6 +26,8 @@ export const ProjectCreateStory = () => {

const form = useProjectStoryForm({ project })

useLocationMandatoryRedirect()

const onLeave = () => {
if (!project) {
return navigate(-1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useNotification } from '../../../../../utils'
import { ProjectCreationWalletConnectionForm } from '..'
import { FormContinueButton } from '../components/FormContinueButton'
import { ProjectCreateLayout } from '../components/ProjectCreateLayout'
import { useLocationMandatoryRedirect } from '../hooks/useLocationMandatoryRedirect'
import { ConnectionOption, useWalletForm } from '../hooks/useWalletForm'
import { ProjectCreateCompletionPage } from './ProjectCreateCompletionPage'

Expand All @@ -27,6 +28,8 @@ export const ProjectCreationWalletConnectionPage = () => {
const { project, loading } = useProjectAtom()
const { createWallet } = useProjectWalletAPI()

useLocationMandatoryRedirect()

const [isReadyForLaunch, setReadyForLaunch] = useState(false)

const handleNext = (createWalletInput: CreateWalletInput | null) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { VStack } from '@chakra-ui/react'
import { useSetAtom } from 'jotai'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'

import { useProjectDetailsAPI } from '@/modules/project/API/useProjectDetailsAPI'
import { projectFormErrorAtom } from '@/modules/project/state/projectFormAtom'

import TitleWithProgressBar from '../../../../../components/molecules/TitleWithProgressBar'
import { getPath } from '../../../../../shared/constants'
Expand All @@ -12,27 +14,47 @@ import { ProjectRegion } from '../../../forms/ProjectRegion'
import { ProjectTagsCreateEdit } from '../../../forms/ProjectTagsCreateEdit'
import { FormContinueButton } from '../components/FormContinueButton'
import { ProjectCreateLayout } from '../components/ProjectCreateLayout'
import { ProjectCountryCodesThatAreRestricted } from '../constants'
import { useProjectDetailsForm } from '../hooks/useProjectDetailsForm'

export const ProjectDetails = () => {
const { t } = useTranslation()
const navigate = useNavigate()

const { toast, unexpected } = useNotification()
const toast = useNotification()

const { queryProjectDetails } = useProjectDetailsAPI(true)

const { updateProject, saveProject, saveTags, setLinks, setTags, project, tags, linkError, tagsLoading, isDirty } =
const { updateProject, saveProject, saveTags, setLinks, setTags, project, tags, linkError, tagsLoading } =
useProjectDetailsForm()

const setProjectFormError = useSetAtom(projectFormErrorAtom)

const onSubmit = async () => {
if (!project) {
return
}

if (!project.location || !project.location.country || !project.location.country.code) {
toast.error({
title: 'Please select a region',
description: 'Project region is required to proceed',
})
setProjectFormError((prev) => ({ ...prev, location: 'Project region is required' }))
return
}

if (ProjectCountryCodesThatAreRestricted.includes(project.location.country.code)) {
toast.error({
title: 'Country not supported',
description: 'We are not able to support projects from this country',
})
setProjectFormError((prev) => ({ ...prev, location: 'Country not supported' }))
return
}

if (linkError.includes(true)) {
toast({
status: 'warning',
toast.warning({
title: 'failed to update project',
description: 'please enter a valid url for project links',
})
Expand All @@ -45,7 +67,7 @@ export const ProjectDetails = () => {

navigate(getPath('launchProjectStory', project.id))
} catch (e) {
unexpected()
toast.unexpected()
}
}

Expand All @@ -66,7 +88,7 @@ export const ProjectDetails = () => {
return (
<>
<ProjectCreateLayout
continueButton={<FormContinueButton isSkip={!isDirty} flexGrow={1} {...nextProps} />}
continueButton={<FormContinueButton flexGrow={1} {...nextProps} />}
onBackClick={onBackClick}
title={<TitleWithProgressBar title={t('Links & tags')} subtitle={t('Create a project')} index={2} length={5} />}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import TitleWithProgressBar from '../../../../../../components/molecules/TitleWi
import { getPath } from '../../../../../../shared/constants'
import { FormContinueButton } from '../../components/FormContinueButton'
import { ProjectCreateLayout } from '../../components/ProjectCreateLayout'
import { useLocationMandatoryRedirect } from '../../hooks/useLocationMandatoryRedirect'

export const ProjectCreateRewards = () => {
const { t } = useTranslation()
Expand All @@ -18,6 +19,8 @@ export const ProjectCreateRewards = () => {
const { project } = useProjectAtom()
const { rewards } = useRewardsAtom()

useLocationMandatoryRedirect()

const isNew = useMatch(getPath('launchProjectRewardsCreate', project?.id))
const isEdit = useMatch(getPath('launchProjectRewardsEdit', project?.id, ':rewardId'))
const isCreatingOrEditing = isNew || isEdit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Button, ButtonProps, VStack } from '@chakra-ui/react'
import { useSetAtom } from 'jotai'
import { useTranslation } from 'react-i18next'

import { useProjectDetailsAPI } from '@/modules/project/API/useProjectDetailsAPI'
import { ProjectLinks } from '@/modules/project/forms/ProjectLinks'
import { ProjectRegion } from '@/modules/project/forms/ProjectRegion'
import { ProjectTagsCreateEdit } from '@/modules/project/forms/ProjectTagsCreateEdit'
import { projectFormErrorAtom } from '@/modules/project/state/projectFormAtom'
import { useNotification } from '@/utils'

import { ProjectCountryCodesThatAreRestricted } from '../../projectCreation/constants'
import { useProjectDetailsForm } from '../../projectCreation/hooks/useProjectDetailsForm'
import { DashboardLayout } from '../common'
import { ProjectUnsavedModal, useProjectUnsavedModal } from '../common/ProjectUnsavedModal'
Expand All @@ -19,12 +22,31 @@ export const ProjectDashboardDetails = () => {

const { project, isDirty, linkError, saveProject, saving, saveTags, setLinks, setTags, tags, updateProject } =
useProjectDetailsForm()
const setProjectFormError = useSetAtom(projectFormErrorAtom)

const unsavedModal = useProjectUnsavedModal({
hasUnsaved: isDirty,
})

const onSubmit = async () => {
if (!project.location || !project.location.country || !project.location.country.code) {
toast.error({
title: 'Please select a region',
description: 'Project region is required to proceed',
})
setProjectFormError((prev) => ({ ...prev, location: 'Project region is required' }))
return
}

if (ProjectCountryCodesThatAreRestricted.includes(project.location.country.code)) {
toast.error({
title: 'Country not supported',
description: 'We are not able to support projects from this country',
})
setProjectFormError((prev) => ({ ...prev, location: 'Country not supported' }))
return
}

if (linkError.includes(true)) {
toast.warning({
title: 'failed to update project',
Expand Down
5 changes: 5 additions & 0 deletions src/modules/project/state/projectFormAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ export const diffProjectAtom = atom((get) => {
])
})

type ProjectFormError = { [key in keyof ProjectState]: string }
/** Project form error state */
export const projectFormErrorAtom = atom<ProjectFormError>({} as ProjectFormError)

/** Reset all real-atoms in this file to it's initial State */
export const projectFormAtomReset = atom(null, (get, set) => {
set(formProjectAtom, {} as ProjectState)
set(projectFormErrorAtom, {} as ProjectFormError)
})
Loading