show quantity and last updated in food item list

the backend is now returning quantity data merged into the food item record, so this is an easy UI update to surface it from the REST response
This commit is contained in:
Bart Akeley 2017-11-19 12:22:09 -06:00
parent 38d25a4f5b
commit f9832afb2e
9 changed files with 75 additions and 51 deletions

View file

@ -19,6 +19,7 @@ export type RawFoodItem = {
latitude: number,
longitude: number,
distance: number,
lastupdated: number,
};
export type FoodItemsForLocation = {

View file

@ -53,6 +53,7 @@ const FilterModal = (props: Props) => {
value={isChecked ? 0 : 1}
checked={isChecked}
onCheck={toggleCategory(category, isChecked)}
label=""
/>
</View>
</View>

View file

@ -7,37 +7,33 @@ import typeof PlaceRecord from '../records/PlaceRecord';
import theme from '../ui-theme';
import { Link } from 'react-router-native';
import { routeWithTitle } from '../helpers/RouteHelpers';
import { TileBox, StrongText, SubText, Thumbnail } from './ItemTile';
import { TileBox, StrongText, SubText, Thumbnail, QuantityLine } from './ItemTile';
import { withPlace } from '../enhancers/placeEnhancers';
const PlaceNameAndDistance = withPlace(({ place = {}, distance = 999.9 }: { place: PlaceRecord, distance: number }) => {
return <SubText>{`${place.name || 'Loading...'} - ${parseFloat(distance).toFixed(1)} mi`}</SubText>;
});
export default pure(
({ foodItem }: { foodItem: FoodItemRecord }) => {
if (!foodItem) {
return <View />;
}
return (
<Link
to={routeWithTitle(`/foodItem/${foodItem.id || ''}`, foodItem.name)}
underlayColor={theme.itemTile.pressHighlightColor}
>
<View>
<TileBox>
<Thumbnail thumb={foodItem.thumbImage} />
<View style={{ paddingTop: 15 }}>
<StrongText>{foodItem.name || ''}</StrongText>
<PlaceNameAndDistance
placeId={foodItem.placeId}
distance={foodItem.distance}
/>
</View>
</TileBox>
</View>
</Link>
);
export default pure(({ foodItem }: { foodItem: FoodItemRecord }) => {
if (!foodItem) {
return <View />;
}
);
return (
<Link
to={routeWithTitle(`/foodItem/${foodItem.id || ''}`, foodItem.name)}
underlayColor={theme.itemTile.pressHighlightColor}
>
<View>
<TileBox>
<Thumbnail thumb={foodItem.thumbImage} />
<View>
<StrongText>{foodItem.name || ''}</StrongText>
<PlaceNameAndDistance placeId={foodItem.placeId} distance={foodItem.distance} />
<QuantityLine quantity={foodItem.quantity} lastupdated={foodItem.lastupdated} />
</View>
</TileBox>
</View>
</Link>
);
});

View file

@ -2,8 +2,15 @@
import React from 'react';
import { Text, View, Image } from 'react-native';
import theme from '../ui-theme';
import { getQuantityLabelText } from '../helpers/QuantityHelpers';
import moment from 'moment';
import type { Quantity } from '../constants/QuantityConstants';
export const Thumbnail = ({ thumb }: { thumb: ?string }) =>
const getRelativeDateText = (lastupdated: ?number) => {
return lastupdated ? ` - ${moment(lastupdated).fromNow()}` : '';
};
export const Thumbnail = ({ thumb }: { thumb: ?string }) => (
<View
style={{
height: theme.itemTile.thumbnailSize,
@ -13,7 +20,7 @@ export const Thumbnail = ({ thumb }: { thumb: ?string }) =>
margin: 10,
}}
>
{!!thumb &&
{!!thumb && (
<Image
style={{
height: theme.itemTile.thumbnailSize,
@ -21,26 +28,28 @@ export const Thumbnail = ({ thumb }: { thumb: ?string }) =>
borderRadius: Math.round(theme.itemTile.thumbnailSize / 2),
}}
source={{ uri: thumb }}
/>}
</View>;
/>
)}
</View>
);
export const StrongText = ({ children, style = {} }: { children?: string, style?: Object }) => {
return (
<Text style={{ ...theme.itemTile.itemNameStyle, ...style }}>
{children}
</Text>
);
return <Text style={{ ...theme.itemTile.itemNameStyle, ...style }}>{children}</Text>;
};
export const SubText = ({ children, style = {} }: { children?: string, style?: Object }) => {
return (
<Text style={{ ...theme.itemTile.itemPlaceStyle, ...style }}>
{children}
</Text>
);
return <Text style={{ ...theme.itemTile.itemPlaceStyle, ...style }}>{children}</Text>;
};
export const TileBox = ({ children, style = {} }: { children?: any, style?: Object }) =>
<View style={{ height: 70, flexDirection: 'row', backgroundColor: 'white', ...style }}>
export const TileBox = ({ children, style = {} }: { children?: any, style?: Object }) => (
<View style={{ height: 70, flexDirection: 'row', backgroundColor: 'white', alignItems: 'center', ...style }}>
{children}
</View>;
</View>
);
export const QuantityLine = ({ quantity, lastupdated }: { quantity: Quantity, lastupdated: ?number }) => (
<SubText>
{getQuantityLabelText(quantity)}
{getRelativeDateText(lastupdated)}
</SubText>
);

View file

@ -1,6 +1,6 @@
// @flow
import React from 'react';
import { getQuantityText } from '../helpers/QuantityHelpers';
import { getQuantityDropdownText } from '../helpers/QuantityHelpers';
import { Picker, View } from 'react-native';
import theme from '../ui-theme';
import { pure } from 'recompose';
@ -16,7 +16,7 @@ const getItemColor = (selected, current) => (selected === current ? selectedColo
const renderQuantityItem = (selectedQuantity: Quantity) => (quantity: Quantity) => (
<Picker.Item
key={quantity}
label={getQuantityText(quantity)}
label={getQuantityDropdownText(quantity)}
value={quantity}
color={getItemColor(selectedQuantity, quantity)}
/>

View file

@ -1,15 +1,25 @@
// @flow
import { type Quantity } from '../constants/QuantityConstants';
export const getQuantityText = (quantity: Quantity) => {
const quantityLabels: { [Quantity]: string } = {
none: 'None left',
few: 'A few left',
lots: 'A lot left',
many: 'Plenty left',
};
export const getQuantityLabelText = (quantity: Quantity) => quantityLabels[quantity] || quantityLabels['many'];
export const getQuantityDropdownText = (quantity: Quantity) => {
const label = quantityLabels[quantity];
switch (quantity) {
case 'none':
return 'None left - 0';
return `${label} - 0`;
case 'few':
return 'A few left - 6 or fewer';
return `${label} - 6 or fewer`;
case 'lots':
return 'A lot Left - 10 or fewer';
return `${label} - 10 or fewer`;
default:
return 'Plenty left - more than 10';
return `${label} - more than 10`;
}
};

View file

@ -16,6 +16,7 @@ export type FoodItem = {
images: List<string>,
thumbImage: ?string,
titleImage: ?string,
lastupdated: number,
};
const FoodRecordDefaults: FoodItem = {
@ -30,6 +31,7 @@ const FoodRecordDefaults: FoodItem = {
images: new List(),
thumbImage: '',
titleImage: '',
lastupdated: 0,
};
const FoodItemRecord = Record(FoodRecordDefaults, 'FoodItemRecord');

View file

@ -11,6 +11,7 @@
"dependencies": {
"babel-preset-es2015": "^6.24.0",
"immutable": "^3.8.1",
"moment": "^2.19.2",
"ramda": "^0.24.1",
"react": "~15.4.1",
"react-native": "~0.42.0",

View file

@ -3208,6 +3208,10 @@ moment@2.x.x:
version "2.18.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f"
moment@^2.19.2:
version "2.19.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.2.tgz#8a7f774c95a64550b4c7ebd496683908f9419dbe"
morgan@~1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.6.1.tgz#5fd818398c6819cba28a7cd6664f292fe1c0bbf2"