-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from Marija-Kov/refactor-usegetdepartures
- Loading branch information
Showing
9 changed files
with
218 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
src/hooks/useFetchData.tsx → src/hooks/useFetchData/useFetchData.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { ResultDeparture, Input } from "../../typeDefinitions/types"; | ||
import useFetchData from "../useFetchData/useFetchData"; | ||
import { | ||
frequencyOnDate, | ||
stationIndex, | ||
filterDepartures, | ||
timeToNumber, | ||
direction, | ||
transformToReturnFormat, | ||
getResult, | ||
} from "./utils"; | ||
|
||
const useGetDepartures = () => { | ||
const { fetchData } = useFetchData(); | ||
|
||
const getDepartures = async ( | ||
input: Input | ||
): Promise<ResultDeparture[] | string> => { | ||
if (!input.from || !input.to || !input.date || !input.time) | ||
return "All fields must be filled"; | ||
|
||
if (input.from === input.to) return "That is not a route"; | ||
|
||
const data = await fetchData(); | ||
const stations = data.stations; | ||
const frequency = frequencyOnDate(input.date, data.holidays); | ||
const indexFrom = stationIndex(stations, input.from); | ||
const indexTo = stationIndex(stations, input.to); | ||
|
||
const possibleDepartures = filterDepartures( | ||
stations[indexFrom].departures, | ||
timeToNumber(input.time), | ||
direction(indexFrom, indexTo), | ||
frequency | ||
); | ||
|
||
if (!possibleDepartures.length) return "no departures"; | ||
|
||
const possibleDeparturesEnriched = transformToReturnFormat( | ||
possibleDepartures, | ||
stations, | ||
indexFrom, | ||
indexTo | ||
); | ||
|
||
const possibleArrivals = filterDepartures( | ||
stations[indexTo].departures, | ||
timeToNumber(input.time), | ||
direction(indexFrom, indexTo), | ||
frequency | ||
); | ||
|
||
return getResult(possibleDeparturesEnriched, possibleArrivals); | ||
}; | ||
|
||
return { getDepartures }; | ||
}; | ||
|
||
export default useGetDepartures; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { StationName } from "../../typeDefinitions/boringTypes"; | ||
import { | ||
ResultDeparture, | ||
StationDetailsDeparture, | ||
StationDetails, | ||
Time, | ||
YyyyMmDd, | ||
} from "../../typeDefinitions/types"; | ||
|
||
/** | ||
* Creates an array out of departure objects with found arrival matches; filters out the undefined. | ||
* @returns An array of departures with all the necessary response information. | ||
*/ | ||
export function getResult( | ||
possibleDepartures: ResultDeparture[], | ||
possibleArrivals: StationDetailsDeparture[] | ||
) { | ||
const result: ResultDeparture[] = []; | ||
for (let departure of possibleDepartures) { | ||
result.push(matchADepartureWithAnArrival(departure, possibleArrivals)); | ||
} | ||
return result.filter((r) => r !== undefined); | ||
} | ||
|
||
/** | ||
* Finds departure-arrival pairs among pre-filtered departures (which are also enriched) | ||
* and arrivals based on matching trainIds. | ||
* When a match is found, real arrival time is written to the enriched departure object. | ||
* @returns A departure object with all the necessary response information or undefined. | ||
*/ | ||
function matchADepartureWithAnArrival( | ||
departure: ResultDeparture, | ||
possibleArrivals: StationDetailsDeparture[] | ||
) { | ||
const matchingArrival = possibleArrivals.filter( | ||
(arrival: StationDetailsDeparture) => | ||
arrival.trainDetails.id === departure.trainId | ||
)[0]; | ||
return matchingArrival && writeArrivalTime(departure, matchingArrival); | ||
} | ||
|
||
/** | ||
* Writes actual arrival time over arrival time placeholder in an enriched departure object. | ||
* @returns A departure with a matching arrival time. | ||
*/ | ||
function writeArrivalTime( | ||
departure: ResultDeparture, | ||
arrival: StationDetailsDeparture | ||
) { | ||
departure.arrivalTime = timeToString(arrival.time); | ||
return departure; | ||
} | ||
|
||
/** | ||
* Transforms departure objects (adds properties) into format that would be found in the final result. | ||
* Sets a placeholder for arrival time. | ||
* @returns Array of enriched departure objects. | ||
*/ | ||
export function transformToReturnFormat( | ||
departures: StationDetailsDeparture[], | ||
stations: StationDetails[], | ||
departureStationIndex: number, | ||
arrivalStationIndex: number | ||
) { | ||
return departures.map((departure: StationDetailsDeparture) => { | ||
return { | ||
departureTime: timeToString(departure.time), | ||
arrivalTime: "0:10", // placeholder | ||
trainId: departure.trainDetails.id, | ||
from: formatName(stations, departureStationIndex), | ||
to: formatName(stations, arrivalStationIndex), | ||
} as ResultDeparture; | ||
}); | ||
} | ||
|
||
/** | ||
* Filters departures/arrivals at a station based on input time, inferred direction and frequency. | ||
* @returns Narrowed down selection of departures that are to be processed further. | ||
*/ | ||
export function filterDepartures( | ||
departures: StationDetailsDeparture[], | ||
time: number, | ||
direction: 1 | 2, | ||
frequency: (boolean | string)[] | ||
) { | ||
return departures.filter((departure: StationDetailsDeparture) => { | ||
return ( | ||
departure.time >= time && | ||
departure.trainDetails.directionId === direction && | ||
frequency.includes(departure.trainDetails.activeOnWeekendsAndHolidays) | ||
); | ||
}); | ||
} | ||
|
||
/** | ||
* Converts a number into a time string. | ||
*/ | ||
function timeToString(time: number) { | ||
return time.toFixed(2).split(".").join(":") as Time; | ||
} | ||
|
||
/** | ||
* Converts time string into a number. | ||
*/ | ||
export function timeToNumber(time: Time) { | ||
return Number(time.split(":").join(".")); | ||
} | ||
|
||
/** | ||
* @returns An array with 2 values of booleans or 1 boolean and 1 string denoting | ||
* whether a train is active every day (true), Monday to Friday only (false) | ||
* or weekends and holidays only ("w&h_only"); | ||
* They serve as departure filtering criteria. | ||
*/ | ||
export function frequencyOnDate(date: YyyyMmDd, holidays: YyyyMmDd[]) { | ||
const day = new Date(date).getDay(); | ||
return day === 0 || day === 6 || holidays.includes(date) | ||
? [true, "w&h_only"] | ||
: [true, false]; | ||
} | ||
|
||
/** | ||
* @returns Index of station in the list of stations (starting with Batajnica, ending with Ovca). | ||
*/ | ||
export function stationIndex( | ||
stations: StationDetails[], | ||
endpoint: StationName | ||
) { | ||
return stations | ||
.filter((station: StationDetails) => station.name === endpoint) | ||
.map((station: StationDetails) => stations.indexOf(station))[0]; | ||
} | ||
|
||
/** | ||
* @returns A station name with correct spacing and capitalization. | ||
*/ | ||
function formatName(stations: StationDetails[], stationIndex: number) { | ||
return stations[stationIndex].nameFormatted; | ||
} | ||
|
||
/** | ||
* Calculates direction based on departure and arrival station index. | ||
* @returns Number 1 or 2. | ||
*/ | ||
export function direction( | ||
departureStationIndex: number, | ||
arrivalStationIndex: number | ||
) { | ||
return departureStationIndex > arrivalStationIndex ? 2 : 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters