trainvel/sncf-station/src/TrainsTable.js

236 lines
7.0 KiB
JavaScript
Raw Normal View History

2024-01-29 00:33:42 +00:00
import {useEffect, useState} from "react"
2024-01-28 22:17:32 +00:00
import {
Box,
styled,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography
2024-01-29 00:33:42 +00:00
} from "@mui/material"
import {CSSTransition, TransitionGroup} from 'react-transition-group'
2024-01-28 22:17:32 +00:00
const StyledTableRow = styled(TableRow)(({ theme, tableType }) => ({
'tbody &:nth-of-type(odd)': {
backgroundColor: theme.palette.sncf[tableType].light,
},
'th, &:nth-of-type(even)': {
backgroundColor: theme.palette.sncf[tableType].dark,
},
// hide last border
'&:last-child td, &:last-child th': {
border: 0,
},
}));
2024-01-28 19:06:55 +00:00
2024-01-28 19:48:44 +00:00
function TrainsTable({stop, date, time, tableType}) {
2024-01-28 19:06:55 +00:00
return <>
2024-01-28 22:17:32 +00:00
<TableContainer>
<Table>
<TrainsTableHeader tableType={tableType} />
<TrainsTableBody stop={stop} date={date} time={time} tableType={tableType} />
</Table>
</TableContainer>
2024-01-28 19:06:55 +00:00
</>
}
2024-01-28 22:17:32 +00:00
function TrainsTableHeader({tableType}) {
return <>
<TableHead>
<StyledTableRow tableType={tableType}>
<TableCell colSpan="2" fontSize={16} fontWeight="bold">Train</TableCell>
<TableCell fontSize={16} fontWeight="bold">Heure</TableCell>
<TableCell fontSize={16} fontWeight="bold">Destination</TableCell>
</StyledTableRow>
</TableHead>
</>
2024-01-28 19:06:55 +00:00
}
2024-01-28 19:48:44 +00:00
function TrainsTableBody({stop, date, time, tableType}) {
2024-01-28 19:06:55 +00:00
const [trains, setTrains] = useState([])
useEffect(() => {
if (stop.id !== undefined) {
2024-01-29 21:17:18 +00:00
let validTrains = trains.filter(train => {
if (tableType === "departures")
return `${train.departure_date}T${train.departure_time_24h}` >= `${date}T${time}`
else
return `${train.arrival_date}T${train.arrival_time_24h}` >= `${date}T${time}`
})
if (trains.length > 0 && validTrains.length === trains.length)
return
console.log(`${trains.length - validTrains.length} trains deleted`)
fetch(`http://localhost:8000/api/station/next_${tableType}/?stop_id=${stop.id}&date=${date}&time=${time}&offset=${validTrains.length}&limit=${20 - validTrains.length}`)
2024-01-28 19:06:55 +00:00
.then(response => response.json())
.then(data => data.results)
.then(data => {
2024-01-29 21:17:18 +00:00
setTrains(trains => [...validTrains, ...data])
2024-01-28 19:06:55 +00:00
})
}
2024-01-28 19:48:44 +00:00
}, [stop, tableType, date, time])
2024-01-28 19:06:55 +00:00
2024-01-29 00:33:42 +00:00
let table_rows = trains.map((train) => <CSSTransition key={train.id} timeout={500} classNames="shrink">
<TrainRow train={train} tableType={tableType} />
</CSSTransition>)
2024-01-28 19:06:55 +00:00
2024-01-29 00:33:42 +00:00
return <>
<TableBody>
<TransitionGroup component={null}>
{table_rows}
</TransitionGroup>
</TableBody>
</>
2024-01-28 19:06:55 +00:00
}
function TrainRow({train, tableType}) {
const [trip, setTrip] = useState({})
const [route, setRoute] = useState({})
const [stopTimes, setStopTimes] = useState([])
const [trainType, setTrainType] = useState("")
useEffect(() => {
if (train.trip !== undefined) {
fetch(`http://localhost:8000/api/gtfs/trip/${train.trip}/`)
.then(response => response.json())
.then(t => {
t.stop_times = []
setTrip(t)
})
}
}, [train.trip])
useEffect(() => {
if (trip.route !== undefined) {
fetch(`http://localhost:8000/api/gtfs/route/${trip.route}/`)
.then(response => response.json())
.then(data => {
setRoute(data)
})
}
}, [trip.route])
useEffect(() => {
if (route !== undefined) {
setTrainType(getTrainType(train, route))
}
}, [train, route]);
useEffect(() => {
if (trip.route !== undefined) {
fetch(`http://localhost:8000/api/gtfs/stop_time/?trip=${trip.id}&order=stop_sequence&limit=1000`)
.then(response => response.json())
.then(data => data.results)
.then(stop_times => {
Promise.all(stop_times.map(stop_time =>
fetch(`http://localhost:8000/api/gtfs/stop/${stop_time.stop}/`).then(response => response.json())
)).then(stops => {
setStopTimes(stop_times.map((stop_time, index) => {
stop_time.stop = stops[index]
return stop_time
}))
})
})
}
}, [trip.route])
let headline = stopTimes[tableType === "departures" ? stopTimes.length - 1 : 0]?.stop ?? {name: "Chargement…"}
2024-01-28 22:17:32 +00:00
let stops_filter
if (tableType === "departures")
stops_filter = (stop_time) => stop_time.stop_sequence > train.stop_sequence && stop_time.drop_off_type === 0
else
stops_filter = (stop_time) => stop_time.stop_sequence < train.stop_sequence && stop_time.pickup_type === 0
let stops_names = stopTimes.filter(stops_filter).map(stop_time => stop_time?.stop.name ?? "").join(", ")
2024-01-28 19:06:55 +00:00
return <>
2024-01-28 22:17:32 +00:00
<StyledTableRow tableType={tableType}>
<TableCell>
2024-01-28 19:06:55 +00:00
<div>
2024-01-28 22:17:32 +00:00
<Box display="flex"
justifyContent="center"
alignItems="center"
textAlign="center"
width="4em"
height="4em"
borderRadius="15%"
fontWeight="bold"
backgroundColor={`#${getBackgroundColor(train, route)}`}
color={`#${getTextColor(train, route)}`}>
{trainType}
</Box>
2024-01-28 19:06:55 +00:00
</div>
2024-01-28 22:17:32 +00:00
</TableCell>
<TableCell>
<Box display="flex" alignItems="center" justifyContent="center" textAlign="center">
<div>
<div>{trip.short_name}</div>
<div>{trip.headsign}</div>
</div>
</Box>
</TableCell>
<TableCell>
<Box display="flex" alignItems="center" justifyContent="center" fontWeight="bold" color="#FFED02" fontSize={24}>
{getDisplayTime(train, tableType)}
</Box>
</TableCell>
<TableCell>
<Typography fontSize={24} fontWeight="bold">{headline.name}</Typography>
<span className="stops">{stops_names}</span>
</TableCell>
</StyledTableRow>
2024-01-28 19:06:55 +00:00
</>
}
function getTrainType(train, route) {
if (train.id.startsWith("IDFM"))
return route.short_name
else {
let trainType = train.stop.split("StopPoint:OCE")[1].split("-")[0]
if (trainType === "Train TER")
trainType = "TER"
else if (trainType === "INTERCITES")
trainType = "INTER-CITÉS"
else if (trainType === "INTERCITES de nuit")
trainType = "INTER-CITÉS de nuit"
return trainType
}
}
function getBackgroundColor(train, route) {
if (route.color)
return route.color
else if (getTrainType(train, route) === "OUIGO")
return "E60075"
return "FFFFFF"
}
function getTextColor(train, route) {
if (route.text_color)
return route.text_color
else {
let trainType = getTrainType(train, route)
switch (trainType) {
case "OUIGO":
return "FFFFFF"
case "TGV INOUI":
return "9B2743"
case "ICE":
return "B4B4B4"
case "INTER-CITÉS":
case "INTER-CITÉS de nuit":
return "404042"
default:
return "000000"
}
}
}
2024-01-28 19:48:44 +00:00
function getDisplayTime(train, tableType) {
let time = tableType === "departures" ? train.departure_time : train.arrival_time
let day_split = time.split(' ')
return day_split[day_split.length - 1].substring(0, 5)
}
2024-01-28 19:06:55 +00:00
export default TrainsTable;