Implemented search into each category instead of its own screen

This commit is contained in:
Yohan Simard 2019-11-15 18:08:47 +01:00
parent edfb32667c
commit d614e8a1ed
4 changed files with 49 additions and 145 deletions

View file

@ -5,7 +5,6 @@ import {createMaterialBottomTabNavigatorWithInitialRoute} from './MainTabNavigat
import SettingsScreen from '../screens/SettingsScreen';
import AboutScreen from '../screens/About/AboutScreen';
import ProximoListScreen from '../screens/Proximo/ProximoListScreen';
import ProximoSearchScreen from "../screens/Proximo/ProximoSearchScreen";
import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen';
import ProxiwashAboutScreen from '../screens/Proxiwash/ProxiwashAboutScreen';
import ProximoAboutScreen from '../screens/Proximo/ProximoAboutScreen';
@ -27,7 +26,6 @@ function createAppContainerWithInitialRoute(initialRoute: string) {
Main: createMaterialBottomTabNavigatorWithInitialRoute(initialRoute),
// Drawer: MainDrawerNavigator,
ProximoListScreen: {screen: ProximoListScreen},
ProximoSearchScreen: {screen: ProximoSearchScreen},
SettingsScreen: {screen: SettingsScreen},
AboutScreen: {screen: AboutScreen},
AboutDependenciesScreen: {screen: AboutDependenciesScreen},
@ -44,7 +42,7 @@ function createAppContainerWithInitialRoute(initialRoute: string) {
initialRouteName: "Main",
mode: 'card',
headerMode: "none",
// transitionConfig: () => fromRight(),
transitionConfig: () => fromRight(),
})
);
}

View file

