import React, { useState, useContext, useEffect } from 'react'; import uuid from 'uuid/v4'; import { MessagingContext } from 'context/MessagingContext'; import { FormControl, Box, Modal, TextField, Typography, Button, } from '@material-ui/core'; import { Autocomplete } from '@material-ui/lab'; import { makeStyles } from '@material-ui/styles'; import GSInputLabel from 'components/common/InputLabel'; const log = require('loglevel'); const useStyles = makeStyles((theme) => ({ box: { position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', backgroundColor: '#FFF', border: `2px solid ${theme.palette.primary.main}`, borderRadius: 20, boxShadow: 24, padding: 20, textAlign: 'center', [theme.breakpoints.down('md')]: { height: 450, width: 300, }, [theme.breakpoints.up('md')]: { height: 550, width: 400, }, [theme.breakpoints.up('lg')]: { height: 650, width: 500, }, }, formContent: { display: 'flex', flexDirection: 'column', justifyContent: 'space-around', height: '90%', padding: '1em', }, header: { color: theme.palette.primary.main, borderBottom: `2px solid black`, padding: 10, }, button: { margin: '10px 0', background: theme.palette.primary.main, color: 'white', }, })); const NewMessage = ({ openModal, handleClose, setMessageRecipient }) => { const { box, formContent, header, button } = useStyles(); const { setErrorMessage, user, authors, setThreads, postMessageSend, } = useContext(MessagingContext); const [messageContent, setMessageContent] = useState(''); const [recipient, setRecipient] = useState(''); const [inputValue, setInputValue] = useState(''); const [errors, setErrors] = useState(null); useEffect(() => { if (openModal === false) { setMessageContent(''); setRecipient(''); } }, [openModal]); useEffect(() => { // set an error message right away if there are no authors if (authors.length === 0) { setErrors('Sorry, no accounts were found.'); } }, [authors]); const handleChange = (e) => { // don't remove the error if it's not a user mistake, like there aren't any authors if (authors.length > 0) { setErrors(null); } const { name, value } = e.target; name === 'body' ? setMessageContent(value) : setRecipient(e.target.textContent); }; const validateMessage = (payload) => { const errors = {}; if (payload.body.length === 0 || !/\w/g.test(payload.body.trim())) { errors.body = 'Please enter a message'; } if (!payload.recipient_handle) { errors.recipient = 'Please select a recipient'; } if (authors.length === 0) { errors.accounts = 'Sorry, no accounts were found.'; } return errors; }; const handleSubmit = async (e) => { e.preventDefault(); const messagePayload = { author_handle: user.userName, recipient_handle: recipient, type: 'message', body: messageContent, }; const errs = validateMessage(messagePayload); const errorsFound = Object.keys(errs).length > 0; if (errorsFound) { setErrors(errs); } else { const res = await postMessageSend(messagePayload); if (res.error) { setErrorMessage(res.message); } else { const newMessage = { parent_message_id: null, body: messageContent, composed_at: new Date().toISOString(), from: user.userName, id: uuid(), recipient_organization_id: null, recipient_region_id: null, survey: null, to: recipient, type: 'message', video_link: null, }; log.debug('...update threads after postMessageSend'); // update the full set of threads setThreads((prev) => [...prev, { userName: recipient, messages: [newMessage] }].sort( (a, b) => new Date(b?.messages?.at(-1).composed_at) - new Date(a?.messages?.at(-1).composed_at) ) ); } setMessageRecipient(recipient); handleClose(); } }; return ( <Modal open={openModal} onClose={handleClose} aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description" > <Box className={box}> <form className={formContent} onSubmit={handleSubmit}> <Box className={header} my={1}> <Typography variant="h3">Send New Message</Typography> </Box> {errors?.accounts && ( <Typography style={{ color: 'red', fontWeight: 'bold', margin: '20px 10px 0px', }} > {errors.accounts} </Typography> )} <FormControl> {errors?.recipient && ( <Typography style={{ color: 'red', fontWeight: 'bold', margin: '20px 10px 0px', }} > {errors.recipient} </Typography> )} <GSInputLabel text="Choose the Message Recipient" /> <Autocomplete name="to" selectOnFocus clearOnBlur handleHomeEndKeys value={recipient} onChange={handleChange} options={ authors.length ? authors.map((author) => author.handle || '').sort() : [] } inputValue={inputValue} getOptionSelected={(option, value) => option === value} onInputChange={(e, val) => setInputValue(val)} id="controllable-states-demo" freeSolo sx={{ width: 300 }} renderInput={(params) => ( <TextField {...params} label="Message Recipient" /> )} /> </FormControl> <FormControl> {errors?.message && ( <Typography style={{ color: 'red', fontWeight: 'bold', margin: '20px 10px 0px', }} > {errors.message} </Typography> )} <GSInputLabel text="Message" /> <TextField multiline placeholder="Write your message here ..." name="body" value={messageContent} onChange={handleChange} /> </FormControl> <Button type="submit" size="large" className={button} disabled={!!errors} > Send Message </Button> </form> </Box> </Modal> ); }; export default NewMessage;