From ab01ff249d06c7490d408047880be115ec3e2fb4 Mon Sep 17 00:00:00 2001 From: Anik Ghosh Date: Tue, 15 Mar 2022 01:24:14 +0530 Subject: [PATCH] invite email modal added --- dashboard/package.json | 1 + dashboard/src/components/InviteEmailModal.tsx | 254 ++++++++++++++++++ dashboard/src/constants.ts | 7 + dashboard/src/pages/Users.tsx | 2 + dashboard/src/utils/index.ts | 11 + 5 files changed, 275 insertions(+) create mode 100644 dashboard/src/components/InviteEmailModal.tsx diff --git a/dashboard/package.json b/dashboard/package.json index af68d43..9f854ba 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -24,6 +24,7 @@ "lodash": "^4.17.21", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-dropzone": "^12.0.4", "react-icons": "^4.3.1", "react-router-dom": "^6.2.1", "typescript": "^4.5.4", diff --git a/dashboard/src/components/InviteEmailModal.tsx b/dashboard/src/components/InviteEmailModal.tsx new file mode 100644 index 0000000..7f69bd5 --- /dev/null +++ b/dashboard/src/components/InviteEmailModal.tsx @@ -0,0 +1,254 @@ +import React, { useState, useCallback } from 'react'; +import { + Button, + Center, + Flex, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + useDisclosure, + useToast, + Tabs, + TabList, + Tab, + TabPanels, + TabPanel, + InputGroup, + Input, + InputRightElement, + Text, + Link, +} from '@chakra-ui/react'; +import { useClient } from 'urql'; +import { FaUserPlus, FaMinusCircle, FaPlus, FaUpload } from 'react-icons/fa'; +import { useDropzone } from 'react-dropzone'; +import { escape } from 'lodash'; +import { validateEmail } from '../utils'; +import { UpdateUser } from '../graphql/mutation'; +import { ArrayInputOperations, csvDemoData } from '../constants'; + +interface emailDataTypes { + value: string; + isInvalid: boolean; +} + +const InviteEmailModal = () => { + const client = useClient(); + const toast = useToast(); + const { isOpen, onOpen, onClose } = useDisclosure(); + const [emails, setEmails] = useState([ + { + value: '', + isInvalid: false, + }, + { + value: '', + isInvalid: false, + }, + { + value: '', + isInvalid: false, + }, + { + value: '', + isInvalid: false, + }, + ]); + const sendInviteHandler = async () => { + onClose(); + }; + const updateEmailListHandler = (operation: string, index: number = 0) => { + switch (operation) { + case ArrayInputOperations.APPEND: + setEmails([ + ...emails, + { + value: '', + isInvalid: false, + }, + ]); + break; + case ArrayInputOperations.REMOVE: + const updatedEmailList = [...emails]; + updatedEmailList.splice(index, 1); + setEmails(updatedEmailList); + break; + default: + break; + } + }; + const inputChangeHandler = (value: string, index: number) => { + const updatedEmailList = [...emails]; + updatedEmailList[index].value = value; + updatedEmailList[index].isInvalid = !validateEmail(value); + setEmails(updatedEmailList); + }; + const onDrop = useCallback((acceptedFiles) => { + console.log(acceptedFiles); + }, []); + const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop }); + return ( + <> + + + + + Invite Email + + + + + Enter emails + Upload CSV + + + + + + Emails + + + + + {emails.map((emailData, index) => ( + + + + inputChangeHandler(e.currentTarget.value, index) + } + /> + + + + + + ))} + + + + + + {isDragActive ? ( + Drop the files here... + ) : ( + +
+ +
+ + Drag 'n' drop the csv file here, or click to select. + + + Download{' '} + e.stopPropagation()} + > + {' '} + sample.csv + {' '} + and modify it.{' '} + +
+ )} +
+
+
+
+
+ + + +
+
+ + ); +}; + +export default InviteEmailModal; diff --git a/dashboard/src/constants.ts b/dashboard/src/constants.ts index 64fa372..6900730 100644 --- a/dashboard/src/constants.ts +++ b/dashboard/src/constants.ts @@ -88,3 +88,10 @@ export const ECDSAEncryptionType = { ES384: 'ES384', ES512: 'ES512', }; + +export const csvDemoData = `email +lakhan.demo@contentment.org +john@gmail.com +anik@contentment.org +harry@potter.com +anikgh89@gmail.com`; diff --git a/dashboard/src/pages/Users.tsx b/dashboard/src/pages/Users.tsx index 5d36c5b..9b9e512 100644 --- a/dashboard/src/pages/Users.tsx +++ b/dashboard/src/pages/Users.tsx @@ -42,6 +42,7 @@ import { UserDetailsQuery } from '../graphql/queries'; import { UpdateUser } from '../graphql/mutation'; import EditUserModal from '../components/EditUserModal'; import DeleteUserModal from '../components/DeleteUserModal'; +import InviteEmailModal from '../components/InviteEmailModal'; interface paginationPropTypes { limit: number; @@ -177,6 +178,7 @@ export default function Users() { Users + {!loading ? ( userList.length > 0 ? ( diff --git a/dashboard/src/utils/index.ts b/dashboard/src/utils/index.ts index 64ca0bf..60f4906 100644 --- a/dashboard/src/utils/index.ts +++ b/dashboard/src/utils/index.ts @@ -64,3 +64,14 @@ export const getObjectDiff = (obj1: any, obj2: any) => { return diff; }; + +export const validateEmail = (email: string) => { + if (!email || email === '') return true; + return email + .toLowerCase() + .match( + /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + ) + ? true + : false; +};