diff --git a/src/pages/route/show.tsx b/src/pages/route/show.tsx index c65b055..0fba6e0 100644 --- a/src/pages/route/show.tsx +++ b/src/pages/route/show.tsx @@ -1,19 +1,196 @@ -import {Stack, Typography} from '@mui/material' +import {Stack, Typography, Box, Grid2 as Grid, Button, MenuItem, Select, FormControl, InputLabel} from '@mui/material' import {useShow} from '@refinedev/core' import {Show, TextFieldComponent as TextField} from '@refinedev/mui' +import {useEffect, useState} from 'react' +import axios from 'axios' +import {BACKEND_URL, VEHICLE_TYPES} from '../../lib/constants' + +type StationItem = { + id: number + name: string + description: string + [key: string]: string | number +} + +type VehicleItem = { + id: number + tail_number: number + type: number + [key: string]: string | number +} export const RouteShow = () => { const {query} = useShow({}) const {data, isLoading} = query - const record = data?.data + // Station states + const [stations, setStations] = useState([]) + const [linkedStations, setLinkedStations] = useState([]) + const [selectedStationId, setSelectedStationId] = useState('') + const [stationsLoading, setStationsLoading] = useState(true) + + // Vehicle states + const [vehicles, setVehicles] = useState([]) + const [linkedVehicles, setLinkedVehicles] = useState([]) + const [selectedVehicleId, setSelectedVehicleId] = useState('') + const [vehiclesLoading, setVehiclesLoading] = useState(true) + + useEffect(() => { + if (record?.id) { + axios + .get(`${BACKEND_URL}/route/${record.id}/station`) + .then((response) => { + setLinkedStations(response?.data || []) + }) + .catch(() => { + setLinkedStations([]) + }) + } + }, [record?.id]) + + useEffect(() => { + axios + .get(`${BACKEND_URL}/station/`) + .then((response) => { + setStations(response?.data || []) + setStationsLoading(false) + }) + .catch(() => { + setStations([]) + setStationsLoading(false) + }) + }, []) + + const availableStations = stations.filter((station) => !linkedStations.some((linked) => linked.id === station.id)) + + const linkStation = () => { + if (selectedStationId) { + axios + .post( + `${BACKEND_URL}/route/${record?.id}/station`, + {station_id: selectedStationId}, + { + headers: { + accept: 'application/json', + 'Content-Type': 'application/json', + }, + }, + ) + .then(() => { + axios + .get(`${BACKEND_URL}/route/${record?.id}/station`) + .then((response) => { + setLinkedStations(response?.data || []) + }) + .catch(() => { + setLinkedStations([]) + }) + }) + .catch((error) => { + console.error('Error linking station:', error) + }) + } + } + + const deleteStation = (stationId: number) => { + axios + .delete(`${BACKEND_URL}/route/${record?.id}/station`, { + data: {station_id: stationId}, + }) + .then(() => { + setLinkedStations((prevStations) => prevStations.filter((item) => item.id !== stationId)) + }) + .catch((error) => { + console.error('Error deleting station:', error) + }) + } + + // Vehicle effects + useEffect(() => { + if (record?.id) { + axios + .get(`${BACKEND_URL}/route/${record.id}/vehicle`) + .then((response) => { + setLinkedVehicles(response?.data || []) + }) + .catch(() => { + setLinkedVehicles([]) + }) + } + }, [record?.id]) + + useEffect(() => { + axios + .get(`${BACKEND_URL}/vehicle/`) + .then((response) => { + setVehicles(response?.data || []) + setVehiclesLoading(false) + }) + .catch(() => { + setVehicles([]) + setVehiclesLoading(false) + }) + }, []) + + const availableVehicles = vehicles.filter((vehicle) => !linkedVehicles.some((linked) => linked.id === vehicle.id)) + + const linkVehicle = () => { + if (selectedVehicleId) { + axios + .post( + `${BACKEND_URL}/route/${record?.id}/vehicle`, + {vehicle_id: selectedVehicleId}, + { + headers: { + accept: 'application/json', + 'Content-Type': 'application/json', + }, + }, + ) + .then(() => { + axios + .get(`${BACKEND_URL}/route/${record?.id}/vehicle`) + .then((response) => { + setLinkedVehicles(response?.data || []) + }) + .catch(() => { + setLinkedVehicles([]) + }) + }) + .catch((error) => { + console.error('Error linking vehicle:', error) + }) + } + } + + const deleteVehicle = (vehicleId: number) => { + axios + .delete(`${BACKEND_URL}/route/${record?.id}/vehicle`, { + data: {vehicle_id: vehicleId}, + }) + .then(() => { + setLinkedVehicles((prevVehicles) => prevVehicles.filter((item) => item.id !== vehicleId)) + }) + .catch((error) => { + console.error('Error deleting vehicle:', error) + }) + } + const fields = [ - // {label: 'ID', data: 'id'}, - // {label: 'ID перевозчика', data: 'carrier_id'}, {label: 'Перевозчик', data: 'carrier'}, {label: 'Номер маршрута', data: 'route_number'}, - {label: 'Путь', data: 'path'}, // # + {label: 'Путь', data: 'path'}, + ] + + const stationFields: Array<{label: string; data: keyof StationItem}> = [ + {label: 'Название', data: 'name'}, + {label: 'Описание', data: 'description'}, + ] + + const vehicleFields: Array<{label: string; data: keyof VehicleItem}> = [ + {label: 'Бортовой номер', data: 'tail_number'}, + {label: 'Тип', data: 'type'}, ] return ( @@ -28,11 +205,122 @@ export const RouteShow = () => { ))} - + - Направление маршрута + Привязанные станции - + + + {stationsLoading ? ( + Загрузка станций... + ) : linkedStations.length > 0 ? ( + linkedStations.map((station, index) => ( + `2px solid ${theme.palette.divider}`, + }} + > + + {stationFields.map(({label, data}) => ( + + {label}: {station[data]} + + ))} + + + + + )) + ) : ( + Станции не найдены + )} + + + + + Привязать станцию + + + + Станция + + + + + + + + + + Привязанные транспортные средства + + + + {vehiclesLoading ? ( + Загрузка транспорта... + ) : linkedVehicles.length > 0 ? ( + linkedVehicles.map((vehicle, index) => ( + `2px solid ${theme.palette.divider}`, + }} + > + + {vehicleFields.map(({label, data}) => ( + + {label}: {vehicle[data]} + + ))} + + + + + )) + ) : ( + Транспортные средства не найдены + )} + + + + + Привязать транспортное средство + + + + Транспортное средство + + + + +