Untitled
unknown
plain_text
a year ago
22 kB
6
Indexable
import { Badge, Box, Button, Flex, FormControl, FormLabel, HStack, Input, Popover, PopoverArrow, PopoverBody, PopoverContent, PopoverTrigger, Select, Spinner, Table, TableContainer, Tag, Tbody, Td, Text, Th, Thead, Tr, useDisclosure } from "@chakra-ui/react";
import { compact, filter, join, map, omit, size } from "lodash";
import { useRouter } from "next/router";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { AiOutlineLeft, AiOutlineRight } from "react-icons/ai";
import { CustomContainer } from "../../components/CustomContainer";
import { STATUS } from "../../constants";
import { useStudenStore } from "../../store/StudentsStore";
import { useLeadsStore } from "../../store/LeadsStore";
import { InfoIcon } from "@chakra-ui/icons";
import dayjs from "dayjs";
import { ConsumeModal } from "./ConsumeModal";
import { UploadLeadsModal } from "./UploadLeadModal";
import { ManageLeadsCall } from "./ManageLeadsCall";
import { EmptyPage } from "../../utils/EmptyPage";
const pagePerLimits = [10, 20, 30, 40, 50];
export const AllLeads = ({ leadListId, getOneLeadList }) => {
const router = useRouter()
const { control, handleSubmit, getValues, reset, setValue, watch } = useForm()
const { isOpen, onOpen, onClose } = useDisclosure()
const { isOpen: manageLeadIsOpen, onOpen: manageLeadOnOpen, onClose: manageLeadOnClose } = useDisclosure()
const { getAllLeadsAction, getAllLeadsStatus, allLeads } = useStudenStore(s => ({
getAllLeadsAction: s.getAllLeadsAction,
getAllLeadsStatus: s.getAllLeadsStatus,
allLeads: s.allLeads
}))
const { getFbAccountsAction, getFbAccountsStatus, fbAccounts, getFbPagesAction, getFbPagesStatus, fbPagesList, getAllActiveFormsAction, getAllActiveFormsStatus, allActiveForms, } = useLeadsStore(s => ({
getFbAccountsAction: s.getFbAccountsAction,
getFbAccountsStatus: s.getFbAccountsStatus,
fbAccounts: s.fbAccounts,
getFbPagesAction: s.getFbPagesAction,
getFbPagesStatus: s.getFbPagesStatus,
fbPagesList: s.fbPagesList,
getAllActiveFormsAction: s.getAllActiveFormsAction,
getAllActiveFormsStatus: s.getAllActiveFormsStatus,
allActiveForms: s.allActiveForms,
}))
useEffect(() => {
getFbAccountsAction()
getFbPagesAction()
}, [getFbAccountsAction, getFbPagesAction])
const selectedPage = watch("pageId")
useEffect(() => {
if (selectedPage) {
getAllActiveFormsAction({ pageId: selectedPage })
}
}, [getAllActiveFormsAction, selectedPage])
const [curPage, setCurPage] = useState(1);
const [pagePerLimit, setPagePerLimit] = useState(10);
const getData = useCallback((data) => {
let payload = { page: curPage, limit: pagePerLimit, ...data }
if (leadListId) { payload.leadListId = leadListId }
getAllLeadsAction(payload)
}, [getAllLeadsAction, curPage, pagePerLimit, leadListId])
const hasNextPage = useMemo(
() => parseInt(allLeads?.page) != allLeads?.totalPages,
[allLeads],
);
const hasPrevPage = useMemo(
() => parseInt(allLeads?.page) != 1,
[allLeads],
);
useEffect(() => {
getData()
}, [getData])
const goToNextPage = () => {
if (hasNextPage)
setCurPage(pre => pre + 1)
}
const goToPrevPage = () => {
if (hasPrevPage)
setCurPage(pre => pre - 1)
}
const _submit = (d) => {
const payload = { page: curPage, limit: pagePerLimit }
if (d.name) { payload.name = d.name }
if (d.source) { payload.leadSource = d.source }
if (d.formId) { payload.facebookFormId = d.formId }
if (d.pageId) { payload.facebookPageId = d.pageId }
if (curPage === 1)
getData()
else
setCurPage(1)
}
const _reset = () => {
setValue("source", "")
setValue("name", "")
if (curPage === 1)
getData({ page: curPage, limit: pagePerLimit })
else
setCurPage(1)
}
const handlePageLimitChange = (e) => {
setCurPage(1);
setPagePerLimit(e.target.value)
}
const selectedSource = watch("source")
const selectedAccount = watch("accountId")
useEffect(() => {
setValue("accountId", "")
setValue("pageId", "")
setValue("formId", "")
}, [selectedSource, setValue])
useEffect(() => {
setValue("pageId", "")
setValue("formId", "")
}, [selectedAccount, setValue])
useEffect(() => {
setValue("formId", "")
}, [selectedPage, setValue])
const [toggleConsumeModal, setToggleConsumeModal] = useState(null)
const consumeAction = (id) => {
setToggleConsumeModal(id)
}
const manageLeadsCallHandler = () => {
manageLeadOnOpen()
}
const goToProfile = (user) => {
if (user?._id) {
router.push(`/leads/${user._id}`);
}
}
return (
<CustomContainer heading={leadListId ? getOneLeadList?.name : "All Leads"} isBackButton={true} >
<Box>
<Flex justifyContent={"space-between"} >
<Box>
<form onSubmit={handleSubmit(_submit)}>
<HStack align={"end"} mb={2}>
<FormControl w="fit-content">
<FormLabel>Name</FormLabel>
<Controller
name="name"
control={control}
render={({ field }) => (
<Input placeholder="Enter Name" {...field} type="text" size={'sm'} />
)}
/>
</FormControl>
<FormControl w="fit-content">
<FormLabel>Source</FormLabel>
<Controller
name="source"
control={control}
render={({ field }) => (
<Select size={'sm'} {...field} placeholder="Select Source" >
<option value="FACEBOOK">FACEBOOK</option>
<option value="WEBSITE">WEBSITE</option>
<option value="OTHER">OTHER</option>
</Select>
)}
/>
</FormControl>
{watch("source") === "FACEBOOK" ?
<>
<FormControl w="fit-content" isRequired={watch("source") === "FACEBOOK"} >
<FormLabel>Account</FormLabel>
<Controller
name="accountId"
control={control}
render={({ field }) => (
<Select size={'sm'} {...field} placeholder="Select Account">
{map(fbAccounts, acc => (
<option value={acc._id}>{acc.name}</option>
))}
</Select>
)}
/>
</FormControl>
<FormControl w="fit-content" isRequired={watch("source") === "FACEBOOK"} >
<FormLabel>Page</FormLabel>
<Controller
name="pageId"
control={control}
render={({ field }) => (
<Select {...field} size={'sm'} placeholder="Select Page">
{map(filter(fbPagesList, p => p.facebookAccountId === watch("accountId")), acc => (
<option value={acc.pageId}>{acc.name}</option>
))}
</Select>
)}
/>
</FormControl>
<FormControl w="fit-content">
<FormLabel>Ads</FormLabel>
<Controller
name="formId"
control={control}
render={({ field }) => (
<Select size={'sm'} {...field} placeholder="Select Ads">
{map(allActiveForms, acc => (
<option value={acc.formId}>{acc.name}</option>
))}
</Select>
)}
/>
</FormControl>
</>
:
null
}
<HStack>
<Button size="sm" colorScheme="blue" type="submit">Apply</Button>
<Button size="sm" variant={'outline'} onClick={_reset}>Reset</Button>
</HStack>
</HStack>
</form>
</Box>
{leadListId ? <Box>
<Flex>
<Button mr={3} size={"sm"} colorScheme="blue" onClick={onOpen}>Upload Leads Excel</Button>
<Button size={"sm"} colorScheme="green" onClick={manageLeadsCallHandler}>Manage Leads Call</Button>
</Flex>
</Box> : null}
</Flex>
<Flex pt={3} justify='space-between' bg="white">
<Box>
<Tag mb={2} px={4} variant='subtle' fontWeight='bold' py={2} colorScheme='blue'>Total Records {allLeads?.totalDocs || 0}</Tag>
</Box>
<Flex flexGrow={'1'} pl={2} align='center' justify='flex-end' mb={2}>
<Box maxW='300px'>
<Select onChange={handlePageLimitChange} bg='white' size='sm'>
{
map(pagePerLimits, limit => <option key={limit} value={limit}>{limit} Records per page</option>)
}
</Select>
</Box>
<Flex ml={8} align='center'>
<Box>
{allLeads?.page || 0} - {allLeads?.totalPages}
</Box>
<Flex ml={2} align='center'>
<Box onClick={goToPrevPage} cursor='pointer' color={hasPrevPage ? 'gray.700' : 'gray.500'} _hover={hasPrevPage && { color: 'gray.700' }}>
<AiOutlineLeft />
</Box>
<Box onClick={goToNextPage} cursor='pointer' color={hasNextPage ? 'gray.700' : 'gray.500'} ml={4} _hover={hasNextPage && { color: 'gray.700' }}>
<AiOutlineRight />
</Box>
</Flex>
</Flex>
</Flex>
</Flex>
<Box>
{size(allLeads?.docs) > 0 ?
<TableContainer>
<Table size={'sm'}>
<Thead bg={'gray.100'}>
<Tr>
<Th>Name</Th>
<Th>Father</Th>
<Th>Contact</Th>
<Th>Created At</Th>
<Th>Consume</Th>
<Th></Th>
<Th>Action</Th>
</Tr>
</Thead>
<Tbody>
{getAllLeadsStatus === STATUS.FETCHING ?
<Tr>
<Td colSpan={6} textAlign='center'>
<Spinner />
</Td>
</Tr>
: allLeads?.docs?.length ?
allLeads.docs.map(user => {
const dataFields = omit(user, "branchId", "leadListId", "createdAt", "facebookFormId", "facebookPageId", "iid", "leadSource", "meta", "updatedAt", "__v", "_id", "name", "father", "contact", "contact1", "consumed", "consumedBy", "consumeRemark", "oldData")
const data = { ...dataFields, ...(dataFields.address ?? {}), ...(dataFields.academicDetails ?? {}) }
return (
<Tr key={user._id}>
<Td _hover={{ color: "blue.500" }} onClick={() => goToProfile(user)} cursor={"pointer"} py={0}>
<Text fontWeight={"semibold"}>{user.name}</Text>
</Td>
<Td>
<Text>{user.father || '-'}</Text>
</Td>
<Td w={100}>
<Text>{join(compact([user.contact, user.contact1]), ', ') || '-'}</Text>
</Td>
<Td>{user.createdAt ? dayjs(user.createdAt).format("DD-MM-YYYY") : ''}</Td>
<Td>
{user.consumed === true ?
<Popover trigger="hover">
<PopoverTrigger>
<Badge cursor="pointer" colorScheme="green" variant="outline">Consumed</Badge>
</PopoverTrigger>
<PopoverContent bg='black' color='white' whiteSpace={"normal"}>
<PopoverArrow bg='black' />
<PopoverBody maxW="40vw" h="fit-content">
<Box>
<Flex mb={2}>
<Text>Consumed By: </Text>
<Text ml={2}>{user.consumedBy?.name}</Text>
</Flex>
<Text wordBreak="break-word">{user.consumeRemark}</Text>
</Box>
</PopoverBody>
</PopoverContent>
</Popover>
:
<Button size="sm" variant={"outline"} colorScheme="blue" onClick={() => consumeAction(user._id)}>Consume</Button>
}
</Td>
<Td>
{Object.keys(data)?.length ?
<Popover trigger="hover" placement={"left"}>
<PopoverTrigger>
<InfoIcon color="orange.300" />
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
<Box>
{map(data, (d, key) => {
const word = key.replace(/([A-Z])/g, ' $1');
if (typeof (d) === 'object') { return }
return (
<Flex><strong>{word[0].toUpperCase() + word.substring(1).toLowerCase()} - </strong> {d}</Flex>
)
})}
</Box>
</PopoverBody>
</PopoverContent>
</Popover>
:
null
}
</Td>
<Td>
<Button size="sm" variant={"outline"} colorScheme="blue" onClick={() => router.push("/enquiry/add?id=" + user._id)}>Add Enquiry</Button>
</Td>
</Tr>
)
})
:
null
}
</Tbody>
</Table>
{toggleConsumeModal && <ConsumeModal student={toggleConsumeModal} closeModal={() => setToggleConsumeModal(null)} />}
</TableContainer>
:
<EmptyPage height={300} />
}
</Box>
</Box>
<UploadLeadsModal isOpen={isOpen} onClose={onClose} leadListId={leadListId} />
<ManageLeadsCall isOpen={manageLeadIsOpen} onClose={manageLeadOnClose} leadListId={leadListId} getOneLeadList={getOneLeadList} />
</CustomContainer>
)
}Editor is loading...
Leave a Comment