WhiteNightsAdminPanel/src/widgets/DevicesTable/index.tsx

226 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { Check, RotateCcw, Send, X } from "lucide-react";
import {
authInstance,
devicesStore,
Modal,
snapshotStore,
vehicleStore,
} from "@shared";
import { useEffect, useState } from "react";
import { observer } from "mobx-react-lite";
import { Button, Checkbox } from "@mui/material";
const formatDate = (dateString: string | undefined) => {
if (!dateString) return "Нет данных";
try {
const date = new Date(dateString);
return new Intl.DateTimeFormat("ru-RU", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
}).format(date);
} catch (error) {
console.error("Error formatting date:", error);
return "Некорректная дата";
}
};
function createData(
uuid: string,
online: boolean,
lastUpdate: string,
gps: boolean,
media: boolean,
connection: boolean
) {
return { uuid, online, lastUpdate, gps, media, connection };
}
const rows = (devices: any[], vehicles: any[]) => {
return devices.map((device) => {
const { device_status } = vehicles.find(
(v) => v?.device_status?.device_uuid === device
);
const findVehicle = vehicles.find((v) => v?.vehicle?.uuid === device);
console.log(findVehicle);
return createData(
findVehicle?.vehicle?.tail_number ?? "1243000",
device_status?.online,
device_status?.last_update,
device_status?.gps_ok,
device_status?.media_service_ok,
device_status?.is_connected
);
});
};
export const DevicesTable = observer(() => {
const {
devices,
getDevices,
uuid,
setSelectedDevice,
sendSnapshotModalOpen,
toggleSendSnapshotModal,
} = devicesStore;
const { snapshots, getSnapshots } = snapshotStore;
const { vehicles, getVehicles } = vehicleStore;
const [selectedDevices, setSelectedDevices] = useState<string[]>([]);
useEffect(() => {
const fetchData = async () => {
await getVehicles();
await getDevices();
await getSnapshots();
};
fetchData();
}, []);
const handleSendSnapshot = (uuid: string) => {
setSelectedDevice(uuid);
toggleSendSnapshotModal();
};
const handleReloadStatus = async (uuid: string) => {
setSelectedDevice(uuid);
await authInstance.post(`/devices/${uuid}/request-status`);
await getDevices();
};
const handleSelectDevice = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.checked) {
setSelectedDevices([...selectedDevices, event.target.value]);
} else {
setSelectedDevices(
selectedDevices.filter((device) => device !== event.target.value)
);
}
};
const handleSendSnapshotAction = async (uuid: string, snapshotId: string) => {
await authInstance.post(`/devices/${uuid}/force-snapshot`, {
snapshot_id: snapshotId,
});
await getDevices();
};
return (
<>
<TableContainer component={Paper}>
<div className="flex justify-end p-3 gap-5">
<Button variant="contained" color="primary">
Выбрать все
</Button>
<Button
variant="contained"
color="primary"
disabled={selectedDevices.length === 0}
className="ml-auto"
onClick={() => handleSendSnapshot(uuid ?? "")}
>
Отправить снапшот
</Button>
</div>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="center"></TableCell>
<TableCell align="center">Бортовой номер</TableCell>
<TableCell align="center">Онлайн</TableCell>
<TableCell align="center">Последнее обновление</TableCell>
<TableCell align="center">ГПС</TableCell>
<TableCell align="center">Медиа-данные</TableCell>
<TableCell align="center">Подключение</TableCell>
<TableCell align="center">Перезапросить</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows(devices, vehicles).map((row) => (
<TableRow
key={row?.uuid}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
className="flex items-center"
>
<TableCell align="center">
<Checkbox
className="h-full"
onChange={handleSelectDevice}
value={row?.uuid}
/>
</TableCell>
<TableCell align="center" component="th" scope="row">
{row?.uuid}
</TableCell>
<TableCell align="center">
{row?.online ? (
<Check className="m-auto text-green-500" />
) : (
<X className="m-auto text-red-500" />
)}
</TableCell>
<TableCell align="center">
{formatDate(row?.lastUpdate)}
</TableCell>
<TableCell align="center">
{row?.gps ? (
<Check className="m-auto text-green-500" />
) : (
<X className="m-auto text-red-500" />
)}
</TableCell>
<TableCell align="center">
{row?.media ? (
<Check className="m-auto text-green-500" />
) : (
<X className="m-auto text-red-500" />
)}
</TableCell>
<TableCell align="center">
{row?.connection ? (
<Check className="m-auto text-green-500" />
) : (
<X className="m-auto text-red-500" />
)}
</TableCell>
<TableCell align="center" className="flex justify-center">
<button onClick={() => handleReloadStatus(row?.uuid ?? "")}>
<RotateCcw className="m-auto" />
</button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<Modal open={sendSnapshotModalOpen} onClose={toggleSendSnapshotModal}>
<p>Выбрать снапшот</p>
<div className="mt-5 flex flex-col gap-2 max-h-[300px] overflow-y-auto">
{snapshots &&
snapshots.map((snapshot) => (
<button
onClick={() => handleSendSnapshotAction(uuid!, snapshot.ID)}
className="p-2 rounded-xl bg-slate-100"
key={snapshot.ID}
>
{snapshot.Name}
</button>
))}
</div>
</Modal>
</>
);
});