import {motion} from 'framer-motion'; import React, {useEffect, useState} from 'react'; import ProgressIndicator from "./ProgressIndicator"; import classNames from "../../../util/classNames"; const PlanElement = (props: { tripId: string, trainIdentifier: string, trainHeading: string, stops: { name: string, arrival: Date, delay?: number, cancelled: boolean }[] }) => { const [shown, setShown] = useState<boolean>(true); useEffect(() => { const update = () => { const latestStop = props.stops.reduce((accu, curr) => { if (curr.arrival >= accu) { return curr.arrival; } return accu; }, new Date(0)); if ((new Date()).getTime() <= latestStop.getTime()) { setShown(true); } else { setShown(false); } }; update(); const updateInterval = setInterval(update, 1000); return () => { clearInterval(updateInterval); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( <motion.div className={"overflow-hidden"} initial={{ opacity: 1, translateY: "0%", marginTop: "0rem" }} animate={shown ? { opacity: 1, translateY: "0%", marginTop: "0rem" } : { opacity: 0, translateY: "-100%", height: 0, marginTop: "-0.75rem" }} transition={{ duration: .5, ease: "easeOut", staggerChildren: .3 }} > <div className={"flex flex-row gap-4 items-center font-semibold"}> <div className={classNames( "flex justify-center items-center text-lg h-10 w-20 leading-none", trainIdentifierToColor(props.trainIdentifier) )}> {props.trainIdentifier} </div> <h3 className={"text-xl leading-9"}> {deDortmund(props.trainHeading)} </h3> </div> <motion.ol role="list" className="overflow-hidden" aria-hidden="true"> { props.stops.map((stop, index) => ( <ProgressIndicator key={stop.name} first={index === 0} id={stop.name} name={deDortmund(stop.name)} arrival={stop.arrival} delay={stop.delay} cancelled={stop.cancelled} /> )) } </motion.ol> </motion.div> ); }; export default PlanElement; const trainIdentifierToColor = (identifier: string): string => { if (identifier.startsWith("S")) { return "bg-green-700"; } if (identifier.startsWith("X")) { return "bg-pink-700"; } // Fixme: This should just be "if first is number" if (identifier.startsWith("4")) { return "bg-sky-700"; } return "bg-zinc-700"; } const deDortmund = (input: string): string => { // Don't remove the city from central station location if (input.includes("Hbf")) { return input; } return input // In all other cases, remove dortmund .replaceAll("Dortmund/Joseph Fraunhofer", "Joseph-von-Fraunhofer") // Special case: Because the API is dumb, translate JvF to be consistent .replaceAll("Dortmund ", ""); }