mirror of
https://github.com/HSLdevcom/digitransit-ui
synced 2025-09-21 05:02:45 +02:00
149 lines
4.5 KiB
JavaScript
149 lines
4.5 KiB
JavaScript
import PropTypes from 'prop-types';
|
|
import React, { useState, useEffect } from 'react';
|
|
import { createFragmentContainer, graphql } from 'react-relay';
|
|
import connectToStores from 'fluxible-addons-react/connectToStores';
|
|
import { FormattedMessage } from 'react-intl';
|
|
import { routerShape, RedirectException } from 'found';
|
|
|
|
import CityBikeStopContent from './CityBikeStopContent';
|
|
import ParkOrStationHeader from './ParkOrStationHeader';
|
|
import Icon from './Icon';
|
|
import withBreakpoint from '../util/withBreakpoint';
|
|
import { getCityBikeNetworkConfig } from '../util/citybikes';
|
|
import { isBrowser } from '../util/browser';
|
|
import { PREFIX_BIKESTATIONS } from '../util/path';
|
|
|
|
const BikeRentalStationContent = (
|
|
{ bikeRentalStation, breakpoint, language, router, error },
|
|
{ config },
|
|
) => {
|
|
const [isClient, setClient] = useState(false);
|
|
useEffect(() => {
|
|
// To prevent SSR from rendering something https://reactjs.org/docs/react-dom.html#hydrate
|
|
setClient(true);
|
|
});
|
|
|
|
// throw error in client side relay query fails
|
|
if (isClient && error && !bikeRentalStation) {
|
|
throw error.message;
|
|
}
|
|
|
|
if (!bikeRentalStation && !error) {
|
|
if (isBrowser) {
|
|
router.replace(`/${PREFIX_BIKESTATIONS}`);
|
|
} else {
|
|
throw new RedirectException(`/${PREFIX_BIKESTATIONS}`);
|
|
}
|
|
return null;
|
|
}
|
|
const { bikesAvailable, capacity } = bikeRentalStation;
|
|
const isFull = bikesAvailable >= capacity;
|
|
|
|
const networkConfig = getCityBikeNetworkConfig(
|
|
bikeRentalStation.networks[0],
|
|
config,
|
|
);
|
|
const cityBikeNetworkUrl = networkConfig?.url?.[language];
|
|
let returnInstructionsUrl;
|
|
if (networkConfig.returnInstructions) {
|
|
returnInstructionsUrl = networkConfig.returnInstructions[language];
|
|
}
|
|
const { cityBike } = config;
|
|
const cityBikeBuyUrl = cityBike.buyUrl?.[language];
|
|
const buyInstructions = cityBikeBuyUrl
|
|
? cityBike.buyInstructions?.[language]
|
|
: undefined;
|
|
|
|
return (
|
|
<div className="bike-station-page-container">
|
|
<ParkOrStationHeader
|
|
parkOrStation={bikeRentalStation}
|
|
breakpoint={breakpoint}
|
|
/>
|
|
<CityBikeStopContent bikeRentalStation={bikeRentalStation} />
|
|
{cityBike.showFullInfo && isFull && (
|
|
<div className="citybike-full-station-guide">
|
|
<FormattedMessage id="citybike-return-full" />
|
|
<a
|
|
onClick={e => {
|
|
e.stopPropagation();
|
|
}}
|
|
className="external-link-citybike"
|
|
href={returnInstructionsUrl}
|
|
>
|
|
{' '}
|
|
<FormattedMessage id="citybike-return-full-link" />{' '}
|
|
</a>
|
|
</div>
|
|
)}
|
|
{(cityBikeBuyUrl || cityBikeNetworkUrl) && (
|
|
<div className="citybike-use-disclaimer">
|
|
<h2 className="disclaimer-header">
|
|
<FormattedMessage id="citybike-start-using" />
|
|
</h2>
|
|
<div className="disclaimer-content">
|
|
{buyInstructions || (
|
|
<a className="external-link-citybike" href={cityBikeNetworkUrl}>
|
|
<FormattedMessage id="citybike-start-using-info" />{' '}
|
|
</a>
|
|
)}
|
|
</div>
|
|
{isClient && cityBikeBuyUrl && (
|
|
<a
|
|
onClick={e => {
|
|
e.stopPropagation();
|
|
}}
|
|
className="external-link"
|
|
href={cityBikeBuyUrl}
|
|
>
|
|
<FormattedMessage id="citybike-purchase-link" />
|
|
<Icon img="icon-icon_external-link-box" />
|
|
</a>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
BikeRentalStationContent.propTypes = {
|
|
bikeRentalStation: PropTypes.any,
|
|
breakpoint: PropTypes.string.isRequired,
|
|
language: PropTypes.string.isRequired,
|
|
router: routerShape.isRequired,
|
|
error: PropTypes.object,
|
|
};
|
|
BikeRentalStationContent.contextTypes = {
|
|
config: PropTypes.object.isRequired,
|
|
};
|
|
const BikeRentalStationContentWithBreakpoint = withBreakpoint(
|
|
BikeRentalStationContent,
|
|
);
|
|
|
|
const connectedComponent = connectToStores(
|
|
BikeRentalStationContentWithBreakpoint,
|
|
['PreferencesStore'],
|
|
context => ({
|
|
language: context.getStore('PreferencesStore').getLanguage(),
|
|
}),
|
|
);
|
|
|
|
const containerComponent = createFragmentContainer(connectedComponent, {
|
|
bikeRentalStation: graphql`
|
|
fragment BikeRentalStationContent_bikeRentalStation on BikeRentalStation {
|
|
lat
|
|
lon
|
|
name
|
|
spacesAvailable
|
|
bikesAvailable
|
|
capacity
|
|
networks
|
|
stationId
|
|
state
|
|
}
|
|
`,
|
|
});
|
|
|
|
export {
|
|
containerComponent as default,
|
|
BikeRentalStationContentWithBreakpoint as Component,
|
|
};
|