aretherecookies-mobile/js/pages/PlaceDetail.js
2020-04-17 22:50:23 -05:00

143 lines
4 KiB
JavaScript

// @flow
import React from 'react';
import { View, Text, Image, ScrollView } from 'react-native';
import theme, { palette } from '../ui-theme';
import { compose, pure, withState, withHandlers, lifecycle } from 'recompose';
import typeof PlaceRecord from '../records/PlaceRecord';
import { withPlace, withPlaceIdFromRoute, withProductsForPlace } from '../enhancers/placeEnhancers';
import Carousel from 'react-native-looped-carousel';
import CountBadge from '../components/CountBadge';
import { StrongText } from '../components/ItemTile';
import IconButton from '../components/IconButton';
import { type List } from 'immutable';
import typeof ProductRecord from '../records/ProductRecord';
import ProductTile from '../components/ProductTile';
import { openUrl } from '../helpers/linkHelpers';
import { routeWithQuery } from '../helpers/RouteHelpers';
import { Link } from 'react-router-native';
const { placeDetails: style } = theme;
const stretchedStyle = { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 };
const contentTileStyle = {
backgroundColor: 'white',
paddingLeft: 20,
paddingRight: 20,
};
type Props = {
place: ?PlaceRecord,
products: ?List<ProductRecord>,
currentImage: number,
setCurrentImage: (idx: number) => void,
viewOnMap: () => void,
fetchPlaceDetails: (arg: { distance: number, placeId: string }) => Promise<void>,
phoneCall: () => Promise<any>,
};
const PlaceDetail = (props: Props) => {
const { place, products, currentImage, setCurrentImage, viewOnMap, phoneCall } = props;
if (!place) {
return <View />;
}
const { photos } = place;
return (
<View style={{ flex: 1 }}>
<ScrollView style={theme.page.container}>
<View style={{ height: 200, flexGrow: 0 }}>
{photos.size === 1 && <Image style={stretchedStyle} source={{ uri: photos.first() }} />}
{photos.size > 1 && (
<Carousel autoplay={false} onAnimateNextPage={setCurrentImage} style={stretchedStyle}>
{photos.map(uri => (
<Image key={uri} style={{ flex: 1, resizeMode: 'stretch' }} source={{ uri }} />
))}
</Carousel>
)}
<CountBadge currentImage={currentImage + 1} totalCount={photos.size} />
</View>
<View style={{ ...contentTileStyle, marginBottom: 10, padding: 10 }}>
<IconButton
glyph="place"
text={place.address}
onPress={viewOnMap}
color={style.actionIconColor}
textStyle={{ fontSize: 16 }}
/>
</View>
<View
style={{
flexDirection: 'column',
...contentTileStyle,
marginBottom: 10,
paddingTop: 5,
paddingBottom: 10,
}}>
<IconButton glyph="phone" text="Call" onPress={phoneCall} color={style.actionIconColor} />
</View>
<View style={{ padding: 15, ...contentTileStyle }}>
<StrongText>Products</StrongText>
{!!products &&
products.map(product => (
<ProductTile key={product.id} product={product} place={place} />
))}
{!products ||
(!products.size && (
<Link
to={routeWithQuery('/createProduct', {
routeTitle: 'Add a Food Item',
placeId: place.id,
})}>
<Text
style={{
marginTop: 15,
marginBottom: 15,
fontSize: 16,
color: palette.accentColor,
}}>
No products yet, add a new one.
</Text>
</Link>
))}
</View>
</ScrollView>
</View>
);
};
export default compose(
pure,
withPlaceIdFromRoute,
withPlace,
withProductsForPlace,
withState('currentImage', 'setCurrentImage', 0),
withHandlers({
viewOnMap: (props: Props) => () => {
const { place } = props;
if (!place) {
return;
}
const { latitude, longitude } = place;
const url = `geo:${latitude}, ${longitude}`;
openUrl(url);
},
phoneCall: (props: Props) => () => {
if (!props.place || !props.place.phoneNumber) {
return;
}
openUrl(`tel:${props.place.phoneNumber}`);
},
}),
lifecycle({
componentDidMount() {
this.props.fetchPlaceDetails({
distance: this.props.place.distance,
placeId: this.props.place.id,
});
},
})
)(PlaceDetail);