|  |  | 
 |  |  | import * as React from 'react'; | 
 |  |  | import { useState } from 'react'; | 
 |  |  | import { Paper, Typography, Box } from '@mui/material'; | 
 |  |  | import ContactsIcon from '@mui/icons-material/AccountCircle'; | 
 |  |  | import DealIcon from '@mui/icons-material/MonetizationOn'; | 
 |  |  | import { Paper, Typography, Box, AvatarGroup, Avatar } from '@mui/material'; | 
 |  |  | import { | 
 |  |  |     useCreatePath, | 
 |  |  |     SelectField, | 
 |  |  |     useRecordContext, | 
 |  |  |     Link, | 
 |  |  |     useResourceContext, | 
 |  |  |     useDataProvider, | 
 |  |  | } from 'react-admin'; | 
 |  |  |  | 
 |  |  | import PulseSignal from '../components/PulseSignal'; | 
 |  |  | import { AgvAvatar } from './AgvAvatar'; | 
 |  |  | import { red, blue } from '@mui/material/colors'; | 
 |  |  |  | 
 |  |  | export const AgvCard = (props) => { | 
 |  |  |     const resource = useResourceContext(); | 
 |  |  | 
 |  |  |     const createPath = useCreatePath(); | 
 |  |  |     const record = useRecordContext(props); | 
 |  |  |     if (!record) return null; | 
 |  |  |  | 
 |  |  |     console.log(record); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <Link | 
 |  |  | 
 |  |  |                     flexDirection: 'column', | 
 |  |  |                     justifyContent: 'space-between', | 
 |  |  |                     padding: '1em', | 
 |  |  |                     ...(!record.online && { | 
 |  |  |                         animation: 'cardBorderPulse 2s infinite', | 
 |  |  |                         '@keyframes cardBorderPulse': { | 
 |  |  |                             '0%': { | 
 |  |  |                                 boxShadow: '0 0 2px 1px rgba(255, 0, 0, 0.1)', | 
 |  |  |                             }, | 
 |  |  |                             '50%': { | 
 |  |  |                                 boxShadow: '0 0 3px 2px rgba(255, 0, 0, 0.3)', | 
 |  |  |                             }, | 
 |  |  |                             '100%': { | 
 |  |  |                                 boxShadow: '0 0 2px 1px rgba(255, 0, 0, 0.1)', | 
 |  |  |                             }, | 
 |  |  |                         }, | 
 |  |  |                     }) | 
 |  |  |                 }} | 
 |  |  |                 elevation={elevation} | 
 |  |  |             > | 
 |  |  |                 <Box display="flex" flexDirection="row" alignItems="center" justifyContent='space-between'> | 
 |  |  |                     <PulseSignal | 
 |  |  |                         flag={record.online} | 
 |  |  |                     /> | 
 |  |  |                     <Typography variant="caption" > | 
 |  |  |                         vol: | 
 |  |  |                         <Box | 
 |  |  |                             component={"span"} | 
 |  |  |                             sx={{ | 
 |  |  |                                 color: record.vol < record.chargeLine ? red[400] : 'inherit' | 
 |  |  |                             }}> | 
 |  |  |                             {record.vol} | 
 |  |  |                         </Box> | 
 |  |  |                     </Typography> | 
 |  |  |                 </Box> | 
 |  |  |                 <Box display="flex" flexDirection="column" alignItems="center"> | 
 |  |  |                     <AgvAvatar /> | 
 |  |  |                     <Box textAlign="center" marginTop={1}> | 
 |  |  |                         <Typography variant="subtitle2"> | 
 |  |  |                             {record.uuid} | 
 |  |  |                         </Typography> | 
 |  |  |                         <SelectField | 
 |  |  |                     <Box textAlign="center" marginTop={2}> | 
 |  |  |                         <Typography | 
 |  |  |                             variant="subtitle2" | 
 |  |  |                             color="textSecondary" | 
 |  |  |                             source="uuid" | 
 |  |  |                             choices={[ | 
 |  |  |                                 { id: '1', name: 'sad' } | 
 |  |  |                             ]} | 
 |  |  |                         /> | 
 |  |  |                             component="div" | 
 |  |  |                             sx={{ fontWeight: 'bold' }} | 
 |  |  |                         > | 
 |  |  |                             {record.agvStatus} | 
 |  |  |                         </Typography> | 
 |  |  |                         <Typography variant="overline" sx={{ opacity: .7 }}> | 
 |  |  |                             code: {record.code} | 
 |  |  |                         </Typography> | 
 |  |  |                     </Box> | 
 |  |  |                 </Box> | 
 |  |  |                 <Box display="flex" justifyContent="space-around" width="100%"> | 
 |  |  |                     <Box display="flex" alignItems="center"> | 
 |  |  |                         <ContactsIcon color="disabled" sx={{ mr: 1 }} /> | 
 |  |  |                         <div> | 
 |  |  |                             <Typography variant="subtitle2" sx={{ mb: -1 }}> | 
 |  |  |                                 {record.nb_contacts} | 
 |  |  |                             </Typography> | 
 |  |  |                             <Typography variant="caption" color="textSecondary"> | 
 |  |  |                                 {record.nb_contacts | 
 |  |  |                                     ? record.nb_contacts > 1 | 
 |  |  |                                         ? 'contacts' | 
 |  |  |                                         : 'contact' | 
 |  |  |                                     : 'contact'} | 
 |  |  |                             </Typography> | 
 |  |  |                         </div> | 
 |  |  |                     </Box> | 
 |  |  |                     <Box sx={{ display: 'flex', alignItems: 'center' }}> | 
 |  |  |                         <DealIcon color="disabled" sx={{ mr: 1 }} /> | 
 |  |  |                         <div> | 
 |  |  |                             <Typography variant="subtitle2" sx={{ mb: -1 }}> | 
 |  |  |                                 {record.nb_deals} | 
 |  |  |                             </Typography> | 
 |  |  |                             <Typography variant="caption" color="textSecondary"> | 
 |  |  |                                 {record.nb_deals | 
 |  |  |                                     ? record.nb_deals > 1 | 
 |  |  |                                         ? 'deals' | 
 |  |  |                                         : 'deal' | 
 |  |  |                                     : 'deal'} | 
 |  |  |                             </Typography> | 
 |  |  |                         </div> | 
 |  |  |                         <TaskAvatarGroupIterator taskIds={record.taskIds} /> | 
 |  |  |                     </Box> | 
 |  |  |                 </Box> | 
 |  |  |             </Paper> | 
 |  |  |         </Link> | 
 |  |  |     ); | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | const TaskAvatarGroupIterator = ({ taskIds }) => { | 
 |  |  |     const dataProvider = useDataProvider(); | 
 |  |  |     const [data, setData] = React.useState([]); | 
 |  |  |     const [total, setTotal] = React.useState(0); | 
 |  |  |  | 
 |  |  |     React.useEffect(() => { | 
 |  |  |         if (taskIds?.length > 0) { | 
 |  |  |             dataProvider.getMany('task', { ids: taskIds }).then(res => { | 
 |  |  |                 if (res.data?.length > 0) { | 
 |  |  |                     setTotal(res.data.length); | 
 |  |  |                     setData(res.data); | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |         } | 
 |  |  |     }, [taskIds]) | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <AvatarGroup | 
 |  |  |             max={4} | 
 |  |  |             total={total} | 
 |  |  |             spacing="medium" | 
 |  |  |             sx={{ | 
 |  |  |                 '& .MuiAvatar-circular': { | 
 |  |  |                     width: 35, | 
 |  |  |                     height: 25, | 
 |  |  |                     fontSize: '0.7rem', | 
 |  |  |                 }, | 
 |  |  |             }} | 
 |  |  |         > | 
 |  |  |             {data.length > 0 ? ( | 
 |  |  |                 data.map((record) => ( | 
 |  |  |                     <Avatar | 
 |  |  |                         key={record.id} | 
 |  |  |                         title={`${record.seqNum}`} | 
 |  |  |                         sx={{ bgcolor: blue[300] }} | 
 |  |  |                     > | 
 |  |  |                         {record.seqNum.slice(0, 4)} | 
 |  |  |                     </Avatar> | 
 |  |  |                 )) | 
 |  |  |             ) : ( | 
 |  |  |                 <Avatar title="No tasks" > | 
 |  |  |                     N/A | 
 |  |  |                 </Avatar> | 
 |  |  |             )} | 
 |  |  |         </AvatarGroup> | 
 |  |  |     ); | 
 |  |  | } |