aboutsummaryrefslogtreecommitdiff
path: root/modern/src/common/components/StatusCard.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'modern/src/common/components/StatusCard.jsx')
-rw-r--r--modern/src/common/components/StatusCard.jsx288
1 files changed, 0 insertions, 288 deletions
diff --git a/modern/src/common/components/StatusCard.jsx b/modern/src/common/components/StatusCard.jsx
deleted file mode 100644
index a63d0f80..00000000
--- a/modern/src/common/components/StatusCard.jsx
+++ /dev/null
@@ -1,288 +0,0 @@
-import React, { useState } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom';
-import Draggable from 'react-draggable';
-import {
- Card,
- CardContent,
- Typography,
- CardActions,
- IconButton,
- Table,
- TableBody,
- TableRow,
- TableCell,
- Menu,
- MenuItem,
- CardMedia,
-} from '@mui/material';
-import makeStyles from '@mui/styles/makeStyles';
-import CloseIcon from '@mui/icons-material/Close';
-import ReplayIcon from '@mui/icons-material/Replay';
-import PublishIcon from '@mui/icons-material/Publish';
-import EditIcon from '@mui/icons-material/Edit';
-import DeleteIcon from '@mui/icons-material/Delete';
-import PendingIcon from '@mui/icons-material/Pending';
-
-import { useTranslation } from './LocalizationProvider';
-import RemoveDialog from './RemoveDialog';
-import PositionValue from './PositionValue';
-import { useDeviceReadonly } from '../util/permissions';
-import usePositionAttributes from '../attributes/usePositionAttributes';
-import { devicesActions } from '../../store';
-import { useCatch, useCatchCallback } from '../../reactHelper';
-import { useAttributePreference } from '../util/preferences';
-
-const useStyles = makeStyles((theme) => ({
- card: {
- pointerEvents: 'auto',
- width: theme.dimensions.popupMaxWidth,
- },
- media: {
- height: theme.dimensions.popupImageHeight,
- display: 'flex',
- justifyContent: 'flex-end',
- alignItems: 'flex-start',
- },
- mediaButton: {
- color: theme.palette.primary.contrastText,
- mixBlendMode: 'difference',
- },
- header: {
- display: 'flex',
- justifyContent: 'space-between',
- alignItems: 'center',
- padding: theme.spacing(1, 1, 0, 2),
- },
- content: {
- paddingTop: theme.spacing(1),
- paddingBottom: theme.spacing(1),
- maxHeight: theme.dimensions.cardContentMaxHeight,
- overflow: 'auto',
- },
- delete: {
- color: theme.palette.error.main,
- },
- icon: {
- width: '25px',
- height: '25px',
- filter: 'brightness(0) invert(1)',
- },
- table: {
- '& .MuiTableCell-sizeSmall': {
- paddingLeft: 0,
- paddingRight: 0,
- },
- },
- cell: {
- borderBottom: 'none',
- },
- actions: {
- justifyContent: 'space-between',
- },
- root: ({ desktopPadding }) => ({
- pointerEvents: 'none',
- position: 'fixed',
- zIndex: 5,
- left: '50%',
- [theme.breakpoints.up('md')]: {
- left: `calc(50% + ${desktopPadding} / 2)`,
- bottom: theme.spacing(3),
- },
- [theme.breakpoints.down('md')]: {
- left: '50%',
- bottom: `calc(${theme.spacing(3)} + ${theme.dimensions.bottomBarHeight}px)`,
- },
- transform: 'translateX(-50%)',
- }),
-}));
-
-const StatusRow = ({ name, content }) => {
- const classes = useStyles();
-
- return (
- <TableRow>
- <TableCell className={classes.cell}>
- <Typography variant="body2">{name}</Typography>
- </TableCell>
- <TableCell className={classes.cell}>
- <Typography variant="body2" color="textSecondary">{content}</Typography>
- </TableCell>
- </TableRow>
- );
-};
-
-const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPadding = 0 }) => {
- const classes = useStyles({ desktopPadding });
- const navigate = useNavigate();
- const dispatch = useDispatch();
- const t = useTranslation();
-
- const deviceReadonly = useDeviceReadonly();
-
- const shareDisabled = useSelector((state) => state.session.server.attributes.disableShare);
- const user = useSelector((state) => state.session.user);
- const device = useSelector((state) => state.devices.items[deviceId]);
-
- const deviceImage = device?.attributes?.deviceImage;
-
- const positionAttributes = usePositionAttributes(t);
- const positionItems = useAttributePreference('positionItems', 'speed,address,totalDistance,course');
-
- const [anchorEl, setAnchorEl] = useState(null);
-
- const [removing, setRemoving] = useState(false);
-
- const handleRemove = useCatch(async (removed) => {
- if (removed) {
- const response = await fetch('/api/devices');
- if (response.ok) {
- dispatch(devicesActions.refresh(await response.json()));
- } else {
- throw Error(await response.text());
- }
- }
- setRemoving(false);
- });
-
- const handleGeofence = useCatchCallback(async () => {
- const newItem = {
- name: t('sharedGeofence'),
- area: `CIRCLE (${position.latitude} ${position.longitude}, 50)`,
- };
- const response = await fetch('/api/geofences', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(newItem),
- });
- if (response.ok) {
- const item = await response.json();
- const permissionResponse = await fetch('/api/permissions', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ deviceId: position.deviceId, geofenceId: item.id }),
- });
- if (!permissionResponse.ok) {
- throw Error(await permissionResponse.text());
- }
- navigate(`/settings/geofence/${item.id}`);
- } else {
- throw Error(await response.text());
- }
- }, [navigate, position]);
-
- return (
- <>
- <div className={classes.root}>
- {device && (
- <Draggable
- handle={`.${classes.media}, .${classes.header}`}
- >
- <Card elevation={3} className={classes.card}>
- {deviceImage ? (
- <CardMedia
- className={classes.media}
- image={`/api/media/${device.uniqueId}/${deviceImage}`}
- >
- <IconButton
- size="small"
- onClick={onClose}
- onTouchStart={onClose}
- >
- <CloseIcon fontSize="small" className={classes.mediaButton} />
- </IconButton>
- </CardMedia>
- ) : (
- <div className={classes.header}>
- <Typography variant="body2" color="textSecondary">
- {device.name}
- </Typography>
- <IconButton
- size="small"
- onClick={onClose}
- onTouchStart={onClose}
- >
- <CloseIcon fontSize="small" />
- </IconButton>
- </div>
- )}
- {position && (
- <CardContent className={classes.content}>
- <Table size="small" classes={{ root: classes.table }}>
- <TableBody>
- {positionItems.split(',').filter((key) => position.hasOwnProperty(key) || position.attributes.hasOwnProperty(key)).map((key) => (
- <StatusRow
- key={key}
- name={positionAttributes[key]?.name || key}
- content={(
- <PositionValue
- position={position}
- property={position.hasOwnProperty(key) ? key : null}
- attribute={position.hasOwnProperty(key) ? null : key}
- />
- )}
- />
- ))}
- </TableBody>
- </Table>
- </CardContent>
- )}
- <CardActions classes={{ root: classes.actions }} disableSpacing>
- <IconButton
- color="secondary"
- onClick={(e) => setAnchorEl(e.currentTarget)}
- disabled={!position}
- >
- <PendingIcon />
- </IconButton>
- <IconButton
- onClick={() => navigate('/replay')}
- disabled={disableActions || !position}
- >
- <ReplayIcon />
- </IconButton>
- <IconButton
- onClick={() => navigate(`/settings/device/${deviceId}/command`)}
- disabled={disableActions}
- >
- <PublishIcon />
- </IconButton>
- <IconButton
- onClick={() => navigate(`/settings/device/${deviceId}`)}
- disabled={disableActions || deviceReadonly}
- >
- <EditIcon />
- </IconButton>
- <IconButton
- onClick={() => setRemoving(true)}
- disabled={disableActions || deviceReadonly}
- className={classes.delete}
- >
- <DeleteIcon />
- </IconButton>
- </CardActions>
- </Card>
- </Draggable>
- )}
- </div>
- {position && (
- <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={() => setAnchorEl(null)}>
- <MenuItem onClick={() => navigate(`/position/${position.id}`)}><Typography color="secondary">{t('sharedShowDetails')}</Typography></MenuItem>
- <MenuItem onClick={handleGeofence}>{t('sharedCreateGeofence')}</MenuItem>
- <MenuItem component="a" target="_blank" href={`https://www.google.com/maps/search/?api=1&query=${position.latitude}%2C${position.longitude}`}>{t('linkGoogleMaps')}</MenuItem>
- <MenuItem component="a" target="_blank" href={`http://maps.apple.com/?ll=${position.latitude},${position.longitude}`}>{t('linkAppleMaps')}</MenuItem>
- <MenuItem component="a" target="_blank" href={`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${position.latitude}%2C${position.longitude}&heading=${position.course}`}>{t('linkStreetView')}</MenuItem>
- {!shareDisabled && !user.temporary && <MenuItem onClick={() => navigate(`/settings/device/${deviceId}/share`)}>{t('deviceShare')}</MenuItem>}
- </Menu>
- )}
- <RemoveDialog
- open={removing}
- endpoint="devices"
- itemId={deviceId}
- onResult={(removed) => handleRemove(removed)}
- />
- </>
- );
-};
-
-export default StatusCard;