@ -51,6 +51,7 @@ type State = {
sortPriceIcon: React.Node,
sortNameIcon: React.Node,
modalCurrentDisplayItem: Object,
currentlyDisplayedData: Array<Object>,
};
/**
@ -59,19 +60,21 @@ type State = {
export default class ProximoListScreen extends React.Component<Props, State> {
modalRef: { current: null | Modalize };
originalData: Array<Object>;
constructor(props: any) {
super(props);
this.modalRef = React.createRef();
this.originalData = this.props.navigation.getParam('data', []);
}
state = {
navData: this.props.navigation.getParam('data', []).sort(sortPrice),
currentlyDisplayedData: this.props.navigation.getParam('data', []).sort(sortPrice),
currentSortMode: sortMode.price,
isSortReversed: false,
sortPriceIcon: '',
sortNameIcon: '',
modalCurrentDisplayItem: {}
modalCurrentDisplayItem: {},
};
_menu: Menu;
@ -111,7 +114,7 @@ export default class ProximoListScreen extends React.Component<Props, State> {
currentSortMode: mode,
isSortReversed: isReverse
});
let data = this.state.navData;
let data = this.state.currentlyDisplayedData;
switch (mode) {
case sortMode.price:
if (isReverse) {
@ -192,6 +195,35 @@ export default class ProximoListScreen extends React.Component<Props, State> {
}
}
sanitizeString(str: string) {
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
}
/**
* Returns only the articles whose name contains str. Case and accents insensitive.
* @param str
* @returns {[]}
*/
filterData(str: string) {
let filteredData = [];
const testStr = this.sanitizeString(str);
const articles = this.originalData;
for (const article of articles) {
const name = this.sanitizeString(article.name);
if (name.includes(testStr)) {
filteredData.push(article)
}
}
return filteredData;
}
search(str: string) {
this.setState({
currentlyDisplayedData: this.filterData(str)
})
}
getModalContent() {
return (
<View style={{
@ -277,13 +309,13 @@ export default class ProximoListScreen extends React.Component<Props, State> {
hasBackButton={true}
navigation={nav}
hasSearchField={true}
searchCallback={(text) => console.log(text)}
searchCallback={(text) => this.search(text)}
rightButton={this.getSortMenu()}/>
<Content>
<FlatList
data={this.state.navData}
extraData={this.state.navData}
data={this.state.currentlyDisplayedData}
extraData={this.state.currentlyDisplayedData}
keyExtractor={(item) => item.name + item.code}
style={{minHeight: 300, width: '100%'}}
renderItem={({item}) =>

View file

@ -102,17 +102,6 @@ export default class ProximoMainScreen extends FetchedDataSectionList {
getRightButton() {
return (
<View
style={{
flexDirection: 'row'
}}>
<Touchable
style={{padding: 6}}
onPress={() => this.props.navigation.navigate('ProximoSearchScreen', {data: this.state.fetchedData})}>
<CustomMaterialIcon
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
icon="magnify"/>
</Touchable>
<Touchable
style={{padding: 6}}
onPress={() => this.props.navigation.navigate('ProximoAboutScreen')}>
@ -120,7 +109,6 @@ export default class ProximoMainScreen extends FetchedDataSectionList {
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
icon="information"/>
</Touchable>
</View>
);
}
@ -138,15 +126,16 @@ export default class ProximoMainScreen extends FetchedDataSectionList {
<CustomMaterialIcon
icon={item.type.icon}
fontSize={30}
color={ThemeManager.getCurrentThemeVariables().brandPrimary}
/>
</Left>
<Body>
<Text>
{item.type.name}
</Text>
<Badge><Text>
<Text note>
{item.data.length} {item.data.length > 1 ? i18n.t('proximoScreen.articles') : i18n.t('proximoScreen.article')}
</Text></Badge>
</Text>
</Body>
<Right>
<CustomMaterialIcon icon="chevron-right"/>

View file

@ -1,115 +0,0 @@
// @flow
import * as React from 'react';
import {Body, Container, Content, Left, ListItem, Right, Text, Thumbnail,} from 'native-base';
import {FlatList} from "react-native";
import i18n from "i18n-js";
import ThemeManager from "../../utils/ThemeManager";
import CustomHeader from "../../components/CustomHeader";
type Props = {
navigation: Object,
};
type State = {
filteredData: Array<Object>,
};
/**
* Class defining proximo's article list of a certain category.
*/
export default class ProximoSearchScreen extends React.Component<Props, State> {
state = {
filteredData: this.props.navigation.getParam('data', {articles: [{name: "Error"}]}).articles,
};
/**
* get color depending on quantity available
*
* @param availableStock
* @return
*/
getStockColor(availableStock: number) {
let color: string;
if (availableStock > 3)
color = ThemeManager.getCurrentThemeVariables().brandSuccess;
else if (availableStock > 0)
color = ThemeManager.getCurrentThemeVariables().brandWarning;
else
color = ThemeManager.getCurrentThemeVariables().brandDanger;
return color;
}
showItemDetails(item: Object) {
//TODO: implement onClick function (copy-paste from ProximoListScreen)
}
/**
* Returns only the articles whose name contains str. Case and accents insensitive.
* @param str
* @returns {[]}
*/
filterData(str: string) {
let filteredData = [];
const testStr: String = str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
const articles: Object = this.props.navigation.getParam('data', {articles: [{name: "Error"}]}).articles;
for (const article: Object of articles) {
const name: String = String(article.name.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""));
if (name.includes(testStr)) {
filteredData.push(article)
}
}
return filteredData;
}
search(str: string) {
this.setState({
filteredData: this.filterData(str)
})
}
render() {
return (
<Container>
<CustomHeader
hasBackButton={true}
navigation={this.props.navigation}
hasSearchField={true}
searchCallback={(text) => this.search(text)}/>
<Content>
<FlatList
data={this.state.filteredData}
keyExtractor={(item) => item.name + item.code}
style={{minHeight: 300, width: '100%'}}
renderItem={({item}) =>
<ListItem
thumbnail
onPress={() => {this.showItemDetails(item);}} >
<Left>
<Thumbnail square source={{uri: item.image}}/>
</Left>
<Body>
<Text style={{marginLeft: 20}}>
{item.name}
</Text>
<Text note style={{
marginLeft: 20,
color: this.getStockColor(parseInt(item.quantity))
}}>
{item.quantity + ' ' + i18n.t('proximoScreen.inStock')}
</Text>
</Body>
<Right>
<Text style={{fontWeight: "bold"}}>
{item.price}
</Text>
</Right>
</ListItem>}
/>
</Content>
</Container>
);
}
}