|  |  |  | 
|---|
|  |  |  | import * as React from 'react'; | 
|---|
|  |  |  | import { useState } from 'react'; | 
|---|
|  |  |  | import { Paper, Typography, Box, Chip, Stack } 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 } from '@mui/material/colors'; | 
|---|
|  |  |  | 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 | 
|---|
|  |  |  | to={createPath({ | 
|---|
|  |  |  | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <Box display="flex" flexDirection="row" alignItems="center" justifyContent='space-between'> | 
|---|
|  |  |  | <PulseSignal | 
|---|
|  |  |  | flag={true} | 
|---|
|  |  |  | flag={record.online} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Typography variant="caption" > | 
|---|
|  |  |  | vol: | 
|---|
|  |  |  | 
|---|
|  |  |  | </Box> | 
|---|
|  |  |  | <Box display="flex" flexDirection="column" alignItems="center"> | 
|---|
|  |  |  | <AgvAvatar /> | 
|---|
|  |  |  | <Box textAlign="center" marginTop={1}> | 
|---|
|  |  |  | <Box textAlign="center" marginTop={2}> | 
|---|
|  |  |  | <Typography variant="subtitle2"> | 
|---|
|  |  |  | {record.agvStatus} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | 
|---|
|  |  |  | </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> | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | } | 
|---|