mirror of
https://gitlab.com/wheres-the-tp/ui-mobile.git
synced 2026-01-25 09:54:55 -06:00
show message when no food items found
This commit is contained in:
parent
a2206a00bf
commit
a7f9a5bae9
5 changed files with 80 additions and 47 deletions
|
|
@ -15,7 +15,7 @@ type homomorph<T> = T => T;
|
|||
type Props = {
|
||||
filter: FilterRecord,
|
||||
foodItemsSeq: SetSeq<FoodItemRecord>,
|
||||
renderFoodItem: (foodItem: typeof FoodItemRecord) => Component<*, *, *>,
|
||||
children: (foodItem: FoodItemRecord) => Component<*, *, *>,
|
||||
};
|
||||
|
||||
const sortByDistance = (foodItemsSeq: SetSeq<FoodItemRecord>): SetSeq<FoodItemRecord> => {
|
||||
|
|
@ -48,7 +48,7 @@ const intoArray = (foodItemsSeq: SetSeq<FoodItemRecord>): Array<FoodItemRecord>
|
|||
foodItemsSeq ? foodItemsSeq.toArray() : [];
|
||||
|
||||
const FoodItemList = (props: Props) => {
|
||||
const { filter, foodItemsSeq, renderFoodItem } = props;
|
||||
const { filter, foodItemsSeq, children } = props;
|
||||
|
||||
if (!foodItemsSeq) {
|
||||
return null;
|
||||
|
|
@ -59,7 +59,7 @@ const FoodItemList = (props: Props) => {
|
|||
intoArray
|
||||
)(foodItemsSeq);
|
||||
|
||||
return <View style={{ flexShrink: 2 }}>{items.map(renderFoodItem)}</View>;
|
||||
return <View style={{ flexShrink: 2 }}>{items.map(children)}</View>;
|
||||
};
|
||||
|
||||
export default compose(
|
||||
|
|
|
|||
23
js/components/FullScreenMessage.js
Normal file
23
js/components/FullScreenMessage.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
|
||||
const FullScreenMessage = ({ children }: { children?: any }) => {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
height: '50%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}>
|
||||
{children}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default FullScreenMessage;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import mapPropsStream from 'recompose/mapPropsStream';
|
||||
import Filter$, { emitter } from '../streams/FilterStream';
|
||||
import Filter$, { emitter, initialFilter } from '../streams/FilterStream';
|
||||
|
||||
export const withFilter = mapPropsStream(props$ => {
|
||||
return props$.combineLatest(Filter$, (props, filter) => {
|
||||
|
|
@ -8,6 +8,7 @@ export const withFilter = mapPropsStream(props$ => {
|
|||
...props,
|
||||
filter,
|
||||
setFilter: emitter,
|
||||
isFilterDirty: initialFilter !== filter,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import { View, ScrollView, RefreshControl } from 'react-native';
|
||||
import React from 'react';
|
||||
import { View, Text, ScrollView, RefreshControl } from 'react-native';
|
||||
import FoodItemTile from '../components/FoodItemTile';
|
||||
import FoodItemList from '../components/FoodItemList';
|
||||
import typeof FoodItemRecord from '../records/FoodItemRecord';
|
||||
|
|
@ -8,59 +8,66 @@ import FilterModal from '../modals/FilterModal';
|
|||
import { withFoodItemsAsSeq } from '../enhancers/foodItemEnhancers';
|
||||
import { type SetSeq } from 'immutable';
|
||||
import { compose, pure, withState, withHandlers } from 'recompose';
|
||||
import { type RoutingContextFlowTypes } from '../routes';
|
||||
import ActionsButton from '../components/ActionsButton';
|
||||
import { withFilter } from '../enhancers/filterEnhancers';
|
||||
import { withRouterContext } from '../enhancers/routeEnhancers';
|
||||
import FullScreenMessage from '../components/FullScreenMessage';
|
||||
|
||||
const renderFoodItem = (foodItem: FoodItemRecord) => (
|
||||
<FoodItemTile key={foodItem.id} foodItem={foodItem} />
|
||||
);
|
||||
type Props = {
|
||||
isFilterModalOpen: boolean,
|
||||
toggleFilterModal: () => void,
|
||||
foodItemsSeq: SetSeq<FoodItemRecord>,
|
||||
isRefreshing: boolean,
|
||||
onRefresh: () => Promise<any>,
|
||||
onPulldown: () => {},
|
||||
isFilterDirty: boolean,
|
||||
};
|
||||
|
||||
class FoodList extends Component {
|
||||
static displayName = 'FoodList';
|
||||
const FoodList = (props: Props) => {
|
||||
const {
|
||||
isFilterModalOpen,
|
||||
foodItemsSeq,
|
||||
isRefreshing,
|
||||
onPulldown,
|
||||
toggleFilterModal,
|
||||
isFilterDirty,
|
||||
} = props;
|
||||
|
||||
context: RoutingContextFlowTypes;
|
||||
const refreshing = isRefreshing || !foodItemsSeq;
|
||||
const showNoResults = !isRefreshing && isFilterDirty && foodItemsSeq && !foodItemsSeq.size;
|
||||
|
||||
props: {
|
||||
isFilterModalOpen: boolean,
|
||||
toggleFilterModal: () => void,
|
||||
foodItemsSeq: SetSeq<FoodItemRecord>,
|
||||
isRefreshing: boolean,
|
||||
onRefresh: () => Promise<any>,
|
||||
onPulldown: () => {},
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
isFilterModalOpen,
|
||||
foodItemsSeq,
|
||||
isRefreshing,
|
||||
onPulldown,
|
||||
toggleFilterModal,
|
||||
} = this.props;
|
||||
|
||||
const refreshing = isRefreshing || !foodItemsSeq;
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{showNoResults && (
|
||||
<FullScreenMessage>
|
||||
<Text style={{ fontSize: 16 }}>No food matched your search.</Text>
|
||||
<Text style={{ fontSize: 16 }}>Check your filters and try again</Text>
|
||||
</FullScreenMessage>
|
||||
)}
|
||||
{!showNoResults && (
|
||||
<ScrollView
|
||||
style={{ flex: 1 }}
|
||||
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onPulldown} />}>
|
||||
<FoodItemList foodItemsSeq={foodItemsSeq} renderFoodItem={renderFoodItem} />
|
||||
<FoodItemList foodItemsSeq={foodItemsSeq}>
|
||||
{(foodItem: FoodItemRecord) => <FoodItemTile key={foodItem.id} foodItem={foodItem} />}
|
||||
</FoodItemList>
|
||||
</ScrollView>
|
||||
<FilterModal isVisible={isFilterModalOpen} onClose={toggleFilterModal} />
|
||||
<ActionsButton
|
||||
toggleFilterModal={toggleFilterModal}
|
||||
actions={['add-food', 'filter-modal', 'view-mode']}
|
||||
icon="add"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
)}
|
||||
<FilterModal isVisible={isFilterModalOpen} onClose={toggleFilterModal} />
|
||||
<ActionsButton
|
||||
toggleFilterModal={toggleFilterModal}
|
||||
actions={['add-food', 'filter-modal', 'view-mode']}
|
||||
icon="add"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default compose(
|
||||
pure,
|
||||
withRouterContext,
|
||||
withFoodItemsAsSeq,
|
||||
withFilter,
|
||||
withState('isRefreshing', 'setRefreshing', false),
|
||||
withHandlers({
|
||||
onPulldown: ({ setRefreshing, onRefresh }) => async () => {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ export function emitter(val: typeof FilterRecord) {
|
|||
multicaster.next(val);
|
||||
}
|
||||
|
||||
emitter(new FilterRecord());
|
||||
export const initialFilter = new FilterRecord();
|
||||
|
||||
emitter(initialFilter);
|
||||
|
||||
export default multicaster;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue