'can see create by in meeting'
5 files changed, +983 -481
+307-161Client/src/views/admin/meeting/View.js
| @@ -1,4 +1,12 @@ | ||
| 1 | -import { Box, Button, Flex, Grid, GridItem, Heading, Text } from "@chakra-ui/react"; | |
| 1 | +import { | |
| 2 | + Box, | |
| 3 | + Button, | |
| 4 | + Flex, | |
| 5 | + Grid, | |
| 6 | + GridItem, | |
| 7 | + Heading, | |
| 8 | + Text, | |
| 9 | +} from "@chakra-ui/react"; | |
| 2 | 10 | import Card from "components/card/Card"; |
| 3 | 11 | import { HSeparator } from "components/separator/Separator"; |
| 4 | 12 | import Spinner from "components/spinner/Spinner"; |
| @@ -14,180 +22,318 @@ import CommonDeleteModel from "components/commonDeleteModel"; | ||
| 14 | 22 | import { FaFilePdf } from "react-icons/fa"; |
| 15 | 23 | import html2pdf from "html2pdf.js"; |
| 16 | 24 | const View = () => { |
| 25 | + const param = useParams(); | |
| 17 | 26 | |
| 18 | - const param = useParams() | |
| 27 | + const [data, setData] = useState(); | |
| 28 | + const [deleteMany, setDeleteMany] = useState(false); | |
| 29 | + const user = JSON.parse(localStorage.getItem("user")); | |
| 30 | + const [isLoding, setIsLoding] = useState(false); | |
| 31 | + const [loading, setLoading] = useState(false); | |
| 32 | + const navigate = useNavigate(); | |
| 33 | + const params = useParams(); | |
| 19 | 34 | |
| 20 | - const [data, setData] = useState() | |
| 21 | - const [deleteMany, setDeleteMany] = useState(false); | |
| 22 | - const user = JSON.parse(localStorage.getItem("user")) | |
| 23 | - const [isLoding, setIsLoding] = useState(false) | |
| 24 | - const [loading, setLoading] = useState(false) | |
| 25 | - const navigate = useNavigate() | |
| 26 | - const params = useParams(); | |
| 35 | + const fetchData = async () => { | |
| 36 | + setIsLoding(true); | |
| 37 | + let response = await getApi("api/meeting/view/", param.id); | |
| 38 | + setData(response?.data); | |
| 39 | + setIsLoding(false); | |
| 40 | + }; | |
| 27 | 41 | |
| 42 | + useEffect(() => { | |
| 43 | + fetchData(); | |
| 44 | + }, []); | |
| 28 | 45 | |
| 29 | - const fetchData = async () => { | |
| 30 | - setIsLoding(true) | |
| 31 | - let response = await getApi('api/meeting/view/', param.id) | |
| 32 | - setData(response?.data); | |
| 33 | - setIsLoding(false) | |
| 46 | + const generatePDF = () => { | |
| 47 | + setLoading(true); | |
| 48 | + const element = document.getElementById("reports"); | |
| 49 | + const hideBtn = document.getElementById("hide-btn"); | |
| 50 | + if (element) { | |
| 51 | + hideBtn.style.display = "none"; | |
| 52 | + html2pdf() | |
| 53 | + .from(element) | |
| 54 | + .set({ | |
| 55 | + margin: [0, 0, 0, 0], | |
| 56 | + filename: `Meeting_Details_${moment().format("DD-MM-YYYY")}.pdf`, | |
| 57 | + image: { type: "jpeg", quality: 0.98 }, | |
| 58 | + html2canvas: { scale: 2, useCORS: true, allowTaint: true }, | |
| 59 | + jsPDF: { unit: "in", format: "letter", orientation: "portrait" }, | |
| 60 | + }) | |
| 61 | + .save() | |
| 62 | + .then(() => { | |
| 63 | + setLoading(false); | |
| 64 | + hideBtn.style.display = ""; | |
| 65 | + }); | |
| 66 | + // }, 500); | |
| 67 | + } else { | |
| 68 | + console.error("Element with ID 'reports' not found."); | |
| 69 | + setLoading(false); | |
| 34 | 70 | } |
| 71 | + }; | |
| 35 | 72 | |
| 36 | - useEffect(() => { | |
| 37 | - fetchData() | |
| 38 | - }, []) | |
| 39 | - | |
| 40 | - const generatePDF = () => { | |
| 41 | - setLoading(true) | |
| 42 | - const element = document.getElementById("reports"); | |
| 43 | - const hideBtn = document.getElementById("hide-btn"); | |
| 44 | - if (element) { | |
| 45 | - hideBtn.style.display = 'none'; | |
| 46 | - html2pdf() | |
| 47 | - .from(element) | |
| 48 | - .set({ | |
| 49 | - margin: [0, 0, 0, 0], | |
| 50 | - filename: `Meeting_Details_${moment().format("DD-MM-YYYY")}.pdf`, | |
| 51 | - image: { type: "jpeg", quality: 0.98 }, | |
| 52 | - html2canvas: { scale: 2, useCORS: true, allowTaint: true }, | |
| 53 | - jsPDF: { unit: "in", format: "letter", orientation: "portrait" }, | |
| 54 | - }) | |
| 55 | - .save().then(() => { | |
| 56 | - setLoading(false) | |
| 57 | - hideBtn.style.display = ''; | |
| 58 | - }) | |
| 59 | - // }, 500); | |
| 60 | - } else { | |
| 61 | - console.error("Element with ID 'reports' not found."); | |
| 62 | - setLoading(false) | |
| 63 | - } | |
| 64 | - }; | |
| 65 | - | |
| 66 | - const handleDeleteMeeting = async (ids) => { | |
| 67 | - try { | |
| 68 | - setIsLoding(true) | |
| 69 | - let response = await deleteApi('api/meeting/delete/', params.id) | |
| 70 | - if (response.status === 200) { | |
| 71 | - setDeleteMany(false) | |
| 72 | - navigate(-1) | |
| 73 | - } | |
| 74 | - } catch (error) { | |
| 75 | - console.log(error) | |
| 76 | - } | |
| 77 | - finally { | |
| 78 | - setIsLoding(false) | |
| 79 | - } | |
| 73 | + const handleDeleteMeeting = async (ids) => { | |
| 74 | + try { | |
| 75 | + setIsLoding(true); | |
| 76 | + let response = await deleteApi("api/meeting/delete/", params.id); | |
| 77 | + if (response.status === 200) { | |
| 78 | + setDeleteMany(false); | |
| 79 | + navigate(-1); | |
| 80 | + } | |
| 81 | + } catch (error) { | |
| 82 | + console.log(error); | |
| 83 | + } finally { | |
| 84 | + setIsLoding(false); | |
| 80 | 85 | } |
| 86 | + }; | |
| 81 | 87 | |
| 82 | - const [permission, contactAccess, leadAccess] = HasAccess(['Meetings', 'Contacts', 'Leads']) | |
| 88 | + const [permission, contactAccess, leadAccess] = HasAccess([ | |
| 89 | + "Meetings", | |
| 90 | + "Contacts", | |
| 91 | + "Leads", | |
| 92 | + ]); | |
| 83 | 93 | |
| 84 | - return ( | |
| 94 | + return ( | |
| 95 | + <> | |
| 96 | + {isLoding ? ( | |
| 97 | + <Flex justifyContent={"center"} alignItems={"center"} width="100%"> | |
| 98 | + <Spinner /> | |
| 99 | + </Flex> | |
| 100 | + ) : ( | |
| 85 | 101 | <> |
| 86 | - {isLoding ? | |
| 87 | - <Flex justifyContent={'center'} alignItems={'center'} width="100%" > | |
| 88 | - <Spinner /> | |
| 89 | - </Flex> : <> | |
| 90 | - | |
| 91 | - <Grid templateColumns="repeat(4, 1fr)" gap={3} id="reports"> | |
| 92 | - <GridItem colSpan={{ base: 4 }}> | |
| 93 | - <Heading size="lg" m={3}> | |
| 94 | - {data?.agenda || ""} | |
| 95 | - </Heading> | |
| 96 | - </GridItem> | |
| 97 | - <GridItem colSpan={{ base: 4 }}> | |
| 98 | - <Card> | |
| 99 | - <Grid gap={4}> | |
| 100 | - <GridItem colSpan={2}> | |
| 101 | - <Box> | |
| 102 | - <Flex justifyContent={"space-between"}> | |
| 103 | - <Heading size="md" mb={3}> | |
| 104 | - Meeting Details | |
| 105 | - </Heading> | |
| 106 | - <Box id="hide-btn"> | |
| 107 | - <Button leftIcon={<FaFilePdf />} size='sm' variant="brand" onClick={generatePDF} disabled={loading}> | |
| 108 | - {loading ? "Please Wait..." : "Print as PDF"} | |
| 109 | - </Button> | |
| 110 | - <Button leftIcon={<IoIosArrowBack />} size='sm' variant="brand" onClick={() => navigate(-1)} style={{ marginLeft: 10 }}> | |
| 111 | - Back | |
| 112 | - </Button> | |
| 113 | - </Box> | |
| 114 | - </Flex> | |
| 115 | - <HSeparator /> | |
| 116 | - </Box> | |
| 117 | - </GridItem> | |
| 118 | - <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 119 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Agenda </Text> | |
| 120 | - <Text>{data?.agenda ? data?.agenda : ' - '}</Text> | |
| 121 | - </GridItem> | |
| 122 | - <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 123 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Created By </Text> | |
| 124 | - <Text>{data?.createdByName ? data?.createdByName : ' - '}</Text> | |
| 125 | - </GridItem> | |
| 102 | + <Grid templateColumns="repeat(4, 1fr)" gap={3} id="reports"> | |
| 103 | + <GridItem colSpan={{ base: 4 }}> | |
| 104 | + <Heading size="lg" m={3}> | |
| 105 | + {data?.agenda || ""} | |
| 106 | + </Heading> | |
| 107 | + </GridItem> | |
| 108 | + <GridItem colSpan={{ base: 4 }}> | |
| 109 | + <Card> | |
| 110 | + <Grid gap={4}> | |
| 111 | + <GridItem colSpan={2}> | |
| 112 | + <Box> | |
| 113 | + <Flex justifyContent={"space-between"}> | |
| 114 | + <Heading size="md" mb={3}> | |
| 115 | + Meeting Details | |
| 116 | + </Heading> | |
| 117 | + <Box id="hide-btn"> | |
| 118 | + <Button | |
| 119 | + leftIcon={<FaFilePdf />} | |
| 120 | + size="sm" | |
| 121 | + variant="brand" | |
| 122 | + onClick={generatePDF} | |
| 123 | + disabled={loading} | |
| 124 | + > | |
| 125 | + {loading ? "Please Wait..." : "Print as PDF"} | |
| 126 | + </Button> | |
| 127 | + <Button | |
| 128 | + leftIcon={<IoIosArrowBack />} | |
| 129 | + size="sm" | |
| 130 | + variant="brand" | |
| 131 | + onClick={() => navigate(-1)} | |
| 132 | + style={{ marginLeft: 10 }} | |
| 133 | + > | |
| 134 | + Back | |
| 135 | + </Button> | |
| 136 | + </Box> | |
| 137 | + </Flex> | |
| 138 | + <HSeparator /> | |
| 139 | + </Box> | |
| 140 | + </GridItem> | |
| 141 | + <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 142 | + <Text | |
| 143 | + fontSize="sm" | |
| 144 | + fontWeight="bold" | |
| 145 | + color={"blackAlpha.900"} | |
| 146 | + > | |
| 147 | + {" "} | |
| 148 | + Agenda{" "} | |
| 149 | + </Text> | |
| 150 | + <Text>{data?.agenda ? data?.agenda : " - "}</Text> | |
| 151 | + </GridItem> | |
| 152 | + <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 153 | + <Text | |
| 154 | + fontSize="sm" | |
| 155 | + fontWeight="bold" | |
| 156 | + color={"blackAlpha.900"} | |
| 157 | + > | |
| 158 | + {" "} | |
| 159 | + Created By{" "} | |
| 160 | + </Text> | |
| 161 | + <Text> | |
| 162 | + {/* this was a typo, createdByName -> createByName to keep the same as others */} | |
| 163 | + {data?.createByName ? data?.createByName : " - "} | |
| 164 | + </Text> | |
| 165 | + </GridItem> | |
| 126 | 166 | |
| 127 | - <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 128 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> DateTime </Text> | |
| 129 | - <Text> {data?.dateTime ? moment(data?.dateTime).format('DD-MM-YYYY h:mma ') : ' - '} [{data?.dateTime ? moment(data?.dateTime).toNow() : ' - '}]</Text> | |
| 130 | - </GridItem> | |
| 131 | - <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 132 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Timestamp </Text> | |
| 133 | - <Text> {data?.timestamp ? moment(data?.timestamp).format('DD-MM-YYYY h:mma ') : ' - '} [{data?.timestamp ? moment(data?.timestamp).toNow() : ' - '}]</Text> | |
| 134 | - </GridItem> | |
| 135 | - <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 136 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Location </Text> | |
| 137 | - <Text>{data?.location ? data?.location : ' - '}</Text> | |
| 138 | - </GridItem> | |
| 139 | - <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 140 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Notes </Text> | |
| 141 | - <Text>{data?.notes ? data?.notes : ' - '}</Text> | |
| 142 | - </GridItem> | |
| 143 | - <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 144 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Attendes </Text> | |
| 145 | - {data?.related === 'Contact' && contactAccess?.view ? data?.attendes && data?.attendes.map((item) => { | |
| 146 | - return ( | |
| 147 | - <Link to={`/contactView/${item._id}`}> | |
| 148 | - <Text color='brand.600' sx={{ '&:hover': { color: 'blue.500', textDecoration: 'underline' } }}>{item.firstName + ' ' + item.lastName}</Text> | |
| 149 | - </Link> | |
| 150 | - ) | |
| 151 | - }) : data?.related === 'Lead' && leadAccess?.view ? data?.attendesLead && data?.attendesLead.map((item) => { | |
| 152 | - return ( | |
| 153 | - <Link to={`/leadView/${item._id}`}> | |
| 154 | - <Text color='brand.600' sx={{ '&:hover': { color: 'blue.500', textDecoration: 'underline' } }}>{item.leadName}</Text> | |
| 155 | - </Link> | |
| 156 | - ) | |
| 157 | - }) : data?.related === 'contact' ? data?.attendes && data?.attendes.map((item) => { | |
| 158 | - return ( | |
| 159 | - <Text color='blackAlpha.900' >{item.firstName + ' ' + item.lastName}</Text> | |
| 160 | - ) | |
| 161 | - }) : data?.related === 'lead' ? data?.attendesLead && data?.attendesLead.map((item) => { | |
| 162 | - return ( | |
| 163 | - <Text color='blackAlpha.900' >{item.leadName}</Text> | |
| 164 | - ) | |
| 165 | - }) : '-'} | |
| 166 | - </GridItem> | |
| 167 | - {/* <Grid templateColumns={'repeat(2, 1fr)'} gap={4} id="reports"> | |
| 167 | + <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 168 | + <Text | |
| 169 | + fontSize="sm" | |
| 170 | + fontWeight="bold" | |
| 171 | + color={"blackAlpha.900"} | |
| 172 | + > | |
| 173 | + {" "} | |
| 174 | + DateTime{" "} | |
| 175 | + </Text> | |
| 176 | + <Text> | |
| 177 | + {" "} | |
| 178 | + {data?.dateTime | |
| 179 | + ? moment(data?.dateTime).format("DD-MM-YYYY h:mma ") | |
| 180 | + : " - "}{" "} | |
| 181 | + [{data?.dateTime ? moment(data?.dateTime).toNow() : " - "} | |
| 182 | + ] | |
| 183 | + </Text> | |
| 184 | + </GridItem> | |
| 185 | + <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 186 | + <Text | |
| 187 | + fontSize="sm" | |
| 188 | + fontWeight="bold" | |
| 189 | + color={"blackAlpha.900"} | |
| 190 | + > | |
| 191 | + {" "} | |
| 192 | + Timestamp{" "} | |
| 193 | + </Text> | |
| 194 | + <Text> | |
| 195 | + {" "} | |
| 196 | + {data?.timestamp | |
| 197 | + ? moment(data?.timestamp).format("DD-MM-YYYY h:mma ") | |
| 198 | + : " - "}{" "} | |
| 199 | + [ | |
| 200 | + {data?.timestamp | |
| 201 | + ? moment(data?.timestamp).toNow() | |
| 202 | + : " - "} | |
| 203 | + ] | |
| 204 | + </Text> | |
| 205 | + </GridItem> | |
| 206 | + <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 207 | + <Text | |
| 208 | + fontSize="sm" | |
| 209 | + fontWeight="bold" | |
| 210 | + color={"blackAlpha.900"} | |
| 211 | + > | |
| 212 | + {" "} | |
| 213 | + Location{" "} | |
| 214 | + </Text> | |
| 215 | + <Text>{data?.location ? data?.location : " - "}</Text> | |
| 216 | + </GridItem> | |
| 217 | + <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 218 | + <Text | |
| 219 | + fontSize="sm" | |
| 220 | + fontWeight="bold" | |
| 221 | + color={"blackAlpha.900"} | |
| 222 | + > | |
| 223 | + {" "} | |
| 224 | + Notes{" "} | |
| 225 | + </Text> | |
| 226 | + <Text>{data?.notes ? data?.notes : " - "}</Text> | |
| 227 | + </GridItem> | |
| 228 | + <GridItem colSpan={{ base: 2, md: 1 }}> | |
| 229 | + <Text | |
| 230 | + fontSize="sm" | |
| 231 | + fontWeight="bold" | |
| 232 | + color={"blackAlpha.900"} | |
| 233 | + > | |
| 234 | + {" "} | |
| 235 | + Attendes{" "} | |
| 236 | + </Text> | |
| 237 | + {data?.related === "Contact" && contactAccess?.view | |
| 238 | + ? data?.attendes && | |
| 239 | + data?.attendes.map((item) => { | |
| 240 | + return ( | |
| 241 | + <Link to={`/contactView/${item._id}`}> | |
| 242 | + <Text | |
| 243 | + color="brand.600" | |
| 244 | + sx={{ | |
| 245 | + "&:hover": { | |
| 246 | + color: "blue.500", | |
| 247 | + textDecoration: "underline", | |
| 248 | + }, | |
| 249 | + }} | |
| 250 | + > | |
| 251 | + {item.firstName + " " + item.lastName} | |
| 252 | + </Text> | |
| 253 | + </Link> | |
| 254 | + ); | |
| 255 | + }) | |
| 256 | + : data?.related === "Lead" && leadAccess?.view | |
| 257 | + ? data?.attendesLead && | |
| 258 | + data?.attendesLead.map((item) => { | |
| 259 | + return ( | |
| 260 | + <Link to={`/leadView/${item._id}`}> | |
| 261 | + <Text | |
| 262 | + color="brand.600" | |
| 263 | + sx={{ | |
| 264 | + "&:hover": { | |
| 265 | + color: "blue.500", | |
| 266 | + textDecoration: "underline", | |
| 267 | + }, | |
| 268 | + }} | |
| 269 | + > | |
| 270 | + {item.leadName} | |
| 271 | + </Text> | |
| 272 | + </Link> | |
| 273 | + ); | |
| 274 | + }) | |
| 275 | + : data?.related === "contact" | |
| 276 | + ? data?.attendes && | |
| 277 | + data?.attendes.map((item) => { | |
| 278 | + return ( | |
| 279 | + <Text color="blackAlpha.900"> | |
| 280 | + {item.firstName + " " + item.lastName} | |
| 281 | + </Text> | |
| 282 | + ); | |
| 283 | + }) | |
| 284 | + : data?.related === "lead" | |
| 285 | + ? data?.attendesLead && | |
| 286 | + data?.attendesLead.map((item) => { | |
| 287 | + return ( | |
| 288 | + <Text color="blackAlpha.900">{item.leadName}</Text> | |
| 289 | + ); | |
| 290 | + }) | |
| 291 | + : "-"} | |
| 292 | + </GridItem> | |
| 293 | + {/* <Grid templateColumns={'repeat(2, 1fr)'} gap={4} id="reports"> | |
| 168 | 294 | |
| 169 | 295 | </Grid> */} |
| 170 | - </Grid> | |
| 171 | - </Card> | |
| 172 | - </GridItem> | |
| 173 | - | |
| 174 | - </Grid> | |
| 175 | - {(user.role === 'superAdmin' || (permission?.update || permission?.delete)) && <Card mt={3}> | |
| 176 | - <Grid templateColumns="repeat(6, 1fr)" gap={1}> | |
| 177 | - <GridItem colStart={6} > | |
| 178 | - <Flex justifyContent={"right"}> | |
| 179 | - {(user.role === 'superAdmin' || permission?.delete) ? <Button size='sm' style={{ background: 'red.800' }} onClick={() => setDeleteMany(true)} leftIcon={<DeleteIcon />} colorScheme="red" >Delete</Button> : ''} | |
| 180 | - </Flex> | |
| 181 | - </GridItem> | |
| 182 | - </Grid> | |
| 183 | - </Card> | |
| 184 | - } | |
| 185 | - | |
| 186 | - </>} | |
| 187 | - {/* Delete model */} | |
| 188 | - <CommonDeleteModel isOpen={deleteMany} onClose={() => setDeleteMany(false)} type='Meetings' handleDeleteData={handleDeleteMeeting} ids={params.id} /> | |
| 296 | + </Grid> | |
| 297 | + </Card> | |
| 298 | + </GridItem> | |
| 299 | + </Grid> | |
| 300 | + {(user.role === "superAdmin" || | |
| 301 | + permission?.update || | |
| 302 | + permission?.delete) && ( | |
| 303 | + <Card mt={3}> | |
| 304 | + <Grid templateColumns="repeat(6, 1fr)" gap={1}> | |
| 305 | + <GridItem colStart={6}> | |
| 306 | + <Flex justifyContent={"right"}> | |
| 307 | + {user.role === "superAdmin" || permission?.delete ? ( | |
| 308 | + <Button | |
| 309 | + size="sm" | |
| 310 | + style={{ background: "red.800" }} | |
| 311 | + onClick={() => setDeleteMany(true)} | |
| 312 | + leftIcon={<DeleteIcon />} | |
| 313 | + colorScheme="red" | |
| 314 | + > | |
| 315 | + Delete | |
| 316 | + </Button> | |
| 317 | + ) : ( | |
| 318 | + "" | |
| 319 | + )} | |
| 320 | + </Flex> | |
| 321 | + </GridItem> | |
| 322 | + </Grid> | |
| 323 | + </Card> | |
| 324 | + )} | |
| 189 | 325 | </> |
| 190 | - ); | |
| 326 | + )} | |
| 327 | + {/* Delete model */} | |
| 328 | + <CommonDeleteModel | |
| 329 | + isOpen={deleteMany} | |
| 330 | + onClose={() => setDeleteMany(false)} | |
| 331 | + type="Meetings" | |
| 332 | + handleDeleteData={handleDeleteMeeting} | |
| 333 | + ids={params.id} | |
| 334 | + /> | |
| 335 | + </> | |
| 336 | + ); | |
| 191 | 337 | }; |
| 192 | 338 | |
| 193 | 339 | export default View; |
+358-190Client/src/views/admin/meeting/components/Addmeeting.js
| @@ -1,206 +1,374 @@ | ||
| 1 | -import { Button, Flex, FormLabel, Grid, GridItem, IconButton, Input, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Radio, RadioGroup, Stack, Text, Textarea } from '@chakra-ui/react'; | |
| 2 | -import { CUIAutoComplete } from 'chakra-ui-autocomplete'; | |
| 3 | -import MultiContactModel from 'components/commonTableModel/MultiContactModel'; | |
| 4 | -import MultiLeadModel from 'components/commonTableModel/MultiLeadModel'; | |
| 5 | -import Spinner from 'components/spinner/Spinner'; | |
| 6 | -import dayjs from 'dayjs'; | |
| 7 | -import { useFormik } from 'formik'; | |
| 8 | -import { useEffect, useState } from 'react'; | |
| 9 | -import { LiaMousePointerSolid } from 'react-icons/lia'; | |
| 10 | -import { useSelector } from 'react-redux'; | |
| 11 | -import { toast } from 'react-toastify'; | |
| 12 | -import { MeetingSchema } from 'schema'; | |
| 13 | -import { getApi, postApi } from 'services/api'; | |
| 1 | +import { | |
| 2 | + Button, | |
| 3 | + Flex, | |
| 4 | + FormLabel, | |
| 5 | + Grid, | |
| 6 | + GridItem, | |
| 7 | + IconButton, | |
| 8 | + Input, | |
| 9 | + Modal, | |
| 10 | + ModalBody, | |
| 11 | + ModalCloseButton, | |
| 12 | + ModalContent, | |
| 13 | + ModalFooter, | |
| 14 | + ModalHeader, | |
| 15 | + ModalOverlay, | |
| 16 | + Radio, | |
| 17 | + RadioGroup, | |
| 18 | + Stack, | |
| 19 | + Text, | |
| 20 | + Textarea, | |
| 21 | +} from "@chakra-ui/react"; | |
| 22 | +import { CUIAutoComplete } from "chakra-ui-autocomplete"; | |
| 23 | +import MultiContactModel from "components/commonTableModel/MultiContactModel"; | |
| 24 | +import MultiLeadModel from "components/commonTableModel/MultiLeadModel"; | |
| 25 | +import Spinner from "components/spinner/Spinner"; | |
| 26 | +import dayjs from "dayjs"; | |
| 27 | +import { useFormik } from "formik"; | |
| 28 | +import { useEffect, useState } from "react"; | |
| 29 | +import { LiaMousePointerSolid } from "react-icons/lia"; | |
| 30 | +import { useSelector } from "react-redux"; | |
| 31 | +import { toast } from "react-toastify"; | |
| 32 | +import { MeetingSchema } from "schema"; | |
| 33 | +import { getApi, postApi } from "services/api"; | |
| 14 | 34 | |
| 15 | 35 | const AddMeeting = (props) => { |
| 16 | - const { onClose, isOpen, setAction, from, fetchData, view } = props | |
| 17 | - const [leaddata, setLeadData] = useState([]) | |
| 18 | - const [contactdata, setContactData] = useState([]) | |
| 19 | - const [isLoding, setIsLoding] = useState(false) | |
| 20 | - const [contactModelOpen, setContactModel] = useState(false); | |
| 21 | - const [leadModelOpen, setLeadModel] = useState(false); | |
| 22 | - const todayTime = new Date().toISOString().split('.')[0]; | |
| 23 | - const leadData = useSelector((state) => state?.leadData?.data); | |
| 36 | + const { onClose, isOpen, setAction, from, fetchData, view } = props; | |
| 37 | + const [leaddata, setLeadData] = useState([]); | |
| 38 | + const [contactdata, setContactData] = useState([]); | |
| 39 | + const [isLoding, setIsLoding] = useState(false); | |
| 40 | + const [contactModelOpen, setContactModel] = useState(false); | |
| 41 | + const [leadModelOpen, setLeadModel] = useState(false); | |
| 42 | + const todayTime = new Date().toISOString().split(".")[0]; | |
| 43 | + const leadData = useSelector((state) => state?.leadData?.data); | |
| 24 | 44 | |
| 45 | + const user = JSON.parse(localStorage.getItem("user")); | |
| 25 | 46 | |
| 26 | - const user = JSON.parse(localStorage.getItem('user')) | |
| 47 | + const contactList = useSelector((state) => state?.contactData?.data); | |
| 27 | 48 | |
| 28 | - const contactList = useSelector((state) => state?.contactData?.data) | |
| 49 | + const initialValues = { | |
| 50 | + agenda: "", | |
| 51 | + attendes: props.leadContect === "contactView" && props.id ? [props.id] : [], | |
| 52 | + attendesLead: | |
| 53 | + props.leadContect === "leadView" && props.id ? [props.id] : [], | |
| 54 | + location: "", | |
| 55 | + related: | |
| 56 | + props.leadContect === "contactView" | |
| 57 | + ? "Contact" | |
| 58 | + : props.leadContect === "leadView" | |
| 59 | + ? "Lead" | |
| 60 | + : "None", | |
| 61 | + dateTime: "", | |
| 62 | + notes: "", | |
| 63 | + createBy: user?._id, | |
| 64 | + }; | |
| 29 | 65 | |
| 66 | + const formik = useFormik({ | |
| 67 | + initialValues: initialValues, | |
| 68 | + validationSchema: MeetingSchema, | |
| 69 | + onSubmit: (values, { resetForm }) => { | |
| 70 | + AddData(); | |
| 71 | + }, | |
| 72 | + }); | |
| 30 | 73 | |
| 31 | - const initialValues = { | |
| 32 | - agenda: '', | |
| 33 | - attendes: props.leadContect === 'contactView' && props.id ? [props.id] : [], | |
| 34 | - attendesLead: props.leadContect === 'leadView' && props.id ? [props.id] : [], | |
| 35 | - location: '', | |
| 36 | - related: props.leadContect === 'contactView' ? 'Contact' : props.leadContect === 'leadView' ? 'Lead' : 'None', | |
| 37 | - dateTime: '', | |
| 38 | - notes: '', | |
| 39 | - createBy: user?._id, | |
| 40 | - } | |
| 41 | - | |
| 42 | - const formik = useFormik({ | |
| 43 | - initialValues: initialValues, | |
| 44 | - validationSchema: MeetingSchema, | |
| 45 | - onSubmit: (values, { resetForm }) => { | |
| 46 | - | |
| 47 | - }, | |
| 48 | - }); | |
| 49 | - const { errors, touched, values, handleBlur, handleChange, handleSubmit, setFieldValue } = formik | |
| 50 | - | |
| 51 | - const AddData = async () => { | |
| 74 | + const { | |
| 75 | + errors, | |
| 76 | + touched, | |
| 77 | + values, | |
| 78 | + handleBlur, | |
| 79 | + handleChange, | |
| 80 | + handleSubmit, | |
| 81 | + setFieldValue, | |
| 82 | + } = formik; | |
| 52 | 83 | |
| 53 | - }; | |
| 54 | - | |
| 55 | - const fetchAllData = async () => { | |
| 56 | - | |
| 84 | + const AddData = async () => { | |
| 85 | + try { | |
| 86 | + setIsLoding(true); | |
| 87 | + let response = await postApi("api/meeting/add", { | |
| 88 | + ...values, | |
| 89 | + }); | |
| 90 | + if (response.status === 200) { | |
| 91 | + props.onClose(); | |
| 92 | + formik.resetForm(); | |
| 93 | + props.setAction((pre) => !pre); | |
| 94 | + toast.success(`Added a meeting for ${values.dateTime} 😄`); | |
| 95 | + } | |
| 96 | + } catch (e) { | |
| 97 | + console.log(e); | |
| 98 | + toast.error("Failed to add meeting 😞"); | |
| 99 | + } finally { | |
| 100 | + setIsLoding(false); | |
| 57 | 101 | } |
| 102 | + }; | |
| 58 | 103 | |
| 59 | - useEffect(() => { | |
| 60 | - | |
| 61 | - }, [props.id, values.related]) | |
| 62 | - | |
| 63 | - const extractLabels = (selectedItems) => { | |
| 64 | - return selectedItems.map((item) => item._id); | |
| 65 | - }; | |
| 66 | - | |
| 67 | - const countriesWithEmailAsLabel = (values.related === "Contact" ? contactdata : leaddata)?.map((item) => ({ | |
| 68 | - ...item, | |
| 69 | - value: item._id, | |
| 70 | - label: values.related === "Contact" ? `${item.firstName} ${item.lastName}` : item.leadName, | |
| 71 | - })); | |
| 72 | - | |
| 73 | - return ( | |
| 74 | - <Modal onClose={onClose} isOpen={isOpen} isCentered> | |
| 75 | - <ModalOverlay /> | |
| 76 | - <ModalContent height={"580px"}> | |
| 77 | - <ModalHeader>Add Meeting </ModalHeader> | |
| 78 | - <ModalCloseButton /> | |
| 79 | - <ModalBody overflowY={"auto"} height={"400px"}> | |
| 80 | - {/* Contact Model */} | |
| 81 | - <MultiContactModel data={contactdata} isOpen={contactModelOpen} onClose={setContactModel} fieldName='attendes' setFieldValue={setFieldValue} /> | |
| 82 | - {/* Lead Model */} | |
| 83 | - <MultiLeadModel data={leaddata} isOpen={leadModelOpen} onClose={setLeadModel} fieldName='attendesLead' setFieldValue={setFieldValue} /> | |
| 84 | - | |
| 85 | - <Grid templateColumns="repeat(12, 1fr)" gap={3}> | |
| 86 | - <GridItem colSpan={{ base: 12 }}> | |
| 87 | - <FormLabel display='flex' ms='4px' fontSize='sm' fontWeight='500' mb='8px'> | |
| 88 | - Agenda<Text color={"red"}>*</Text> | |
| 89 | - </FormLabel> | |
| 90 | - <Input | |
| 91 | - fontSize='sm' | |
| 92 | - onChange={handleChange} onBlur={handleBlur} | |
| 93 | - value={values.agenda} | |
| 94 | - name="agenda" | |
| 95 | - placeholder='Agenda' | |
| 96 | - fontWeight='500' | |
| 97 | - borderColor={errors.agenda && touched.agenda ? "red.300" : null} | |
| 98 | - /> | |
| 99 | - <Text fontSize='sm' mb='10px' color={'red'}> {errors.agenda && touched.agenda && errors.agenda}</Text> | |
| 100 | - </GridItem> | |
| 101 | - <GridItem colSpan={{ base: 12 }} > | |
| 102 | - <FormLabel display='flex' ms='4px' fontSize='sm' fontWeight='500' mb='8px'> | |
| 103 | - Related To<Text color={"red"}>*</Text> | |
| 104 | - </FormLabel> | |
| 105 | - <RadioGroup onChange={(e) => setFieldValue('related', e)} value={values.related}> | |
| 106 | - <Stack direction='row'> | |
| 107 | - {props.leadContect === 'contactView' && <Radio value='Contact'>Contact</Radio>} | |
| 108 | - {props.leadContect === 'leadView' && <Radio value='Lead'>Lead</Radio>} | |
| 109 | - {!props.leadContect && <> <Radio value='Contact'>Contact</Radio><Radio value='Lead'>Lead</Radio></>} | |
| 110 | - </Stack> | |
| 111 | - </RadioGroup> | |
| 112 | - <Text mb='10px' color={'red'} fontSize='sm'> {errors.related && touched.related && errors.related}</Text> | |
| 113 | - </GridItem> | |
| 114 | - {(values.related === "Contact" ? (contactdata?.length ?? 0) > 0 : (leaddata?.length ?? 0) > 0) && values.related && | |
| 104 | + const fetchAllData = async () => {}; | |
| 115 | 105 | |
| 116 | - <GridItem colSpan={{ base: 12 }}> | |
| 117 | - <Flex alignItems={'end'} justifyContent={'space-between'} > | |
| 118 | - <Text w={'100%'} > | |
| 119 | - <CUIAutoComplete | |
| 120 | - label={`Choose Preferred Attendes ${values.related === "Contact" ? "Contact" : values.related === "Lead" && "Lead"}`} | |
| 121 | - placeholder="Type a Name" | |
| 122 | - name="attendes" | |
| 123 | - items={countriesWithEmailAsLabel} | |
| 124 | - className='custom-autoComplete' | |
| 125 | - selectedItems={countriesWithEmailAsLabel?.filter((item) => values.related === "Contact" ? values?.attendes.includes(item._id) : values.related === "Lead" && values?.attendesLead.includes(item._id))} | |
| 126 | - onSelectedItemsChange={(changes) => { | |
| 127 | - const selectedLabels = extractLabels(changes.selectedItems); | |
| 128 | - values.related === "Contact" ? setFieldValue('attendes', selectedLabels) : values.related === "Lead" && setFieldValue('attendesLead', selectedLabels) | |
| 129 | - }} | |
| 130 | - /> | |
| 131 | - </Text> | |
| 132 | - <IconButton mb={6} onClick={() => values.related === "Contact" ? setContactModel(true) : values.related === "Lead" && setLeadModel(true)} fontSize='25px' icon={<LiaMousePointerSolid />} /> | |
| 133 | - </Flex> | |
| 134 | - <Text color={'red'}> {errors.attendes && touched.attendes && errors.attendes}</Text> | |
| 135 | - </GridItem> | |
| 136 | - } | |
| 137 | - <GridItem colSpan={{ base: 12 }}> | |
| 138 | - <FormLabel display='flex' ms='4px' fontSize='sm' fontWeight='500' mb='8px'> | |
| 139 | - Location | |
| 140 | - </FormLabel> | |
| 141 | - <Input | |
| 142 | - fontSize='sm' | |
| 143 | - onChange={handleChange} onBlur={handleBlur} | |
| 144 | - value={values.location} | |
| 145 | - name="location" | |
| 146 | - placeholder='Location' | |
| 147 | - fontWeight='500' | |
| 148 | - borderColor={errors.location && touched.location ? "red.300" : null} | |
| 149 | - /> | |
| 150 | - <Text mb='10px' color={'red'} fontSize='sm'> {errors.location && touched.location && errors.location}</Text> | |
| 151 | - </GridItem> | |
| 152 | - <GridItem colSpan={{ base: 12 }}> | |
| 153 | - <FormLabel display='flex' ms='4px' fontSize='sm' fontWeight='500' mb='8px'> | |
| 154 | - Date Time<Text color={"red"}>*</Text> | |
| 155 | - </FormLabel> | |
| 156 | - <Input | |
| 157 | - fontSize='sm' | |
| 158 | - type='datetime-local' | |
| 159 | - onChange={handleChange} onBlur={handleBlur} | |
| 160 | - min={dayjs(todayTime).format('YYYY-MM-DD HH:mm')} | |
| 161 | - value={values.dateTime} | |
| 162 | - name="dateTime" | |
| 163 | - placeholder='Date Time' | |
| 164 | - fontWeight='500' | |
| 165 | - borderColor={errors.dateTime && touched.dateTime ? "red.300" : null} | |
| 166 | - /> | |
| 167 | - <Text fontSize='sm' mb='10px' color={'red'}> {errors.dateTime && touched.dateTime && errors.dateTime}</Text> | |
| 168 | - </GridItem> | |
| 169 | - <GridItem colSpan={{ base: 12 }}> | |
| 170 | - <FormLabel display='flex' ms='4px' fontSize='sm' fontWeight='500' mb='8px'> | |
| 171 | - Notes | |
| 172 | - </FormLabel> | |
| 173 | - <Textarea | |
| 174 | - resize={'none'} | |
| 175 | - fontSize='sm' | |
| 176 | - placeholder='Notes' | |
| 177 | - onChange={handleChange} onBlur={handleBlur} | |
| 178 | - value={values.notes} | |
| 179 | - name="notes" | |
| 180 | - fontWeight='500' | |
| 181 | - borderColor={errors.notes && touched.notes ? "red.300" : null} | |
| 182 | - /> | |
| 183 | - <Text mb='10px' color={'red'}> {errors.notes && touched.notes && errors.notes}</Text> | |
| 184 | - </GridItem> | |
| 106 | + useEffect(() => {}, [props.id, values.related]); | |
| 185 | 107 | |
| 186 | - </Grid> | |
| 108 | + const extractLabels = (selectedItems) => { | |
| 109 | + return selectedItems.map((item) => item._id); | |
| 110 | + }; | |
| 187 | 111 | |
| 112 | + const countriesWithEmailAsLabel = ( | |
| 113 | + values.related === "Contact" ? contactdata : leaddata | |
| 114 | + )?.map((item) => ({ | |
| 115 | + ...item, | |
| 116 | + value: item._id, | |
| 117 | + label: | |
| 118 | + values.related === "Contact" | |
| 119 | + ? `${item.firstName} ${item.lastName}` | |
| 120 | + : item.leadName, | |
| 121 | + })); | |
| 188 | 122 | |
| 189 | - </ModalBody> | |
| 190 | - <ModalFooter> | |
| 191 | - <Button size="sm" variant='brand' me={2} disabled={isLoding ? true : false} onClick={handleSubmit}>{isLoding ? <Spinner /> : 'Save'}</Button> | |
| 192 | - <Button sx={{ | |
| 193 | - textTransform: "capitalize", | |
| 194 | - }} variant="outline" | |
| 195 | - colorScheme="red" size="sm" onClick={() => { | |
| 196 | - formik.resetForm() | |
| 197 | - onClose() | |
| 198 | - }}>Close</Button> | |
| 199 | - </ModalFooter> | |
| 200 | - </ModalContent> | |
| 201 | - </Modal> | |
| 202 | - ) | |
| 203 | -} | |
| 123 | + return ( | |
| 124 | + <Modal onClose={onClose} isOpen={isOpen} isCentered> | |
| 125 | + <ModalOverlay /> | |
| 126 | + <ModalContent height={"580px"}> | |
| 127 | + <ModalHeader>Add Meeting </ModalHeader> | |
| 128 | + <ModalCloseButton /> | |
| 129 | + <ModalBody overflowY={"auto"} height={"400px"}> | |
| 130 | + {/* Contact Model */} | |
| 131 | + <MultiContactModel | |
| 132 | + data={contactdata} | |
| 133 | + isOpen={contactModelOpen} | |
| 134 | + onClose={setContactModel} | |
| 135 | + fieldName="attendes" | |
| 136 | + setFieldValue={setFieldValue} | |
| 137 | + /> | |
| 138 | + {/* Lead Model */} | |
| 139 | + <MultiLeadModel | |
| 140 | + data={leaddata} | |
| 141 | + isOpen={leadModelOpen} | |
| 142 | + onClose={setLeadModel} | |
| 143 | + fieldName="attendesLead" | |
| 144 | + setFieldValue={setFieldValue} | |
| 145 | + /> | |
| 204 | 146 | |
| 205 | -export default AddMeeting | |
| 147 | + <Grid templateColumns="repeat(12, 1fr)" gap={3}> | |
| 148 | + <GridItem colSpan={{ base: 12 }}> | |
| 149 | + <FormLabel | |
| 150 | + display="flex" | |
| 151 | + ms="4px" | |
| 152 | + fontSize="sm" | |
| 153 | + fontWeight="500" | |
| 154 | + mb="8px" | |
| 155 | + > | |
| 156 | + Agenda<Text color={"red"}>*</Text> | |
| 157 | + </FormLabel> | |
| 158 | + <Input | |
| 159 | + fontSize="sm" | |
| 160 | + onChange={handleChange} | |
| 161 | + onBlur={handleBlur} | |
| 162 | + value={values.agenda} | |
| 163 | + name="agenda" | |
| 164 | + placeholder="Agenda" | |
| 165 | + fontWeight="500" | |
| 166 | + borderColor={errors.agenda && touched.agenda ? "red.300" : null} | |
| 167 | + /> | |
| 168 | + <Text fontSize="sm" mb="10px" color={"red"}> | |
| 169 | + {" "} | |
| 170 | + {errors.agenda && touched.agenda && errors.agenda} | |
| 171 | + </Text> | |
| 172 | + </GridItem> | |
| 173 | + <GridItem colSpan={{ base: 12 }}> | |
| 174 | + <FormLabel | |
| 175 | + display="flex" | |
| 176 | + ms="4px" | |
| 177 | + fontSize="sm" | |
| 178 | + fontWeight="500" | |
| 179 | + mb="8px" | |
| 180 | + > | |
| 181 | + Related To<Text color={"red"}>*</Text> | |
| 182 | + </FormLabel> | |
| 183 | + <RadioGroup | |
| 184 | + onChange={(e) => setFieldValue("related", e)} | |
| 185 | + value={values.related} | |
| 186 | + > | |
| 187 | + <Stack direction="row"> | |
| 188 | + {props.leadContect === "contactView" && ( | |
| 189 | + <Radio value="Contact">Contact</Radio> | |
| 190 | + )} | |
| 191 | + {props.leadContect === "leadView" && ( | |
| 192 | + <Radio value="Lead">Lead</Radio> | |
| 193 | + )} | |
| 194 | + {!props.leadContect && ( | |
| 195 | + <> | |
| 196 | + {" "} | |
| 197 | + <Radio value="Contact">Contact</Radio> | |
| 198 | + <Radio value="Lead">Lead</Radio> | |
| 199 | + </> | |
| 200 | + )} | |
| 201 | + </Stack> | |
| 202 | + </RadioGroup> | |
| 203 | + <Text mb="10px" color={"red"} fontSize="sm"> | |
| 204 | + {" "} | |
| 205 | + {errors.related && touched.related && errors.related} | |
| 206 | + </Text> | |
| 207 | + </GridItem> | |
| 208 | + {(values.related === "Contact" | |
| 209 | + ? (contactdata?.length ?? 0) > 0 | |
| 210 | + : (leaddata?.length ?? 0) > 0) && | |
| 211 | + values.related && ( | |
| 212 | + <GridItem colSpan={{ base: 12 }}> | |
| 213 | + <Flex alignItems={"end"} justifyContent={"space-between"}> | |
| 214 | + <Text w={"100%"}> | |
| 215 | + <CUIAutoComplete | |
| 216 | + label={`Choose Preferred Attendes ${ | |
| 217 | + values.related === "Contact" | |
| 218 | + ? "Contact" | |
| 219 | + : values.related === "Lead" && "Lead" | |
| 220 | + }`} | |
| 221 | + placeholder="Type a Name" | |
| 222 | + name="attendes" | |
| 223 | + items={countriesWithEmailAsLabel} | |
| 224 | + className="custom-autoComplete" | |
| 225 | + selectedItems={countriesWithEmailAsLabel?.filter( | |
| 226 | + (item) => | |
| 227 | + values.related === "Contact" | |
| 228 | + ? values?.attendes.includes(item._id) | |
| 229 | + : values.related === "Lead" && | |
| 230 | + values?.attendesLead.includes(item._id) | |
| 231 | + )} | |
| 232 | + onSelectedItemsChange={(changes) => { | |
| 233 | + const selectedLabels = extractLabels( | |
| 234 | + changes.selectedItems | |
| 235 | + ); | |
| 236 | + values.related === "Contact" | |
| 237 | + ? setFieldValue("attendes", selectedLabels) | |
| 238 | + : values.related === "Lead" && | |
| 239 | + setFieldValue("attendesLead", selectedLabels); | |
| 240 | + }} | |
| 241 | + /> | |
| 242 | + </Text> | |
| 243 | + <IconButton | |
| 244 | + mb={6} | |
| 245 | + onClick={() => | |
| 246 | + values.related === "Contact" | |
| 247 | + ? setContactModel(true) | |
| 248 | + : values.related === "Lead" && setLeadModel(true) | |
| 249 | + } | |
| 250 | + fontSize="25px" | |
| 251 | + icon={<LiaMousePointerSolid />} | |
| 252 | + /> | |
| 253 | + </Flex> | |
| 254 | + <Text color={"red"}> | |
| 255 | + {" "} | |
| 256 | + {errors.attendes && touched.attendes && errors.attendes} | |
| 257 | + </Text> | |
| 258 | + </GridItem> | |
| 259 | + )} | |
| 260 | + <GridItem colSpan={{ base: 12 }}> | |
| 261 | + <FormLabel | |
| 262 | + display="flex" | |
| 263 | + ms="4px" | |
| 264 | + fontSize="sm" | |
| 265 | + fontWeight="500" | |
| 266 | + mb="8px" | |
| 267 | + > | |
| 268 | + Location | |
| 269 | + </FormLabel> | |
| 270 | + <Input | |
| 271 | + fontSize="sm" | |
| 272 | + onChange={handleChange} | |
| 273 | + onBlur={handleBlur} | |
| 274 | + value={values.location} | |
| 275 | + name="location" | |
| 276 | + placeholder="Location" | |
| 277 | + fontWeight="500" | |
| 278 | + borderColor={ | |
| 279 | + errors.location && touched.location ? "red.300" : null | |
| 280 | + } | |
| 281 | + /> | |
| 282 | + <Text mb="10px" color={"red"} fontSize="sm"> | |
| 283 | + {" "} | |
| 284 | + {errors.location && touched.location && errors.location} | |
| 285 | + </Text> | |
| 286 | + </GridItem> | |
| 287 | + <GridItem colSpan={{ base: 12 }}> | |
| 288 | + <FormLabel | |
| 289 | + display="flex" | |
| 290 | + ms="4px" | |
| 291 | + fontSize="sm" | |
| 292 | + fontWeight="500" | |
| 293 | + mb="8px" | |
| 294 | + > | |
| 295 | + Date Time<Text color={"red"}>*</Text> | |
| 296 | + </FormLabel> | |
| 297 | + <Input | |
| 298 | + fontSize="sm" | |
| 299 | + type="datetime-local" | |
| 300 | + onChange={handleChange} | |
| 301 | + onBlur={handleBlur} | |
| 302 | + min={dayjs(todayTime).format("YYYY-MM-DD HH:mm")} | |
| 303 | + value={values.dateTime} | |
| 304 | + name="dateTime" | |
| 305 | + placeholder="Date Time" | |
| 306 | + fontWeight="500" | |
| 307 | + borderColor={ | |
| 308 | + errors.dateTime && touched.dateTime ? "red.300" : null | |
| 309 | + } | |
| 310 | + /> | |
| 311 | + <Text fontSize="sm" mb="10px" color={"red"}> | |
| 312 | + {" "} | |
| 313 | + {errors.dateTime && touched.dateTime && errors.dateTime} | |
| 314 | + </Text> | |
| 315 | + </GridItem> | |
| 316 | + <GridItem colSpan={{ base: 12 }}> | |
| 317 | + <FormLabel | |
| 318 | + display="flex" | |
| 319 | + ms="4px" | |
| 320 | + fontSize="sm" | |
| 321 | + fontWeight="500" | |
| 322 | + mb="8px" | |
| 323 | + > | |
| 324 | + Notes | |
| 325 | + </FormLabel> | |
| 326 | + <Textarea | |
| 327 | + resize={"none"} | |
| 328 | + fontSize="sm" | |
| 329 | + placeholder="Notes" | |
| 330 | + onChange={handleChange} | |
| 331 | + onBlur={handleBlur} | |
| 332 | + value={values.notes} | |
| 333 | + name="notes" | |
| 334 | + fontWeight="500" | |
| 335 | + borderColor={errors.notes && touched.notes ? "red.300" : null} | |
| 336 | + /> | |
| 337 | + <Text mb="10px" color={"red"}> | |
| 338 | + {" "} | |
| 339 | + {errors.notes && touched.notes && errors.notes} | |
| 340 | + </Text> | |
| 341 | + </GridItem> | |
| 342 | + </Grid> | |
| 343 | + </ModalBody> | |
| 344 | + <ModalFooter> | |
| 345 | + <Button | |
| 346 | + size="sm" | |
| 347 | + variant="brand" | |
| 348 | + me={2} | |
| 349 | + disabled={isLoding ? true : false} | |
| 350 | + onClick={handleSubmit} | |
| 351 | + > | |
| 352 | + {isLoding ? <Spinner /> : "Save"} | |
| 353 | + </Button> | |
| 354 | + <Button | |
| 355 | + sx={{ | |
| 356 | + textTransform: "capitalize", | |
| 357 | + }} | |
| 358 | + variant="outline" | |
| 359 | + colorScheme="red" | |
| 360 | + size="sm" | |
| 361 | + onClick={() => { | |
| 362 | + formik.resetForm(); | |
| 363 | + onClose(); | |
| 364 | + }} | |
| 365 | + > | |
| 366 | + Close | |
| 367 | + </Button> | |
| 368 | + </ModalFooter> | |
| 369 | + </ModalContent> | |
| 370 | + </Modal> | |
| 371 | + ); | |
| 372 | +}; | |
| 206 | 373 | |
| 374 | +export default AddMeeting; |
+246-113Client/src/views/admin/meeting/meetingView.js
| @@ -1,126 +1,259 @@ | ||
| 1 | -import { CloseIcon, DeleteIcon, EditIcon, ViewIcon } from '@chakra-ui/icons' | |
| 2 | -import { DrawerFooter, Flex, Grid, GridItem, IconButton, Modal, ModalBody, ModalContent, ModalHeader, ModalOverlay, Text } from '@chakra-ui/react' | |
| 3 | -import Spinner from "components/spinner/Spinner" | |
| 4 | -import moment from 'moment' | |
| 5 | -import { useEffect, useState } from 'react' | |
| 6 | -import { BiLink } from 'react-icons/bi' | |
| 7 | -import { Link } from 'react-router-dom' | |
| 8 | -import { getApi } from 'services/api' | |
| 1 | +import { CloseIcon, DeleteIcon, EditIcon, ViewIcon } from "@chakra-ui/icons"; | |
| 2 | +import { | |
| 3 | + DrawerFooter, | |
| 4 | + Flex, | |
| 5 | + Grid, | |
| 6 | + GridItem, | |
| 7 | + IconButton, | |
| 8 | + Modal, | |
| 9 | + ModalBody, | |
| 10 | + ModalContent, | |
| 11 | + ModalHeader, | |
| 12 | + ModalOverlay, | |
| 13 | + Text, | |
| 14 | +} from "@chakra-ui/react"; | |
| 15 | +import Spinner from "components/spinner/Spinner"; | |
| 16 | +import moment from "moment"; | |
| 17 | +import { useEffect, useState } from "react"; | |
| 18 | +import { BiLink } from "react-icons/bi"; | |
| 19 | +import { Link } from "react-router-dom"; | |
| 20 | +import { getApi } from "services/api"; | |
| 9 | 21 | // import DeleteTask from './components/deleteTask' |
| 10 | -import { useNavigate } from 'react-router-dom'; | |
| 22 | +import { useNavigate } from "react-router-dom"; | |
| 11 | 23 | import { HasAccess } from "../../../redux/accessUtils"; |
| 12 | 24 | |
| 13 | 25 | const MeetingView = (props) => { |
| 14 | - const { onClose, isOpen, info, fetchData, setAction, action, access } = props | |
| 15 | - const [data, setData] = useState(); | |
| 16 | - const [edit, setEdit] = useState(false); | |
| 17 | - const [deleteModel, setDelete] = useState(false); | |
| 18 | - const user = JSON.parse(localStorage.getItem("user")) | |
| 19 | - const [isLoding, setIsLoding] = useState(false) | |
| 20 | - const navigate = useNavigate() | |
| 26 | + const { onClose, isOpen, info, fetchData, setAction, action, access } = props; | |
| 27 | + const [data, setData] = useState(); | |
| 28 | + const [edit, setEdit] = useState(false); | |
| 29 | + const [deleteModel, setDelete] = useState(false); | |
| 30 | + const user = JSON.parse(localStorage.getItem("user")); | |
| 31 | + const [isLoding, setIsLoding] = useState(false); | |
| 32 | + const navigate = useNavigate(); | |
| 21 | 33 | |
| 22 | - const fetchViewData = async () => { | |
| 23 | - if (info) { | |
| 24 | - setIsLoding(true) | |
| 25 | - let result = await getApi('api/meeting/view/', info?.event ? info?.event?.id : info); | |
| 26 | - setData(result?.data); | |
| 27 | - setIsLoding(false) | |
| 28 | - } | |
| 34 | + const fetchViewData = async () => { | |
| 35 | + if (info) { | |
| 36 | + setIsLoding(true); | |
| 37 | + let result = await getApi( | |
| 38 | + "api/meeting/view/", | |
| 39 | + info?.event ? info?.event?.id : info | |
| 40 | + ); | |
| 41 | + setData(result?.data); | |
| 42 | + setIsLoding(false); | |
| 29 | 43 | } |
| 44 | + }; | |
| 30 | 45 | |
| 31 | - useEffect(() => { | |
| 32 | - fetchViewData() | |
| 33 | - }, [action, info]) | |
| 46 | + useEffect(() => { | |
| 47 | + fetchViewData(); | |
| 48 | + }, [action, info]); | |
| 34 | 49 | |
| 35 | - const [contactAccess, leadAccess] = HasAccess(['Contacts', 'Leads']) | |
| 50 | + const [contactAccess, leadAccess] = HasAccess(["Contacts", "Leads"]); | |
| 36 | 51 | |
| 37 | - const handleViewOpen = () => { | |
| 38 | - if (info?.event) { | |
| 39 | - navigate(`/view/${info?.event?.id}`) | |
| 40 | - } | |
| 41 | - else { | |
| 42 | - navigate(`/view/${info}`) | |
| 43 | - } | |
| 52 | + const handleViewOpen = () => { | |
| 53 | + if (info?.event) { | |
| 54 | + navigate(`/view/${info?.event?.id}`); | |
| 55 | + } else { | |
| 56 | + navigate(`/view/${info}`); | |
| 44 | 57 | } |
| 45 | - return ( | |
| 46 | - <Modal isOpen={isOpen} size={'md'} isCentered> | |
| 47 | - <ModalOverlay /> | |
| 48 | - <ModalContent height={"70%"}> | |
| 49 | - <ModalHeader justifyContent='space-between' display='flex' > | |
| 50 | - Meeting | |
| 51 | - <IconButton onClick={() => onClose(false)} icon={<CloseIcon />} /> | |
| 52 | - </ModalHeader> | |
| 53 | - {isLoding ? | |
| 54 | - <Flex justifyContent={'center'} alignItems={'center'} mb={30} width="100%" > | |
| 55 | - <Spinner /> | |
| 56 | - </Flex> : <> | |
| 58 | + }; | |
| 59 | + return ( | |
| 60 | + <Modal isOpen={isOpen} size={"md"} isCentered> | |
| 61 | + <ModalOverlay /> | |
| 62 | + <ModalContent height={"70%"}> | |
| 63 | + <ModalHeader justifyContent="space-between" display="flex"> | |
| 64 | + Meeting | |
| 65 | + <IconButton onClick={() => onClose(false)} icon={<CloseIcon />} /> | |
| 66 | + </ModalHeader> | |
| 67 | + {isLoding ? ( | |
| 68 | + <Flex | |
| 69 | + justifyContent={"center"} | |
| 70 | + alignItems={"center"} | |
| 71 | + mb={30} | |
| 72 | + width="100%" | |
| 73 | + > | |
| 74 | + <Spinner /> | |
| 75 | + </Flex> | |
| 76 | + ) : ( | |
| 77 | + <> | |
| 78 | + <ModalBody overflowY={"auto"}> | |
| 79 | + <Grid templateColumns="repeat(12, 1fr)" gap={3}> | |
| 80 | + <GridItem colSpan={{ base: 12, md: 6 }}> | |
| 81 | + <Text | |
| 82 | + fontSize="sm" | |
| 83 | + fontWeight="bold" | |
| 84 | + color={"blackAlpha.900"} | |
| 85 | + > | |
| 86 | + {" "} | |
| 87 | + Agenda{" "} | |
| 88 | + </Text> | |
| 89 | + <Text>{data?.agenda ? data?.agenda : " - "}</Text> | |
| 90 | + </GridItem> | |
| 91 | + <GridItem colSpan={{ base: 12, md: 6 }}> | |
| 92 | + <Text | |
| 93 | + fontSize="sm" | |
| 94 | + fontWeight="bold" | |
| 95 | + color={"blackAlpha.900"} | |
| 96 | + > | |
| 97 | + {" "} | |
| 98 | + Date&Time{" "} | |
| 99 | + </Text> | |
| 100 | + <Text> | |
| 101 | + {data?.dateTime | |
| 102 | + ? moment(data?.dateTime).format("lll ") | |
| 103 | + : " - "} | |
| 104 | + </Text> | |
| 105 | + </GridItem> | |
| 106 | + <GridItem colSpan={{ base: 12, md: 6 }}> | |
| 107 | + <Text | |
| 108 | + fontSize="sm" | |
| 109 | + fontWeight="bold" | |
| 110 | + color={"blackAlpha.900"} | |
| 111 | + > | |
| 112 | + {" "} | |
| 113 | + Created By{" "} | |
| 114 | + </Text> | |
| 115 | + <Text>{data?.createdByName ? data?.createdByName : "-"}</Text> | |
| 116 | + </GridItem> | |
| 117 | + <GridItem colSpan={{ base: 12, md: 6 }}> | |
| 118 | + <Text | |
| 119 | + fontSize="sm" | |
| 120 | + fontWeight="bold" | |
| 121 | + color={"blackAlpha.900"} | |
| 122 | + > | |
| 123 | + {" "} | |
| 124 | + Related{" "} | |
| 125 | + </Text> | |
| 126 | + <Text>{data?.related ? data?.related : "-"}</Text> | |
| 127 | + </GridItem> | |
| 128 | + <GridItem colSpan={{ base: 12, md: 6 }}> | |
| 129 | + <Text | |
| 130 | + fontSize="sm" | |
| 131 | + fontWeight="bold" | |
| 132 | + color={"blackAlpha.900"} | |
| 133 | + > | |
| 134 | + {" "} | |
| 135 | + Location{" "} | |
| 136 | + </Text> | |
| 137 | + <Text>{data?.location ? data?.location : "-"}</Text> | |
| 138 | + </GridItem> | |
| 139 | + <GridItem colSpan={{ base: 12, md: 6 }}> | |
| 140 | + <Text | |
| 141 | + fontSize="sm" | |
| 142 | + fontWeight="bold" | |
| 143 | + color={"blackAlpha.900"} | |
| 144 | + > | |
| 145 | + {" "} | |
| 146 | + Notes{" "} | |
| 147 | + </Text> | |
| 148 | + <Text>{data?.notes ? data?.notes : "-"}</Text> | |
| 149 | + </GridItem> | |
| 150 | + <GridItem colSpan={{ base: 12, md: 6 }}> | |
| 151 | + <Text | |
| 152 | + fontSize="sm" | |
| 153 | + fontWeight="bold" | |
| 154 | + color={"blackAlpha.900"} | |
| 155 | + > | |
| 156 | + {" "} | |
| 157 | + attendes{" "} | |
| 158 | + </Text> | |
| 159 | + {data?.related === "Contact" && contactAccess?.view | |
| 160 | + ? data?.attendes && | |
| 161 | + data?.attendes.map((item) => { | |
| 162 | + return ( | |
| 163 | + <Link to={`/contactView/${item._id}`}> | |
| 164 | + <Text | |
| 165 | + color="brand.600" | |
| 166 | + sx={{ | |
| 167 | + "&:hover": { | |
| 168 | + color: "blue.500", | |
| 169 | + textDecoration: "underline", | |
| 170 | + }, | |
| 171 | + }} | |
| 172 | + > | |
| 173 | + {item.firstName + " " + item.lastName} | |
| 174 | + </Text> | |
| 175 | + </Link> | |
| 176 | + ); | |
| 177 | + }) | |
| 178 | + : data?.related === "Lead" && leadAccess?.view | |
| 179 | + ? data?.attendesLead && | |
| 180 | + data?.attendesLead.map((item) => { | |
| 181 | + return ( | |
| 182 | + <Link to={`/leadView/${item._id}`}> | |
| 183 | + <Text | |
| 184 | + color="brand.600" | |
| 185 | + sx={{ | |
| 186 | + "&:hover": { | |
| 187 | + color: "blue.500", | |
| 188 | + textDecoration: "underline", | |
| 189 | + }, | |
| 190 | + }} | |
| 191 | + > | |
| 192 | + {item.leadName} | |
| 193 | + </Text> | |
| 194 | + </Link> | |
| 195 | + ); | |
| 196 | + }) | |
| 197 | + : data?.related === "Contact" | |
| 198 | + ? data?.attendes && | |
| 199 | + data?.attendes.map((item) => { | |
| 200 | + return ( | |
| 201 | + <Text color="blackAlpha.900"> | |
| 202 | + {item.firstName + " " + item.lastName} | |
| 203 | + </Text> | |
| 204 | + ); | |
| 205 | + }) | |
| 206 | + : data?.related === "Lead" | |
| 207 | + ? data?.attendesLead && | |
| 208 | + data?.attendesLead.map((item) => { | |
| 209 | + return ( | |
| 210 | + <Text color="blackAlpha.900">{item.leadName}</Text> | |
| 211 | + ); | |
| 212 | + }) | |
| 213 | + : "-"} | |
| 214 | + </GridItem> | |
| 215 | + </Grid> | |
| 216 | + </ModalBody> | |
| 217 | + <DrawerFooter> | |
| 218 | + {access?.view && ( | |
| 219 | + <IconButton | |
| 220 | + variant="outline" | |
| 221 | + colorScheme={"green"} | |
| 222 | + onClick={() => handleViewOpen()} | |
| 223 | + borderRadius="10px" | |
| 224 | + size="md" | |
| 225 | + icon={<ViewIcon />} | |
| 226 | + /> | |
| 227 | + )} | |
| 228 | + {access?.update && ( | |
| 229 | + <IconButton | |
| 230 | + variant="outline" | |
| 231 | + onClick={() => setEdit(true)} | |
| 232 | + ml={3} | |
| 233 | + borderRadius="10px" | |
| 234 | + size="md" | |
| 235 | + icon={<EditIcon />} | |
| 236 | + /> | |
| 237 | + )} | |
| 238 | + {access?.delete && ( | |
| 239 | + <IconButton | |
| 240 | + colorScheme="red" | |
| 241 | + onClick={() => setDelete(true)} | |
| 242 | + ml={3} | |
| 243 | + borderRadius="10px" | |
| 244 | + size="md" | |
| 245 | + icon={<DeleteIcon />} | |
| 246 | + /> | |
| 247 | + )} | |
| 57 | 248 | |
| 58 | - <ModalBody overflowY={"auto"}> | |
| 59 | - <Grid templateColumns="repeat(12, 1fr)" gap={3} > | |
| 60 | - <GridItem colSpan={{ base: 12, md: 6 }} > | |
| 61 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Agenda </Text> | |
| 62 | - <Text>{data?.agenda ? data?.agenda : ' - '}</Text> | |
| 63 | - </GridItem> | |
| 64 | - <GridItem colSpan={{ base: 12, md: 6 }} > | |
| 65 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Date&Time </Text> | |
| 66 | - <Text>{data?.dateTime ? moment(data?.dateTime).format('lll ') : ' - '}</Text> | |
| 67 | - </GridItem> | |
| 68 | - <GridItem colSpan={{ base: 12, md: 6 }} > | |
| 69 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Created By </Text> | |
| 70 | - <Text>{data?.createdByName ? data?.createdByName : '-'}</Text> | |
| 71 | - </GridItem> | |
| 72 | - <GridItem colSpan={{ base: 12, md: 6 }} > | |
| 73 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Related </Text> | |
| 74 | - <Text>{data?.related ? data?.related : '-'}</Text> | |
| 75 | - </GridItem> | |
| 76 | - <GridItem colSpan={{ base: 12, md: 6 }} > | |
| 77 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Location </Text> | |
| 78 | - <Text>{data?.location ? data?.location : '-'}</Text> | |
| 79 | - </GridItem> | |
| 80 | - <GridItem colSpan={{ base: 12, md: 6 }} > | |
| 81 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> Notes </Text> | |
| 82 | - <Text>{data?.notes ? data?.notes : '-'}</Text> | |
| 83 | - </GridItem> | |
| 84 | - <GridItem colSpan={{ base: 12, md: 6 }} > | |
| 85 | - <Text fontSize="sm" fontWeight="bold" color={'blackAlpha.900'}> attendes </Text> | |
| 86 | - {data?.related === 'Contact' && contactAccess?.view ? data?.attendes && data?.attendes.map((item) => { | |
| 87 | - return ( | |
| 88 | - <Link to={`/contactView/${item._id}`}> | |
| 89 | - <Text color='brand.600' sx={{ '&:hover': { color: 'blue.500', textDecoration: 'underline' } }}>{item.firstName + ' ' + item.lastName}</Text> | |
| 90 | - </Link> | |
| 91 | - ) | |
| 92 | - }) : data?.related === 'Lead' && leadAccess?.view ? data?.attendesLead && data?.attendesLead.map((item) => { | |
| 93 | - return ( | |
| 94 | - <Link to={`/leadView/${item._id}`}> | |
| 95 | - <Text color='brand.600' sx={{ '&:hover': { color: 'blue.500', textDecoration: 'underline' } }}>{item.leadName}</Text> | |
| 96 | - </Link> | |
| 97 | - ) | |
| 98 | - }) : data?.related === 'Contact' ? data?.attendes && data?.attendes.map((item) => { | |
| 99 | - return ( | |
| 100 | - <Text color='blackAlpha.900' >{item.firstName + ' ' + item.lastName}</Text> | |
| 101 | - ) | |
| 102 | - }) : data?.related === 'Lead' ? data?.attendesLead && data?.attendesLead.map((item) => { | |
| 103 | - return ( | |
| 104 | - <Text color='blackAlpha.900' >{item.leadName}</Text> | |
| 105 | - ) | |
| 106 | - }) : '-'} | |
| 107 | - </GridItem> | |
| 108 | - | |
| 109 | - </Grid> | |
| 110 | - | |
| 111 | - </ModalBody> | |
| 112 | - <DrawerFooter> | |
| 113 | - {access?.view && <IconButton variant='outline' colorScheme={'green'} onClick={() => handleViewOpen()} borderRadius="10px" size="md" icon={<ViewIcon />} />} | |
| 114 | - {access?.update && <IconButton variant='outline' onClick={() => setEdit(true)} ml={3} borderRadius="10px" size="md" icon={<EditIcon />} />} | |
| 115 | - {access?.delete && <IconButton colorScheme='red' onClick={() => setDelete(true)} ml={3} borderRadius="10px" size="md" icon={<DeleteIcon />} />} | |
| 116 | - | |
| 117 | - {/* | |
| 249 | + {/* | |
| 118 | 250 | <DeleteTask fetchData={props.fetchData} isOpen={deleteModel} onClose={setDelete} viewClose={onClose} url='api/task/delete/' method='one' id={info?.event ? info?.event?.id : info} /> */} |
| 119 | - </DrawerFooter> | |
| 120 | - </>} | |
| 121 | - </ModalContent> | |
| 122 | - </Modal> | |
| 123 | - ) | |
| 124 | -} | |
| 251 | + </DrawerFooter> | |
| 252 | + </> | |
| 253 | + )} | |
| 254 | + </ModalContent> | |
| 255 | + </Modal> | |
| 256 | + ); | |
| 257 | +}; | |
| 125 | 258 | |
| 126 | -export default MeetingView | |
| 259 | +export default MeetingView; |
+13-2server/controllers/meeting/_routes.js
| @@ -1,5 +1,16 @@ | ||
| 1 | -const express = require('express'); | |
| 1 | +const express = require("express"); | |
| 2 | +const auth = require("../../middelwares/auth"); | |
| 3 | +const meeting = require("./meeting"); | |
| 2 | 4 | |
| 3 | 5 | const router = express.Router(); |
| 4 | 6 | |
| 5 | -module.exports = router | |
| 7 | +router.get("/", auth, meeting.index); | |
| 8 | +router.post("/add", auth, meeting.add); | |
| 9 | +// router.post("/addMany", auth, meeting.addMany); | |
| 10 | +router.get("/view/:id", auth, meeting.view); | |
| 11 | +// router.put("/edit/:id", auth, meeting.edit); | |
| 12 | +// router.put("/changeStatus/:id", auth, meeting.changeStatus); | |
| 13 | +// router.delete("/delete/:id", auth, meeting.deleteData); | |
| 14 | +// router.post("/deleteMany", auth, meeting.deleteMany); | |
| 15 | + | |
| 16 | +module.exports = router; |
+59-15server/controllers/meeting/meeting.js
| @@ -1,24 +1,68 @@ | ||
| 1 | -const MeetingHistory = require('../../model/schema/meeting') | |
| 2 | -const mongoose = require('mongoose'); | |
| 1 | +const MeetingHistory = require("../../model/schema/meeting"); | |
| 2 | +const mongoose = require("mongoose"); | |
| 3 | 3 | |
| 4 | 4 | const add = async (req, res) => { |
| 5 | - | |
| 6 | -} | |
| 5 | + try { | |
| 6 | + req.body.createdDate = new Date(); | |
| 7 | + const user = new MeetingHistory(req.body); | |
| 8 | + await user.save(); | |
| 9 | + res.status(200).json(user); | |
| 10 | + } catch (err) { | |
| 11 | + console.error("Failed to create Lead:", err); | |
| 12 | + res.status(400).json({ error: "Failed to create Lead" }); | |
| 13 | + } | |
| 14 | +}; | |
| 7 | 15 | |
| 8 | 16 | const index = async (req, res) => { |
| 9 | - | |
| 10 | -} | |
| 17 | + const query = req.query; | |
| 18 | + query.deleted = false; | |
| 19 | + | |
| 20 | + // let result = await Lead.find(query) | |
| 21 | + | |
| 22 | + let allData = await MeetingHistory.find(query) | |
| 23 | + .populate({ | |
| 24 | + path: "createBy", | |
| 25 | + match: { deleted: false }, // Populate only if createBy.deleted is false | |
| 26 | + }) | |
| 27 | + .exec(); | |
| 28 | + | |
| 29 | + const result = allData.filter((item) => item.createBy !== null); | |
| 30 | + res.send(result); | |
| 31 | +}; | |
| 11 | 32 | |
| 12 | 33 | const view = async (req, res) => { |
| 13 | - | |
| 14 | -} | |
| 34 | + console.log("getting view"); | |
| 35 | + try { | |
| 36 | + let response = await MeetingHistory.findOne({ _id: req.params.id }); | |
| 37 | + if (!response) return res.status(404).json({ message: "no Data Found." }); | |
| 38 | + let result = await MeetingHistory.aggregate([ | |
| 39 | + { $match: { _id: response._id } }, | |
| 40 | + { | |
| 41 | + $lookup: { | |
| 42 | + from: "User", | |
| 43 | + localField: "createBy", | |
| 44 | + foreignField: "_id", | |
| 45 | + as: "users", | |
| 46 | + }, | |
| 47 | + }, | |
| 48 | + { $unwind: { path: "$users", preserveNullAndEmptyArrays: true } }, | |
| 49 | + { | |
| 50 | + $addFields: { | |
| 51 | + createByName: "$users.username", | |
| 52 | + }, | |
| 53 | + }, | |
| 54 | + { $project: { contact: 0, users: 0, Lead: 0, createdByName: 0 } }, | |
| 55 | + ]); | |
| 56 | + console.log(result[0]); | |
| 57 | + res.status(200).json(result[0]); | |
| 58 | + } catch (err) { | |
| 59 | + console.log("Error:", err); | |
| 60 | + res.status(400).json({ Error: err }); | |
| 61 | + } | |
| 62 | +}; | |
| 15 | 63 | |
| 16 | -const deleteData = async (req, res) => { | |
| 17 | - | |
| 18 | -} | |
| 64 | +const deleteData = async (req, res) => {}; | |
| 19 | 65 | |
| 20 | -const deleteMany = async (req, res) => { | |
| 21 | - | |
| 22 | -} | |
| 66 | +const deleteMany = async (req, res) => {}; | |
| 23 | 67 | |
| 24 | -module.exports = { add, index, view, deleteData, deleteMany } | |
| 68 | +module.exports = { add, index, view, deleteData, deleteMany }; |