Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* eslint-disable no-nested-ternary */
- import React from 'react';
- import {
- FlatList, RefreshControl, StyleSheet, TextInput, View, TouchableOpacity, ActivityIndicator
- } from 'react-native';
- import {
- Text, TouchableText, Seperator, Touhca
- } from 'src/components';
- import { ColorScheme } from 'src/constants';
- import i18next from 'src/locale';
- import { HomeStore, APIStore } from 'src/stores';
- import _ from 'lodash';
- const PAGE_SIZE = 20;
- type Props = {
- onPressSelectCompany: Function,
- };
- type CompanyProps = {
- id: String,
- email: String,
- name: String,
- organisationNumber: String,
- isSpecial: Number,
- status: Number,
- subscriptionId: Number,
- }
- type State = {
- companies: CompanyProps[],
- refreshing: Boolean,
- keyword: String,
- selectedCompany: Object,
- page: Number,
- fetching: Boolean, // Indication that the component is fetching/downloading data from api.
- };
- /**
- * Format company.
- * @param {*} company input company.
- */
- const formatCompany = (company: Object): CompanyProps => ({
- id: company.CompanyId,
- name: company.CompanyName || '',
- organisationNumber: company.OrganisationNumber,
- isSpecial: company.IsSpecial,
- email: company.Email || '',
- subscriptionId: company.SubscriptionId,
- status: company.Status,
- });
- export default class CompanyAssignedView extends React.Component<Props, State> {
- // Indication that the component is working.
- mounted = false;
- state = {
- companies: HomeStore.companies.slice(),
- refreshing: false,
- keyword: '',
- selectedCompany: HomeStore.selectedCompany || null,
- page: 1, // Variable for pagination data.
- fetching: false,
- };
- fetchCompanies = _.debounce(async (reset = false) => {
- const { keyword, page } = this.state;
- const searchPage = reset ? 1 : page;
- const { data: rawCompanies } = await APIStore.fetchCompany(searchPage, PAGE_SIZE, keyword);
- const formattedCompanies = rawCompanies.map(item => formatCompany(item));
- this.mounted && this.setState(prevState => ({
- companies: reset ? formattedCompanies : [...prevState.companies, ...formattedCompanies],
- fetching: false,
- page: reset ? 2 : prevState.page + 1,
- }));
- }, 300);
- componentDidMount() {
- this.mounted = true;
- this.setState({ fetching: true }, () => this.fetchCompanies(true));
- }
- componentWillUnmount() {
- this.mounted = false;
- }
- renderRow = ({ item }) => {
- const hId = _.get(item, ['id'], '');
- const cId = _.get(this.state, ['selectedCompany', 'id'], '');
- const isSelected = hId === cId;
- return (
- <TouchableOpacity
- style={styles.companyRow}
- onPress={() => this.setState({ selectedCompany: item })}
- >
- <View style={styles.flex1}>
- <Text
- style={isSelected ? styles.selectedCompanyText : null}
- size15
- medium
- >
- {item.name}
- </Text>
- {!!item.email && (
- <Text size13 gray>
- {item.email}
- </Text>
- )}
- {!!item.organisationNumber && (
- <Text size12 gray>
- {item.organisationNumber}
- </Text>
- )}
- </View>
- <View style={styles.selectedCompanyView}>
- {isSelected && <View style={styles.dot} />}
- </View>
- </TouchableOpacity>
- );
- };
- keyExtractor = (item, index) => `${index}`;
- renderSeperator = () => (<Seperator />)
- onRefresh = async () => {
- this.mounted && this.setState({ refreshing: true, page: 1 });
- await this.fetchCompanies(true);
- this.mounted && this.setState({ refreshing: false });
- };
- onPressSelect = () => {
- const { onPressSelectCompany } = this.props;
- const { selectedCompany } = this.state;
- onPressSelectCompany && onPressSelectCompany(selectedCompany);
- }
- onChangeText = (text) => {
- const searchText = text.trim().toLowerCase();
- this.fetchCompanies.cancel();
- this.setState({
- keyword: searchText,
- fetching: true,
- page: 1,
- }, () => this.fetchCompanies(true));
- }
- reachedListThreshold = () => {
- // If the current list have less than 5 items.
- // That means we don't have more item because the PAGE_SIZE is 20.
- // Stop fetching to make the api do not call page 2+
- const { companies } = this.state;
- if (companies.length <= 5) {
- return;
- }
- // Start searching.
- this.fetchCompanies.cancel();
- this.setState({
- fetching: true,
- }, () => this.fetchCompanies());
- }
- render() {
- const {
- refreshing, selectedCompany, companies, fetching,
- } = this.state;
- return (
- <View style={styles.container}>
- {/* Search view */}
- <View style={styles.searchView}>
- <TextInput
- placeholder={i18next.t('home.searchCompanyName')}
- style={styles.searchInput}
- onChangeText={keyword => this.onChangeText(keyword)}
- />
- { fetching && (<ActivityIndicator style={styles.indicator} />)}
- </View>
- {/* Body Flatlist */}
- <FlatList
- style={styles.list}
- data={companies}
- extraData={`${companies.length}+${selectedCompany ? selectedCompany.id : ''}`}
- renderItem={this.renderRow}
- keyExtractor={this.keyExtractor}
- refreshControl={(<RefreshControl refreshing={refreshing} onRefresh={this.onRefresh} />)}
- ItemSeparatorComponent={this.renderSeperator}
- onEndReached={this.reachedListThreshold}
- onEndReachedThreshold={0.1}
- />
- <TouchableText
- style={styles.selectButton}
- textStyle={styles.selectText}
- text={i18next.t('home.select')}
- onPress={this.onPressSelect}
- />
- </View>
- );
- }
- }
- const styles = StyleSheet.create({
- container: {
- },
- list: {
- height: 300,
- },
- searchView: {
- flexDirection: 'row',
- height: 44,
- alignItems: 'center',
- paddingHorizontal: 15,
- marginHorizontal: 20,
- borderColor: ColorScheme.borderGray,
- borderWidth: 1,
- borderRadius: 10,
- marginTop: 10,
- },
- searchInput: {
- flex: 1,
- alignSelf: 'stretch',
- },
- purchaseButton: {
- borderRadius: 5,
- borderColor: ColorScheme.primary,
- borderWidth: 1,
- height: 35,
- paddingHorizontal: 5,
- marginLeft: 5,
- },
- purchaseText: {
- color: ColorScheme.primary,
- },
- row: {
- flexDirection: 'row',
- alignSelf: 'stretch',
- alignItems: 'center',
- marginHorizontal: 20,
- marginVertical: 10,
- },
- flex1: {
- flex: 1,
- },
- verifiedText: {
- color: ColorScheme.blue,
- },
- companyRow: {
- alignSelf: 'stretch',
- marginHorizontal: 20,
- marginVertical: 10,
- flexDirection: 'row',
- alignItems: 'center',
- },
- selectButton: {
- height: 52,
- borderRadius: 10,
- backgroundColor: '#2196f3',
- marginHorizontal: 16,
- marginTop: 1,
- marginBottom: 10,
- },
- selectText: {
- fontSize: 16,
- color: ColorScheme.white,
- },
- dot: {
- width: 12,
- height: 12,
- borderRadius: 6,
- backgroundColor: ColorScheme.orange,
- },
- indicator: {
- marginLeft: 10,
- },
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement