2024-01-28 23:17:32 +01:00
|
|
|
import {
|
|
|
|
Box,
|
|
|
|
styled,
|
|
|
|
Table,
|
|
|
|
TableBody,
|
|
|
|
TableCell,
|
|
|
|
TableContainer,
|
|
|
|
TableHead,
|
|
|
|
TableRow,
|
|
|
|
Typography
|
2024-01-29 01:33:42 +01:00
|
|
|
} from "@mui/material"
|
|
|
|
import {CSSTransition, TransitionGroup} from 'react-transition-group'
|
2024-02-02 00:50:50 +01:00
|
|
|
import {useQueries, useQuery, useQueryClient} from "@tanstack/react-query";
|
|
|
|
import {useEffect, useState} from "react";
|
2024-01-28 23:17:32 +01: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 20:06:55 +01:00
|
|
|
|
2024-01-28 20:48:44 +01:00
|
|
|
function TrainsTable({stop, date, time, tableType}) {
|
2024-01-28 20:06:55 +01:00
|
|
|
return <>
|
2024-01-28 23:17:32 +01:00
|
|
|
<TableContainer>
|
|
|
|
<Table>
|
|
|
|
<TrainsTableHeader tableType={tableType} />
|
|
|
|
<TrainsTableBody stop={stop} date={date} time={time} tableType={tableType} />
|
|
|
|
</Table>
|
|
|
|
</TableContainer>
|
2024-01-28 20:06:55 +01:00
|
|
|
</>
|
|
|
|
}
|
|
|
|
|
2024-01-28 23:17:32 +01: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 20:06:55 +01:00
|
|
|
}
|
|
|
|
|
2024-01-28 20:48:44 +01:00
|
|
|
function TrainsTableBody({stop, date, time, tableType}) {
|
2024-02-02 00:50:50 +01:00
|
|
|
const queryClient = useQueryClient()
|
|
|
|
|
|
|
|
let filterTime = (train) => {
|
|
|
|
if (train.departure_time === "04:56:00")
|
|
|
|
return false
|
|
|
|
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}`
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateTrains() {
|
|
|
|
return fetch(`http://localhost:8000/api/station/next_${tableType}/?stop_id=${stop.id}&date=${date}&time=${time}&offset=${0}&limit=${20}`)
|
2024-01-28 20:06:55 +01:00
|
|
|
.then(response => response.json())
|
|
|
|
.then(data => data.results)
|
2024-02-02 00:50:50 +01:00
|
|
|
.then(data => [...data])
|
|
|
|
}
|
|
|
|
|
|
|
|
const trainsQuery = useQuery({
|
|
|
|
queryKey: ['trains', stop.id, tableType],
|
|
|
|
queryFn: updateTrains,
|
|
|
|
enabled: !!stop.id,
|
|
|
|
})
|
|
|
|
const trains = trainsQuery.data ?? []
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
let validTrains = trains?.filter(filterTime) ?? []
|
|
|
|
console.log(validTrains.length)
|
|
|
|
if (trains?.length > 0 && validTrains.length <= trains?.length)
|
|
|
|
queryClient.invalidateQueries({queryKey: ['trains', stop.id, tableType]})
|
|
|
|
}, [stop.id, tableType, date, time])
|
2024-01-28 20:06:55 +01:00
|
|
|
|
2024-01-29 01:33:42 +01:00
|
|
|
let table_rows = trains.map((train) => <CSSTransition key={train.id} timeout={500} classNames="shrink">
|
|
|
|
<TrainRow train={train} tableType={tableType} />
|
|
|
|
</CSSTransition>)
|
2024-01-28 20:06:55 +01:00
|
|
|
|
2024-01-29 01:33:42 +01:00
|
|
|
return <>
|
|
|
|
<TableBody>
|
|
|
|
<TransitionGroup component={null}>
|
|
|
|
{table_rows}
|
|
|
|
</TransitionGroup>
|
|
|
|
</TableBody>
|
|
|
|
</>
|
2024-01-28 20:06:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function TrainRow({train, tableType}) {
|
2024-02-02 00:50:50 +01:00
|
|
|
const tripQuery = useQuery({
|
|
|
|
queryKey: ['trip', train.trip],
|
|
|
|
queryFn: () => fetch(`http://localhost:8000/api/gtfs/trip/${train.trip}/`)
|
|
|
|
.then(response => response.json()),
|
|
|
|
enabled: !!train.trip,
|
|
|
|
})
|
|
|
|
const trip = tripQuery.data ?? {}
|
|
|
|
|
|
|
|
const routeQuery = useQuery({
|
|
|
|
queryKey: ['route', trip.route],
|
|
|
|
queryFn: () => fetch(`http://localhost:8000/api/gtfs/route/${trip.route}/`)
|
|
|
|
.then(response => response.json()),
|
|
|
|
enabled: !!trip.route,
|
|
|
|
})
|
|
|
|
const route = routeQuery.data ?? {}
|
|
|
|
const trainType = getTrainType(train, route)
|
|
|
|
|
|
|
|
const stopTimesQuery = useQuery({
|
|
|
|
queryKey: ['stop_times', trip.id],
|
|
|
|
queryFn: () => fetch(`http://localhost:8000/api/gtfs/stop_time/?trip=${trip.id}&order=stop_sequence&limit=1000`)
|
2024-01-28 20:06:55 +01:00
|
|
|
.then(response => response.json())
|
2024-02-02 00:50:50 +01:00
|
|
|
.then(data => data.results),
|
|
|
|
enabled: !!trip.id,
|
|
|
|
})
|
|
|
|
const stopTimes = stopTimesQuery.data ?? []
|
|
|
|
const stopIds = stopTimes.map(stop_time => stop_time.stop)
|
|
|
|
|
|
|
|
const stopQueries = useQueries({
|
|
|
|
queries: stopIds.map(stopId => ({
|
|
|
|
queryKey: ['stop', stopId],
|
|
|
|
queryFn: () => fetch(`http://localhost:8000/api/gtfs/stop/${stopId}/`)
|
|
|
|
.then(response => response.json()),
|
|
|
|
enabled: !!stopId,
|
|
|
|
})),
|
|
|
|
})
|
|
|
|
const stops = stopTimes.map(((stopTime, i) => ({...stopTime, stop: stopQueries[i]?.data ?? {"name": "…"}}))) ?? []
|
|
|
|
|
|
|
|
let headline = stops[tableType === "departures" ? stops.length - 1 : 0]?.stop ?? {name: "Chargement…"}
|
|
|
|
|
|
|
|
let stopsFilter
|
2024-01-28 23:17:32 +01:00
|
|
|
if (tableType === "departures")
|
2024-02-02 00:50:50 +01:00
|
|
|
stopsFilter = (stop_time) => stop_time.stop_sequence > train.stop_sequence && stop_time.drop_off_type === 0
|
2024-01-28 23:17:32 +01:00
|
|
|
else
|
2024-02-02 00:50:50 +01:00
|
|
|
stopsFilter = (stop_time) => stop_time.stop_sequence < train.stop_sequence && stop_time.pickup_type === 0
|
|
|
|
let stopsNames = stops.filter(stopsFilter).map(stopTime => stopTime?.stop.name ?? "").join(", ") ?? ""
|
2024-01-28 20:06:55 +01:00
|
|
|
|
|
|
|
return <>
|
2024-01-28 23:17:32 +01:00
|
|
|
<StyledTableRow tableType={tableType}>
|
|
|
|
<TableCell>
|
2024-01-28 20:06:55 +01:00
|
|
|
<div>
|
2024-01-28 23:17:32 +01: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 20:06:55 +01:00
|
|
|
</div>
|
2024-01-28 23:17:32 +01: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>
|
2024-02-02 00:50:50 +01:00
|
|
|
<Typography fontSize={24} fontWeight="bold" data-stop-id={headline.id}>{headline.name}</Typography>
|
|
|
|
<span className="stops">{stopsNames}</span>
|
2024-01-28 23:17:32 +01:00
|
|
|
</TableCell>
|
|
|
|
</StyledTableRow>
|
2024-01-28 20:06:55 +01: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 20:48:44 +01: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 20:06:55 +01:00
|
|
|
export default TrainsTable;
|