Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
233 changes: 199 additions & 34 deletions frontend/src/admin/SuperAdminUserList.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@ import {
AccordionPanel,
Badge,
Box,
Button,
Flex,
IconButton,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Stack,
Text,
useDisclosure,
useToast,
} from '@chakra-ui/react'

import { FIND_MY_USERS } from '../graphql/queries'
import { CLOSE_ACCOUNT, SIGN_OUT } from '../graphql/mutations'
import { LoadingMessage } from '../components/LoadingMessage'
import { ErrorFallbackMessage } from '../components/ErrorFallbackMessage'
import { RelayPaginationControls } from '../components/RelayPaginationControls'
Expand All @@ -24,6 +34,10 @@ import { CheckCircleIcon, EditIcon, MinusIcon } from '@chakra-ui/icons'
import { SearchBox } from '../components/SearchBox'
import { UserListModal } from './UserListModal'
import { string } from 'prop-types'
import { FormField } from '../components/fields/FormField'
import { createValidationSchema } from '../utilities/fieldRequirements'
import { Formik } from 'formik'
import { useMutation } from '@apollo/client'

export function SuperAdminUserList({ permission }) {
const [mutation, setMutation] = useState()
Expand All @@ -32,15 +46,76 @@ export function SuperAdminUserList({ permission }) {
const [searchTerm, setSearchTerm] = useState('')
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('')
const [usersPerPage, setUsersPerPage] = useState(10)
const [closeAccountUser, setCloseAccountUser] = useState({
userName: '',
displayName: '',
userId: '',
})

const toast = useToast()
const { isOpen, onOpen, onClose } = useDisclosure()
const {
isOpen: closeAccountIsOpen,
onOpen: closeAccountOnOpen,
onClose: closeAccountOnClose,
} = useDisclosure()

const memoizedSetDebouncedSearchTermCallback = useCallback(() => {
setDebouncedSearchTerm(searchTerm)
}, [searchTerm])

useDebouncedFunction(memoizedSetDebouncedSearchTermCallback, 500)

const [closeAccount, { loading: loadingCloseAccount }] = useMutation(
CLOSE_ACCOUNT,
{
refetchQueries: ['FindMyUsers'],
awaitRefetchQueries: true,

onError(error) {
toast({
title: t`Unable to close this account.`,
description: error.message,
status: 'error',
duration: 9000,
isClosable: true,
position: 'top-left',
})
},
onCompleted({ closeAccount }) {
if (closeAccount.result.__typename === 'CloseAccountResult') {
toast({
title: t`Account Closed Successfully`,
description: t`Tracker account has been successfully closed.`,
status: 'success',
duration: 9000,
isClosable: true,
position: 'top-left',
})
closeAccountOnClose()
} else if (closeAccount.result.__typename === 'CloseAccountError') {
toast({
title: t`Unable to close the account.`,
description: closeAccount.result.description,
status: 'error',
duration: 9000,
isClosable: true,
position: 'top-left',
})
} else {
toast({
title: t`Incorrect send method received.`,
description: t`Incorrect closeAccount.result typename.`,
status: 'error',
duration: 9000,
isClosable: true,
position: 'top-left',
})
}
},
},
)

const {
loading,
isLoadingMore,
Expand Down Expand Up @@ -152,8 +227,7 @@ export function SuperAdminUserList({ permission }) {
onOpen()
console.log(`Removed user from org ${orgName}`)
}}
p={2}
m={0}
p="2"
icon={<MinusIcon />}
/>
<IconButton
Expand All @@ -164,8 +238,7 @@ export function SuperAdminUserList({ permission }) {
onOpen()
console.log(`Edit user in org ${orgName}`)
}}
p={2}
m={0}
p="2"
icon={<EditIcon />}
/>
</Stack>
Expand Down Expand Up @@ -224,37 +297,129 @@ export function SuperAdminUserList({ permission }) {

return (
<AccordionItem key={userId}>
<AccordionButton
width="100%"
p="4"
alignItems={{ base: 'flex-start', md: 'center' }}
flexDirection={{ base: 'column', md: 'row' }}
_hover={{ bg: 'gray.100' }}
mb="2"
borderWidth="1px"
borderColor="black"
rounded="md"
>
<Flex w="100%" textAlign="left">
<Text minW="33%">{userName}</Text>
<Text minW="25%">{displayName}</Text>
<Box minW="25%">
<Badge
variant="solid"
bg={emailValidated ? 'strong' : 'weak'}
pt={1}
mr={{ md: '1rem' }}
justifySelf={{ base: 'start', md: 'end' }}
>
<Trans>Verified</Trans>
</Badge>
</Box>
<Text minW="17%">
<Trans>Affiliations:</Trans> {totalCount}
</Text>
<Box>
<Flex w="100%">
<AccordionButton
width="100%"
p="4"
alignItems={{ base: 'flex-start', md: 'center' }}
flexDirection={{ base: 'column', md: 'row' }}
_hover={{ bg: 'gray.100' }}
mb="2"
borderWidth="1px"
borderColor="black"
rounded="md"
>
<Flex w="100%" textAlign="left">
<Text minW="33%">{userName}</Text>
<Text minW="25%">{displayName}</Text>
<Box minW="25%">
<Badge
variant="solid"
bg={emailValidated ? 'strong' : 'weak'}
pt={1}
mr={{ md: '1rem' }}
justifySelf={{ base: 'start', md: 'end' }}
>
<Trans>Verified</Trans>
</Badge>
</Box>
<Text minW="17%">
<Trans>Affiliations:</Trans> {totalCount}
</Text>
</Flex>
</AccordionButton>
<Button
alignSelf="center"
variant="danger"
onClick={() => {
setCloseAccountUser({ userId, userName, displayName })
closeAccountOnOpen()
}}
w={{ base: '100%', md: 'auto' }}
mx="2"
mb="2"
>
<Trans>Close Account</Trans>
</Button>
</Flex>
</AccordionButton>
<AccordionPanel>{userAffiliations}</AccordionPanel>
<AccordionPanel>{userAffiliations}</AccordionPanel>
</Box>

<Modal
isOpen={closeAccountIsOpen}
onClose={closeAccountOnClose}
motionPreset="slideInBottom"
>
<Formik
validateOnBlur={false}
initialValues={{
matchEmail: '',
}}
initialTouched={{
matchEmail: true,
}}
validationSchema={createValidationSchema(['matchEmail'], {
matches: closeAccountUser.userName,
})}
onSubmit={async () => {
await closeAccount({
variables: { userId: closeAccountUser.userId },
})
}}
>
{({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader>
<Trans>Close Account</Trans>
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Trans>
This action CANNOT be reversed, are you sure you
wish to to close the account{' '}
{closeAccountUser.displayName}?
</Trans>

<Text mb="1rem">
<Trans>
Enter "{closeAccountUser.userName}" below to
confirm removal. This field is case-sensitive.
</Trans>
</Text>

<FormField
name="matchEmail"
label={t`User Email`}
placeholder={closeAccountUser.userName}
/>
</ModalBody>

<ModalFooter>
<Button
variant="primaryOutline"
mr="4"
onClick={closeAccountOnClose}
>
<Trans>Cancel</Trans>
</Button>

<Button
variant="primary"
mr="4"
type="submit"
isLoading={loadingCloseAccount}
>
<Trans>Confirm</Trans>
</Button>
</ModalFooter>
</ModalContent>
</form>
)}
</Formik>
</Modal>
</AccordionItem>
)
},
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/auth/TwoFactorAuthenticatePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default function TwoFactorAuthenticatePage() {
isClosable: true,
position: 'top-left',
})
history.push('/sign-in')
},
onCompleted({ authenticate }) {
// User successfully completes tfa validation
Expand All @@ -48,9 +49,9 @@ export default function TwoFactorAuthenticatePage() {
if (authenticate.result.user.preferredLang === 'ENGLISH') activate('en')
else if (authenticate.result.user.preferredLang === 'FRENCH')
activate('fr')
// // redirect to the home page.
// redirect to the home page.
history.replace(from)
// // Display a welcome message
// Display a welcome message
toast({
title: i18n._(t`Sign In.`),
description: i18n._(t`Welcome, you are successfully signed in!`),
Expand All @@ -72,6 +73,7 @@ export default function TwoFactorAuthenticatePage() {
isClosable: true,
position: 'top-left',
})
history.push('/sign-in')
} else {
toast({
title: t`Incorrect send method received.`,
Expand All @@ -81,7 +83,7 @@ export default function TwoFactorAuthenticatePage() {
isClosable: true,
position: 'top-left',
})
console.log('Incorrect authenticate.result typename.')
history.push('/sign-in')
}
},
})
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/landing/LandingPageSummaries.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { useQuery } from '@apollo/client'
import { SummaryGroup } from '../summaries/SummaryGroup'
import { HTTPS_AND_DMARC_SUMMARY } from '../graphql/queries'
import { Box } from '@chakra-ui/react'
import { LoadingMessage } from '../components/LoadingMessage'
import { ErrorFallbackMessage } from '../components/ErrorFallbackMessage'

export function LandingPageSummaries() {
const { _loading, _error, data } = useQuery(HTTPS_AND_DMARC_SUMMARY)
const { loading, error, data } = useQuery(HTTPS_AND_DMARC_SUMMARY)

if (loading) return <LoadingMessage />
if (error) return <ErrorFallbackMessage error={error} />

return (
<Box w="100%">
Expand Down
Loading