From b34326783ecfbea1a456b9d849b30d37122b6647 Mon Sep 17 00:00:00 2001 From: samwel141 Date: Fri, 23 Feb 2024 07:23:42 +0300 Subject: [PATCH] Added additional info UI/UX in messaging(Inbox) --- src/components/GrowerDetail.js | 16 ++ src/components/Messaging/MessageBody.js | 179 +++++++++++++++++++---- src/context/GrowerDetailStatusContext.js | 27 ++++ 3 files changed, 196 insertions(+), 26 deletions(-) create mode 100644 src/context/GrowerDetailStatusContext.js diff --git a/src/components/GrowerDetail.js b/src/components/GrowerDetail.js index dfd0d5c60..b625d1eca 100644 --- a/src/components/GrowerDetail.js +++ b/src/components/GrowerDetail.js @@ -45,6 +45,7 @@ import { captureStatus } from '../common/variables'; import { getDateTimeStringLocale } from '../common/locale'; import { makeStyles } from '@material-ui/core/styles'; import treeTrackerApi from 'api/treeTrackerApi'; +import { GrowerDetailStatusContext } from 'context/GrowerDetailStatusContext'; const log = loglevel.getLogger('../components/GrowerDetail.js'); @@ -159,7 +160,12 @@ const GrowerDetail = ({ open, growerId, onClose }) => { const [loading, setLoading] = useState(false); const [isImageLoading, setIsImageLoading] = useState(true); const [errorMessage, setErrorMessage] = useState(null); + const growerDetailStatusContext = useContext(GrowerDetailStatusContext); + const { + setGrowerDetailLoading, + setVerificationStatus_, + } = growerDetailStatusContext; function formatDevices(grower) { // deduplicate and format const devices = grower?.devices?.reduce((result, device) => { @@ -209,6 +215,7 @@ const GrowerDetail = ({ open, growerId, onClose }) => { async function loadCaptures() { if (grower.id) { setLoading(true); + setGrowerDetailLoading(true); const [ approvedCount, awaitingCount, @@ -224,7 +231,16 @@ const GrowerDetail = ({ open, growerId, onClose }) => { [captureStatus.UNPROCESSED]: awaitingCount, [captureStatus.REJECTED]: rejectedCount, }); + + setVerificationStatus_((prevStatus) => ({ + ...prevStatus, + [captureStatus.APPROVED]: approvedCount, + [captureStatus.UNPROCESSED]: awaitingCount, + [captureStatus.REJECTED]: rejectedCount, + })); + setLoading(false); + setGrowerDetailLoading(false); } } loadCaptures(); diff --git a/src/components/Messaging/MessageBody.js b/src/components/Messaging/MessageBody.js index 7320afce7..1d24d9f47 100644 --- a/src/components/Messaging/MessageBody.js +++ b/src/components/Messaging/MessageBody.js @@ -17,12 +17,19 @@ import { Modal, Paper, Typography, + LinearProgress, CircularProgress, + List, + ListItem, + ListItemAvatar, + ListItemText, } from '@material-ui/core'; +import { Clear, Done, HourglassEmptyOutlined } from '@material-ui/icons'; import { TextInput } from './TextInput.js'; import { MessagingContext } from 'context/MessagingContext.js'; import SurveyCharts from './SurveyCharts.js'; import * as loglevel from 'loglevel'; +import { GrowerDetailStatusContext } from 'context/GrowerDetailStatusContext.js'; const log = loglevel.getLogger('./MessageBody.js'); @@ -111,6 +118,7 @@ const useStyles = makeStyles((theme) => ({ senderInfo: { padding: '10px', borderBottom: '2px solid black', + position: 'relative', }, messagesBody: { flexGrow: 1, @@ -163,31 +171,56 @@ const useStyles = makeStyles((theme) => ({ color: 'black', }, }, - surveyResponse: { - display: 'flex', - flexDirection: 'column', - backgroundColor: 'lightGrey', - borderRadius: '10px', - padding: '1em', - margin: '5px', - }, - modalContainer: { - backgroundColor: 'white', - width: '45%', - outline: 'none', - borderRadius: '4px', - padding: '20px', + messageInbox: { position: 'absolute', - top: '30%', - left: '22%', + right: 0, + top: 0, + }, + box: { + paddingLeft: theme.spacing(2), + paddingRight: theme.spacing(2), + marginRight: theme.spacing(1), }, - centeredMessage: { + + listCaptures: { display: 'flex', - flexDirection: 'column', - justifyContent: 'center', alignItems: 'center', - marginTop: '20%', - height: '50%', + justifyContent: 'space-between', + }, + rejectedChip: { + backgroundColor: theme.palette.stats.red.replace(/[^,]+(?=\))/, '0.2'), // Change opacity of rgba + color: theme.palette.stats.red, + fontWeight: 600, + fontSize: '0.5em', + }, + awaitingChip: { + backgroundColor: theme.palette.stats.orange.replace(/[^,]+(?=\))/, '0.2'), // Change opacity of rgba + color: theme.palette.stats.orange, + fontWeight: 600, + fontSize: '0.5em', + }, + approvedChip: { + backgroundColor: theme.palette.stats.green.replace(/[^,]+(?=\))/, '0.2'), // Change opacity of rgba + color: theme.palette.stats.green, + fontWeight: 600, + fontSize: '0.5em', + }, + captures: { + width: '100%', + }, + liAvatar: { + minWidth: 20, + }, + boxItem: { + borderRadius: 10, + border: '1px solid #ddd', + marginLeft: theme.spacing(1), + maxHeight: '4rem', + pading: 'auto 6px', + }, + gutters: { + paddingLeft: 4, + paddingRight: 4, }, })); @@ -352,13 +385,102 @@ const SenderInformation = ({ showCharts, setShowCharts, }) => { - const { senderInfo, senderItem, avatar, button, dataContainer } = useStyles(); + const { + senderInfo, + senderItem, + avatar, + button, + dataContainer, + messageInbox, + box, + captures, + approvedChip, + liAvatar, + gutters, + boxItem, + listCaptures, + awaitingChip, + rejectedChip, + } = useStyles(); + + const growerDetailStatusContext = useContext(GrowerDetailStatusContext); + + const { + growerDetailLoading, + verificationStatus_, + } = growerDetailStatusContext; return ( {type === 'message' ? ( - + + + + + + Captures + + {growerDetailLoading ? ( + + ) : ( + + + + + + + + + + {verificationStatus_?.approved || 0} + + } + secondary="Approved" + /> + + + + + + + + + + + {verificationStatus_?.unprocessed || 0} + + } + secondary="Awaiting" + /> + + + + + + + + + + + {verificationStatus_?.rejected || 0} + + } + secondary="Rejected" + /> + + + + )} + + + ) : type === 'announce' ? ( - ID: {id} - + <> + + Recipient-Name + + + ID: {id} + + )} {(type === 'survey' || type === 'survey_response') && responseCount > 0 && ( diff --git a/src/context/GrowerDetailStatusContext.js b/src/context/GrowerDetailStatusContext.js new file mode 100644 index 000000000..92b75de5d --- /dev/null +++ b/src/context/GrowerDetailStatusContext.js @@ -0,0 +1,27 @@ +import React from 'react'; +import { createContext } from 'react'; + +export const GrowerDetailStatusContext = createContext({ + growerDetailLoading: false, + verificationStatus_: null, + setGrowerDetailLoading: () => {}, + setVerificationStatus_: () => {}, +}); + +export const GrowerDetailStatusProvider = (props) => { + const [growerDetailLoading, setGrowerDetailLoading] = React.useState(false); + const [verificationStatus_, setVerificationStatus] = React.useState(null); + + const value = { + growerDetailLoading, + verificationStatus_, + setGrowerDetailLoading, + setVerificationStatus, + }; + + return ( + + {props.children} + + ); +};