react-native-paper#Headline JavaScript Examples

The following examples show how to use react-native-paper#Headline. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From puente-reactnative-collect with MIT License 6 votes vote down vote up
Feedback = () => {
  const handleEmail = async () => {
    await MailComposer.isAvailableAsync().then((mailAvailable) => {
      if (mailAvailable) {
        MailComposer.composeAsync({
          recipients: ['[email protected]'],
          subject: 'User Feedback',
          body: emailBody
        });
      }
    });
  };

  const [emailBody, setEmailBody] = useState('');

  return (
    <View style={styles.mainContainer}>
      <Headline>{I18n.t('feedback.feedback')}</Headline>
      <View style={styles.horizontalLinePrimary} />
      <Text>{I18n.t('feedback.enterFeedback')}</Text>
      <View style={styles.horizontalLinePrimary} />
      <TextInput
        multiline
        onChangeText={(text) => setEmailBody(text)}
        placeholder={I18n.t('feedback.typeFeedback')}
      />
      <View style={styles.languageContainer}>
        <Button mode="contained" onPress={() => handleEmail()}>{I18n.t('feedback.sendMail')}</Button>
      </View>
    </View>
  );
}
Example #2
Source File: index.js    From Cosmos with MIT License 6 votes vote down vote up
renderScreen(item, index) {
    return (
      <View style={styles.innerView}>
        <View style={{width: width, height: width / 1.5}}>
          <LottieView source={item.source} autoPlay />
        </View>
        <Caption style={Styles.fontSmall}>{item.madeBy}</Caption>
        <Headline style={Styles.fontLarge}>{item.header}</Headline>
        <Text
          style={[{textAlign: 'justify', marginTop: 10}, Styles.fontMedium]}>
          {item.body}
        </Text>
        <Button
          mode="contained"
          labelStyle={Styles.fontSmall}
          style={styles.googleBtn}
          onPress={
            index === data.length - 1
              ? () => this.continueWithGoogle()
              : () =>
                  this.flatList.scrollToIndex({
                    animated: true,
                    index: index + 1,
                  })
          }>
          {index === data.length - 1 ? 'Continue With Google' : 'Next'}
        </Button>
      </View>
    );
  }
Example #3
Source File: index.js    From puente-reactnative-collect with MIT License 6 votes vote down vote up
export default function TermsModal(props) {
  const { visible, setVisible } = props;
  return (
    <Portal theme={theme}>
      <Modal
        visible={visible}
        theme={theme}
        contentContainerStyle={styles.modal}
        dismissable={false}
      >
        <ScrollView>
          <Headline theme={theme}>{I18n.t('termsModal.termsService')}</Headline>
          <Text>{I18n.t('termsModal.policy')}</Text>
          <Button mode="contained" theme={theme} color="#3E81FD" style={styles.button} onPress={() => setVisible(false)}>{I18n.t('termsModal.ok')}</Button>
        </ScrollView>
      </Modal>
    </Portal>
  );
}
Example #4
Source File: index.js    From puente-reactnative-collect with MIT License 5 votes vote down vote up
Language = () => {
  useEffect(() => {
    async function setUserInformation() {
      const currentLocale = await getData('locale');
      setLanguage(currentLocale);
    }
    setUserInformation();
  }, [updated]);

  const [language, setLanguage] = useState('');
  const [updated, setUpdated] = useState(false);

  const handleLanguage = async (lang) => {
    setLanguage(lang);
    await storeData(lang, 'locale');
    setUpdated(true);
    I18n.locale = lang;
  };

  return (
    <View>
      <Headline>{I18n.t('languageSettings.chooseLanguage')}</Headline>
      <View style={styles.languageContainer}>
        {language === 'en' && (
          <Button mode="contained">{I18n.t('languagePicker.english')}</Button>
        )}
        {language !== 'en' && (
          <Button mode="outlined" onPress={() => { handleLanguage('en'); }}>{I18n.t('languagePicker.english')}</Button>
        )}
      </View>
      <View style={styles.languageContainer}>
        {language === 'es' && (
          <Button mode="contained">{I18n.t('languagePicker.spanish')}</Button>
        )}
        {language !== 'es' && (
          <Button mode="outlined" onPress={() => { handleLanguage('es'); }}>{I18n.t('languagePicker.spanish')}</Button>
        )}
      </View>
      <View style={styles.languageContainer}>
        {language === 'hk' && (
          <Button mode="contained">{I18n.t('languagePicker.creole')}</Button>
        )}
        {language !== 'hk' && (
          <Button mode="outlined" onPress={() => { handleLanguage('hk'); }}>{I18n.t('languagePicker.creole')}</Button>
        )}
      </View>
    </View>
  );
}
Example #5
Source File: number.screen.js    From astrale with GNU General Public License v3.0 5 votes vote down vote up
/**
 * @param navigation
 * @returns {*}
 * @constructor
 */
function NumberScreen({ navigation }) {
  const [{ session }, dispatch] = useGlobals();
  const [number, setNumber] = React.useState();
  const buttonDisabled = !number;
  const _handleContinue = () => {
    dispatch({
      type: 'setSession',
      fields: { number },
    });
    navigation.push('Loading');
  };

  return (
    <DefaultView>
      <SpaceSky />
      <Aquarius width={60} height={60} style={styles.aquarius} />
      <View style={{ flex: 1 }} />
      <View style={styles.textContainer}>
        <Headline style={styles.textHeadline}>
          {i18n.t('Your favorite number')}
        </Headline>
        <Text style={styles.textText}>
          {i18n.t(
            '{name}, to give you accurate and personal information we need to know some info',
            { name: session.name }
          )}
        </Text>
      </View>
      <View style={styles.logoContainer}>
        <Dices height={60} />
      </View>
      <View style={styles.inputContainer}>
        <CustomInput
          value={number}
          onChangeText={(text) => setNumber(text)}
          placeholder={i18n.t('Type here')}
          keyboardType="number-pad"
          enablesReturnKeyAutomatically
        />
      </View>
      <View style={styles.buttonContainer}>
        <Button
          mode="contained"
          disabled={buttonDisabled}
          onPress={_handleContinue}
        >
          {i18n.t('Continue')}
        </Button>
      </View>
    </DefaultView>
  );
}
Example #6
Source File: name.screen.js    From astrale with GNU General Public License v3.0 5 votes vote down vote up
/**
 * @param navigation
 * @returns {*}
 * @constructor
 */
function NameScreen({ navigation }) {
  const dispatch = useGlobals()[1];
  const [name, setName] = React.useState();
  const { colors } = useTheme();
  const buttonDisabled = !name || name.length < 2;
  const _handleContinue = () => {
    dispatch({
      type: 'setSession',
      fields: { name },
    });
    navigation.push('BirthDate');
  };

  return (
    <DefaultView>
      <SpaceSky />
      <Aquarius width={60} height={60} style={styles.aquarius} />
      <Backgrounds.Constellation
        color={colors.text}
        dotColor={colors.primary}
        height={180}
        width={180}
        style={styles.constellation}
      />
      <View style={{ flex: 0.5 }} />
      <View style={styles.textContainer}>
        <Headline style={styles.textHeadline}>
          {i18n.t("What's your name?")}
        </Headline>
        <Text style={styles.textText}>
          {i18n.t(
            'In order to give you accurate and personal information we need to know some info'
          )}
        </Text>
      </View>
      <View style={styles.inputContainer}>
        <CustomInput
          value={name}
          placeholder={i18n.t('Write here')}
          onChangeText={(text) => setName(text)}
          style={{ fontSize: 12 }}
          maxLength={20}
        />
      </View>
      <View style={styles.buttonContainer}>
        <Button
          mode="contained"
          disabled={buttonDisabled}
          onPress={_handleContinue}
        >
          {i18n.t('Continue')}
        </Button>
      </View>
    </DefaultView>
  );
}
Example #7
Source File: sex.screen.js    From astrale with GNU General Public License v3.0 5 votes vote down vote up
/**
 * @param navigation
 * @returns {*}
 * @constructor
 */
function SexScreen({ navigation }) {
  const [{ session }, dispatch] = useGlobals();
  const [sex, setSex] = React.useState('');
  const buttonDisabled = !sex;
  const _handleContinue = () => {
    dispatch({
      type: 'setSession',
      fields: { sex },
    });
    navigation.push('Relationship');
  };

  return (
    <DefaultView>
      <SpaceSky />
      <Leo width={60} height={60} style={styles.leo} />
      <View style={{ flex: 1 }} />
      <View style={styles.textContainer}>
        <Headline style={styles.textHeadline}>{i18n.t('Your gender')}</Headline>
        <Text style={styles.textText}>
          {i18n.t(
            '{name}, to give you accurate and personal information we need to know some info',
            { name: session.name }
          )}
        </Text>
      </View>
      <View style={styles.sexContainer}>
        <TouchableRipple
          onPress={() => setSex('Male')}
          rippleColor="rgba(0,0,0,0)"
        >
          <View>
            <Male style={{ opacity: sex === 'Male' ? 1 : 0.5 }} />
            <Text style={styles.sexText}>{i18n.t('Male')}</Text>
          </View>
        </TouchableRipple>
        <TouchableRipple
          onPress={() => setSex('Female')}
          rippleColor="rgba(0,0,0,0)"
        >
          <View>
            <Female style={{ opacity: sex === 'Female' ? 1 : 0.5 }} />
            <Text style={styles.sexText}>{i18n.t('Female')}</Text>
          </View>
        </TouchableRipple>
      </View>
      <View style={styles.buttonContainer}>
        <Button
          mode="contained"
          disabled={buttonDisabled}
          onPress={_handleContinue}
        >
          {i18n.t('Continue')}
        </Button>
      </View>
    </DefaultView>
  );
}
Example #8
Source File: Counts.js    From real-frontend with GNU General Public License v3.0 5 votes vote down vote up
ProfileCounts = ({
  theme,
  navigation,
  usersGetProfile,
}) => {
  const styling = styles(theme)
  const { t } = useTranslation()

  const userId = path(['data', 'userId'])(usersGetProfile)

  const handleProfileFollowerPress = () => navigation.navigate({
    routeName: 'ProfileFollower',
    params: { userId },
    key: `ProfileFollower-userId${userId}`,
  })
  const handleProfileFollowedPress = () => navigation.navigate({
    routeName: 'ProfileFollowed',
    params: { userId },
    key: `ProfileFollowed-userId${userId}`,
  })
  
  const followerCount = path(['data', 'followerCount'])(usersGetProfile)
  const followedCount = path(['data', 'followedCount'])(usersGetProfile)

  return (
    <View style={styling.root}>
      <View style={styling.item}>
        <Headline style={styling.itemTitle}>{path(['data', 'postCount'])(usersGetProfile)}</Headline>
        <Caption style={styling.itemText} numberOfLines={1}>{t('Posts')}</Caption>
      </View>
      
      <TouchableOpacity style={styling.item} onPress={handleProfileFollowerPress}>
        {!path(['data', 'followCountsHidden'])(usersGetProfile) && is(Number)(followerCount) ?
          <Headline style={styling.itemTitle}>{followerCount}</Headline>
        :
          <Headline style={styling.itemTitle}>•</Headline>
        }
        <Caption style={styling.itemText} numberOfLines={1}>{t('Followers')}</Caption>
      </TouchableOpacity>

      
      <TouchableOpacity style={styling.item} onPress={handleProfileFollowedPress}>
        {!path(['data', 'followCountsHidden'])(usersGetProfile) && is(Number)(followedCount) ?
          <Headline style={styling.itemTitle}>{followedCount}</Headline>
        :
          <Headline style={styling.itemTitle}>•</Headline>
        }
        <Caption style={styling.itemText} numberOfLines={1}>{t('Following')}</Caption>
      </TouchableOpacity>
    </View>
  )
}
Example #9
Source File: index.js    From Cosmos with MIT License 5 votes vote down vote up
render() {
    const {enrolledBy, btnLoading, isBottomSheetOpen} = this.state;

    return (
      <View style={styles.boxScreenContainer}>
        <View style={styles.authorContainer}>
          <Headline style={Styles.fontMedium}>
            Author: {this.state.auth[0]}
          </Headline>
        </View>
        <View style={styles.addPartConatiner}>
          <Text style={Styles.fontSmall}>Add Participant</Text>
          <TextInput
            style={[Styles.fontMedium, styles.textInput]}
            mode="outlined"
            placeholder="Email"
            maxLength={50}
            value={this.state.email}
            dense={true}
            onChangeText={(email) => this.setAddParticipant(email)}
          />
          <Button
            labelStyle={Styles.fontSmall}
            loading={btnLoading}
            icon="plus"
            onPress={() => this.handleAddUser()}>
            Add Member
          </Button>
        </View>
        <FlatList
          ListHeaderComponent={() => {
            return (
              <Text style={Styles.fontSmall}>
                Enrolled Users: {enrolledBy.length}
              </Text>
            );
          }}
          ListHeaderComponentStyle={{margin: 10}}
          ListEmptyComponent={() => {
            return <ActivityIndicator />;
          }}
          data={enrolledBy}
          keyExtractor={(item) => item.uid}
          renderItem={({item, index}) => {
            return (
              <Card
                style={styles.card}
                onPress={() => this.handleOptions(index)}>
                <Card.Content>
                  <Subheading style={Styles.fontMedium}>{item.name}</Subheading>
                </Card.Content>
              </Card>
            );
          }}
          ItemSeparatorComponent={() => <Divider style={styles.Divider} />}
        />
        <BottomSheet
          isOpen={isBottomSheetOpen}
          closeBottomSheet={() => this.setBottomSheet(false)}
          options={[{text: 'Remove User', onPress: this.handleRemoveUser}]}
        />
      </View>
    );
  }
Example #10
Source File: index.js    From Cosmos with MIT License 5 votes vote down vote up
render() {
    const {state} = this.context;
    const {enrolledBoxes, newBoxName, btnLoading} = this.state;
    return (
      <View style={styles.listCircleContainer}>
        <Text style={[Styles.fontSmall, styles.helpText]}>
          Boxes are your personal Friend/Family/Work groups where you share
          relevant posts which interest a perticular group. You can either join
          an existing group or create a new group.
        </Text>
        <View style={styles.addPartConatiner}>
          <Text style={Styles.fontSmall}>Create New Box</Text>
          <TextInput
            style={[Styles.fontMedium, styles.textInput]}
            mode="outlined"
            placeholder="Box Name"
            maxLength={30}
            dense={true}
            value={newBoxName}
            onChangeText={(nb) => this.setNewBoxName(nb)}
          />
          <Button
            labelStyle={Styles.fontSmall}
            loading={btnLoading}
            icon="plus"
            onPress={() => this.handleCreateBox()}>
            Create Box
          </Button>
        </View>
        <Divider />
        <FlatList
          ListHeaderComponent={() => {
            return <Text style={Styles.fontSmall}>Enrolled Boxes</Text>;
          }}
          ListHeaderComponentStyle={{margin: 10}}
          ListEmptyComponent={() => {
            return (
              <View style={styles.emptyComponentContainer}>
                <Planet
                  size={width / 2.5}
                  mood={newBoxName.length !== 0 ? 'lovestruck' : 'blissful'}
                  color="#FCCB7E"
                />
                <Headline style={[Styles.fontMedium, styles.noBoxesYet]}>
                  Here you create new Boxes and see what boxes you are enrolled
                  in. To switch boxes you just tap on them from the given list.
                  To get started create a New Box, don't forget to give it
                  exciting name.
                </Headline>
              </View>
            );
          }}
          data={enrolledBoxes}
          keyExtractor={(item) => item}
          renderItem={({item}) => {
            return (
              <Card
                onPress={() => this.handleSelectBox(item)}
                style={styles.card}>
                <Card.Content style={styles.cardContent}>
                  <Subheading styles={Styles.fontMedium}>{item}</Subheading>
                  {state.box === item ? (
                    <Icons
                      name="check"
                      size={20}
                      color={DarkTheme.colors.primary}
                    />
                  ) : null}
                </Card.Content>
              </Card>
            );
          }}
          ItemSeparatorComponent={() => <Divider style={styles.Divider} />}
        />
      </View>
    );
  }
Example #11
Source File: index.js    From Cosmos with MIT License 5 votes vote down vote up
render() {
    const {
      name,
      posts,
      photoURL,
      love,
      meh,
      sad,
      isBottomSheetOpen,
    } = this.state;
    return (
      <View style={styles.profileContainer}>
        <BottomSheet
          isOpen={isBottomSheetOpen}
          closeBottomSheet={() => this.setBottomSheet(false)}
          options={[
            {text: 'Delete Post', onPress: () => this.handleDeletePost()},
          ]}
        />
        <View style={styles.fixedTopHeader}>
          <ActiveImage
            uri={photoURL}
            style={styles.userImage}
            size={width / 4}
          />
          <Headline style={Styles.fontLarge}>{name}</Headline>
          <View style={styles.fixedTopHeaderInnerSection}>
            <View style={styles.fixedTopHeaderCards}>
              <Text style={Styles.fontMedium}>{posts.length}</Text>
              <Text style={Styles.fontMedium}>POSTS</Text>
            </View>
            <View style={styles.fixedTopHeaderCards}>
              <Text style={[Styles.fontMedium, {color: 'red'}]}>{love}</Text>
              <Icon name="heart" size={width * 0.06} color="red" />
            </View>
            <View style={styles.fixedTopHeaderCards}>
              <Text style={[Styles.fontMedium, {color: 'green'}]}>{meh}</Text>
              <Icon name="meh" size={width * 0.06} color="green" />
            </View>
            <View style={styles.fixedTopHeaderCards}>
              <Text style={[Styles.fontMedium, {color: 'yellow'}]}>{sad}</Text>
              <Icon name="frown" size={width * 0.06} color="yellow" />
            </View>
          </View>
        </View>
        <ScrollView style={styles.scrollBottomView} onScrollAnimationEnd>
          {this.renderPosts()}
        </ScrollView>
      </View>
    );
  }
Example #12
Source File: index.js    From puente-reactnative-collect with MIT License 5 votes vote down vote up
Geolocation = ({ errors, formikKey, setFieldValue }) => {
  const [location, setLocation] = useState({ latitude: 0, longitude: 0, altitude: 0 });
  const [locationLoading, setLocationLoading] = useState(false);
  const [submissionError, setSubmissionError] = useState(false);

  const handleLocation = async () => {
    setLocationLoading(true);

    const locationPromise = new Promise((resolve, reject) => {
      try {
        return getLocation().then((value) => resolve(value));
      } catch (e) {
        return reject(e);
      }
    });

    const currentLocation = await fulfillWithTimeLimit(20000, locationPromise, null);

    if (!currentLocation) {
      setFieldValue('location', { latitude: 0, longitude: 0, altitude: 0 });
      setLocationLoading(false);
      setSubmissionError(true);
    } else {
      const { latitude, longitude, altitude } = currentLocation.coords;
      setFieldValue('location', { latitude, longitude, altitude });
      setLocation({ latitude, longitude, altitude });
      setLocationLoading(false);
    }
  };
  return (
    <View key={formikKey}>
      {location === null && (
      <PaperButton
        onPressEvent={handleLocation}
        buttonText={I18n.t('paperButton.getLocation')}
      />
      )}
      {location !== null && (
      <View>
        <PaperButton
          onPressEvent={handleLocation}
          buttonText={I18n.t('paperButton.getLocationAgain')}
        />
        <View style={{ marginLeft: 'auto', marginRight: 'auto', flexDirection: 'row' }}>
          {
            locationLoading === true
            && <Spinner color={theme.colors.primary} />
          }
          {locationLoading === false
            && (
              <View>
                <Headline>
                  {`(${location.latitude.toFixed(2)}, ${location.longitude.toFixed(2)})`}
                </Headline>
              </View>
            )}
        </View>
        <Text style={{ color: 'red' }}>
          {errors[formikKey]}
        </Text>
      </View>
      )}
      <PopupError
        error={submissionError}
        setError={setSubmissionError}
        errorMessage="submissionError.geolocation"
      />
    </View>
  );
}
Example #13
Source File: index.mobile.js    From MediBuddy with MIT License 5 votes vote down vote up
export default function MyAppointments() {
  const appointments = useSelector(
    state => state.appointmentReducer.appointments,
  );

  const localData = [...appointments];
  // Sort data by datetime
  localData.sort((a, b) => {
    return moment(a.date).unix() - moment(b.date).unix();
  });

  // Reduce data for SectionList
  const groupedData = localData.reduce(
    (
      accumulator,
      currentValue,
      currentIndex,
      array,
      key = currentValue.date,
    ) => {
      const keyObjectPosition = accumulator.findIndex(item => item.key == key);
      if (keyObjectPosition >= 0) {
        accumulator[keyObjectPosition].data.push(currentValue);
        return accumulator;
      } else {
        return accumulator.concat({ data: [currentValue], key: key });
      }
    },
    [],
  );

  return (
    <SafeAreaView style={styles.container}>
      <SectionList
        style={styles.list}
        sections={groupedData}
        renderItem={({ item }) => <Item item={item} />}
        renderSectionHeader={({ section: { key } }) => <Title>{key}</Title>}
        ListHeaderComponent={() => (
          <Headline style={styles.headline}>My Appointments</Headline>
        )}
        stickySectionHeadersEnabled={false}
        showsVerticalScrollIndicator={false}
        keyExtractor={item => item.id}
      />
    </SafeAreaView>
  );
}
Example #14
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
SupportHome = ({
  logOut, settingsView, setSettingsView, setSettings
}) => {
  const [supportView, setSupportView] = useState('');

  const rateApp = async () => {
    if (await StoreReview.isAvailableAsync()) {
      StoreReview.requestReview();
    }
  };
  const inputs = [
    {
      key: 'feedback',
      label: I18n.t('supportHome.feedback'),
      button: true,
      touchable: false,
      action: null
    },
    {
      key: 'rateApp',
      label: I18n.t('supportHome.rateApp'),
      button: false,
      touchable: true,
      action: rateApp
    }
  ];
  return (
    <View>
      {settingsView === 'Support' && supportView === '' && (
        <View>
          <View style={{ flexDirection: 'row', marginLeft: 'auto', marginRight: 'auto' }}>
            <View style={{ paddingRight: '5%' }}>
              <Button onPress={() => setSettingsView('Settings')}>{I18n.t('accountSettings.settings')}</Button>
            </View>
            <View style={{ paddingLeft: '5%' }}>
              <Button mode="contained">
                {I18n.t('accountSettings.support')}
              </Button>
            </View>
          </View>
          <View style={{ paddingLeft: '5%', paddingRight: '5%', paddingTop: 20 }}>
            <Headline style={{ fontWeight: 'bold' }}>{I18n.t('supportHome.helpCenter')}</Headline>
            <View style={styles.horizontalLineGray} />
            {inputs.length > 0 && inputs.map((input) => (
              <View key={input.key}>
                {input.touchable ? (
                  <TouchableOpacity style={{ flexDirection: 'row' }} onPress={() => input.action()}>
                    <Text style={styles.text}>{input.label}</Text>
                    {input.button && (
                      <IconButton
                        icon="chevron-right"
                        size={30}
                        color={theme.colors.primary}
                        style={{ marginLeft: 'auto', marginTop: -5, marginBottom: -10 }}
                        onPress={() => {
                          setSupportView(input.key);
                        }}
                      />
                    )}
                  </TouchableOpacity>
                ) : (
                  <View style={{ flexDirection: 'row' }}>
                    <Text style={styles.text}>{input.label}</Text>
                    {input.button && (
                      <IconButton
                        icon="chevron-right"
                        size={30}
                        color={theme.colors.primary}
                        style={{ marginLeft: 'auto', marginTop: -5, marginBottom: -10 }}
                        onPress={() => {
                          setSupportView(input.key);
                        }}
                      />
                    )}
                  </View>
                )}
                <View style={styles.horizontalLineGray} />
              </View>
            ))}
          </View>
          <Button onPress={() => {
            setSettings(false);
          }}
          >
            {I18n.t('accountSettings.back')}
          </Button>
          <Button mode="contained" onPress={logOut} style={{ marginTop: 20, marginLeft: '5%', marginRight: '5%' }}>{I18n.t('accountSettings.logout')}</Button>
        </View>
      )}
      {supportView !== '' && (
        <View>
          <SupportSettings
            supportView={supportView}
            setSupportView={setSupportView}
          />
        </View>
      )}
    </View>
  );
}
Example #15
Source File: index.js    From Cosmos with MIT License 4 votes vote down vote up
render() {
    const {image, imageCaption, isLoading} = this.state;
    const {state} = this.context;

    if (state.box.length === 0) {
      return (
        <View style={styles.addContainer}>
          <Backpack size={width / 2.5} mood="sad" color="#FFD882" />
          <Headline style={[Styles.fontMedium, styles.imgText]}>
            Oops looks like you haven't created a group yet. Please go back to
            the Home screen and take Sun's help to create one first
          </Headline>
        </View>
      );
    }

    if (isLoading) {
      return (
        <View style={styles.addContainer}>
          <BoxLoading />
        </View>
      );
    }

    if (image !== null) {
      return (
        <View style={styles.addContainer}>
          <AppHeader
            iconLeft="x"
            onPressLeft={() => {
              Alert.alert(
                'Discard Post',
                'Do you want to discard your post, all changes will be lost?',
                [
                  {
                    text: 'Discard',
                    onPress: () =>
                      this.setState({
                        isLoading: false,
                        fileBlog: null,
                        image: null,
                        imageCaption: '',
                      }),
                  },
                  {
                    text: 'Cancel',
                    onPress: () => {},
                  },
                ],
                {cancelable: true},
              );
            }}
            iconRight="send"
            onPressRight={this.onPostUpload}
          />
          <ScrollView showsVerticalScrollIndicator={false}>
            <View>
              <Image style={styles.loadedImage} source={image} />
              <View style={styles.captionContainer}>
                <TextInput
                  value={imageCaption}
                  style={styles.textInputCaption}
                  onChangeText={(caption) => this.setImageCaption(caption)}
                  placeholder="Write a caption"
                  placeholderTextColor="white"
                  autoCapitalize="sentences"
                  autoFocus={true}
                  maxLength={300}
                  multiline={true}
                  numberOfLines={6}
                  textAlignVertical="top"
                  defaultValue="No Caption"
                />
              </View>
            </View>
          </ScrollView>
        </View>
      );
    }

    return (
      <View style={styles.addContainer}>
        <Backpack size={width / 2.5} mood="excited" color="#FFD882" />
        <Headline style={[Styles.fontMedium, styles.imgText]}>
          Lets see what you got in your bag of pics, or I can help you get a
          shot if you need help with that
        </Headline>
        <View style={styles.optionsContainer}>
          <TouchableOpacity
            style={styles.optionContainer}
            onPress={() => {
              if (state.box === '') {
                return ToastAndroid.showWithGravity(
                  'No Box selected!',
                  ToastAndroid.SHORT,
                  ToastAndroid.CENTER,
                );
              }
              this.openImagePicker();
            }}>
            <Icon size={width * 0.06} name="plus" color="white" />
            <Text style={Styles.fontMedium}>Open Bag</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={styles.optionContainer}
            onPress={() => {
              if (state.box === '') {
                return ToastAndroid.showWithGravity(
                  'No Box selected!',
                  ToastAndroid.SHORT,
                  ToastAndroid.CENTER,
                );
              }
              this.openImageCamera();
            }}>
            <Icon size={width * 0.06} name="camera" color="white" />
            <Text style={Styles.fontMedium}>Start Camera</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
Example #16
Source File: astrologuers-question.screen.js    From astrale with GNU General Public License v3.0 4 votes vote down vote up
/**
 * @param route
 * @param navigation
 * @returns {*}
 * @constructor
 */
function AstrologerQuestionScreen({ route, navigation }) {
  const dispatch = useGlobals()[1];
  const astrologist = route.params.astrologist;
  const setData = React.useState({
    message: null,
    email: null,
    astrologer: astrologist.name,
  })[1];
  const isDark = useIsDark();
  const isAndroid = PlatformUtils.isAndroid;
  const handleProceed = () => {
    try {
      dispatch({ type: 'toggleLoader' });
    } catch {
    } finally {
      dispatch({ type: 'toggleLoader' });
      navigation.pop();
    }
  };

  return (
    <BlurView
      style={[StyleSheet.absoluteFill, { flex: 1 }]}
      tint={isDark ? 'dark' : 'light'}
      intensity={isAndroid ? 150 : 100}
    >
      <TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
        <ScrollView style={{ paddingBottom: 200 }}>
          <Close position="right" />
          <View style={{ margin: 20, alignItems: 'center' }}>
            <Headline>{astrologist.name}</Headline>
            <Subheading>
              {i18n.t(astrologist.school, { word: i18n.t('Astrology') })}
            </Subheading>
            <Image source={astrologist.photo} style={styles.image} />
          </View>
          <Divider />
          <View style={{ margin: 20 }}>
            <View style={{ height: 5 }} />
            <TextInput
              label={i18n.t('Your question')}
              multiline
              style={{ height: 150 }}
              maxLength={250}
              onChangeText={(text) =>
                setData((data) => ({ ...data, message: text }))
              }
            />
            <View style={{ height: 5 }} />
            <TextInput
              label={i18n.t('Your email')}
              keyboardType="email-address"
              onChangeText={(text) =>
                setData((data) => ({ ...data, email: text }))
              }
            />
          </View>
          <View style={{ marginHorizontal: 20, marginBottom: 20 }}>
            <Button
              onPress={handleProceed}
              mode="contained"
              style={{ borderRadius: 20 }}
              icon="send"
            >
              {i18n.t('Proceed')}
            </Button>
            <Text style={styles.advice}>
              *
              {i18n.t(
                "You'll need to see an ad before you can send the question"
              )}
            </Text>
          </View>
          <Divider />
        </ScrollView>
      </TouchableWithoutFeedback>
    </BlurView>
  );
}
Example #17
Source File: relationship.screen.js    From astrale with GNU General Public License v3.0 4 votes vote down vote up
/**
 * @param navigation
 * @returns {*}
 * @constructor
 */
function RelationshipScreen({ navigation }) {
  const [{ session }, dispatch] = useGlobals();
  const [relationshipStatus, setRelationshipStatus] = React.useState('');
  const buttonDisabled = !relationshipStatus;
  const _handleContinue = () => {
    dispatch({
      type: 'setSession',
      fields: { relationship: relationshipStatus },
    });
    navigation.push('Number');
  };

  return (
    <DefaultView>
      <SpaceSky />
      <Taurus width={60} height={60} style={styles.taurus} />
      <View style={{ flex: 0.4 }} />
      <View style={styles.textContainer}>
        <Headline style={styles.textHeadline}>
          {i18n.t('What is your relationship status')}
        </Headline>
        <Text style={styles.textText}>
          {i18n.t(
            '{name}, to give you accurate and personal information we need to know some info',
            { name: session.name }
          )}
        </Text>
      </View>
      <View style={styles.sexContainer}>
        <TouchableRipple
          onPress={() => setRelationshipStatus('Married')}
          rippleColor="rgba(0,0,0,0)"
        >
          <View>
            <Married
              width={100}
              style={{ opacity: relationshipStatus === 'Married' ? 1 : 0.5 }}
            />
            <Text style={styles.sexText}>{i18n.t('Married')}</Text>
          </View>
        </TouchableRipple>
        <TouchableRipple
          onPress={() => setRelationshipStatus('Single')}
          rippleColor="rgba(0,0,0,0)"
        >
          <View>
            <Cool
              width={100}
              style={{ opacity: relationshipStatus === 'Single' ? 1 : 0.5 }}
            />
            <Text style={styles.sexText}>{i18n.t('Single')}</Text>
          </View>
        </TouchableRipple>
      </View>
      <View style={{ flex: 0.1 }} />
      <View style={styles.sexContainer}>
        <TouchableRipple
          onPress={() => setRelationshipStatus('In love')}
          rippleColor="rgba(0,0,0,0)"
        >
          <View>
            <InLove
              width={100}
              style={{ opacity: relationshipStatus === 'In love' ? 1 : 0.5 }}
            />
            <Text style={styles.sexText}>{i18n.t('In love')}</Text>
          </View>
        </TouchableRipple>
        <TouchableRipple
          onPress={() => setRelationshipStatus("It's difficult")}
          rippleColor="rgba(0,0,0,0)"
        >
          <View>
            <ItsDifficult
              width={100}
              style={{
                opacity: relationshipStatus === "It's difficult" ? 1 : 0.5,
              }}
            />
            <Text style={styles.sexText}>{i18n.t("It's difficult")}</Text>
          </View>
        </TouchableRipple>
      </View>
      <View style={styles.buttonContainer}>
        <Button
          mode="contained"
          disabled={buttonDisabled}
          onPress={_handleContinue}
        >
          {i18n.t('Continue')}
        </Button>
      </View>
    </DefaultView>
  );
}
Example #18
Source File: birth-date.screen.js    From astrale with GNU General Public License v3.0 4 votes vote down vote up
/**
 * @param navigation
 * @returns {*}
 * @constructor
 */
function BirthDateScreen({ navigation }) {
  const [{ session }, dispatch] = useGlobals();
  const { colors } = useTheme();
  const [date, setDate] = React.useState(new Date(642449499000));
  const [sign, setSign] = React.useState(
    ZodiacCalculator(date.getDate(), date.getMonth() + 1)
  );
  const [show, setShow] = React.useState(true);
  React.useLayoutEffect(() => {
    setSign(ZodiacCalculator(date.getDate(), date.getMonth() + 1));
  }, [date]);

  const onChange = (event, selectedDate) => {
    const currentDate = selectedDate || date;
    Platform.isAndroid && setShow(Platform.isIos);
    setDate(currentDate);
  };
  const showDatePicker = () => {
    setShow(true);
  };
  const _handleContinue = () => {
    dispatch({
      type: 'setSession',
      fields: { birthDate: date.getTime(), sign },
    });
    navigation.push('Sex');
  };

  return (
    <DefaultView>
      <SpaceSky />
      <Scorpio width={60} height={60} style={styles.scorpio} />
      <Backgrounds.ConstellationSimple
        color={colors.text}
        dotColor={colors.primary}
        height={200}
        width={200}
        style={styles.constellation}
      />
      <View style={{ flex: 1 }} />
      <View style={styles.textContainer}>
        <Headline style={styles.textHeadline}>
          {i18n.t('Your date of birth')}
        </Headline>
        <Text style={styles.textText}>
          {i18n.t(
            '{name}, to give you accurate and personal information we need to know some info',
            { name: session.name }
          )}
        </Text>
      </View>
      <View style={styles.logoContainer}>
        <Sign sign={sign} width={50} showTitle={false} height={50} />
      </View>
      <Surface style={styles.dateContainer}>
        {Platform.isAndroid && (
          <Button style={{ alignSelf: 'center' }} onPress={showDatePicker}>
            {i18n.t('Press to change')}
          </Button>
        )}
        {show && (
          <RNDateTimePicker
            value={date}
            display="spinner"
            onChange={onChange}
            on
            minimumDate={new Date(1930, 0, 0)}
            maximumDate={new Date(2010, 0, 0)}
            textColor="#ffffff"
          />
        )}
        {Platform.isAndroid && (
          <View style={{ justifyContent: 'center', alignItems: 'center' }}>
            <Text style={{ fontSize: 40 }}>{DateUtils.toEuropean(date)}</Text>
          </View>
        )}
      </Surface>
      <View style={styles.buttonContainer}>
        <Button mode="contained" disabled={!date} onPress={_handleContinue}>
          {i18n.t('Continue')}
        </Button>
      </View>
    </DefaultView>
  );
}
Example #19
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
AssetSearchbar = ({ setSelectedAsset, surveyingOrganization }) => {
  const [query, setQuery] = useState('');
  const [assetData, setAssetData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [online, setOnline] = useState(true);
  const [searchTimeout, setSearchTimeout] = useState(null);

  useEffect(() => {
    checkOnlineStatus().then(async (connected) => {
      if (connected) fetchData(true, '');
      if (!connected) fetchData(false, '');
    });
  }, [surveyingOrganization]);

  // remove this offline portion if he says no offline
  const fetchOfflineData = async () => {
    setOnline(false);

    await getData('assetData').then(() => {
      if (assetData) {
        let offlineData = [];
        getData('offlineAssetIDForms').then((offlineAssetData) => {
          if (offlineAssetData !== null) {
            Object.entries(offlineAssetData).forEach(([key, value]) => { //eslint-disable-line
              offlineData = offlineData.concat(value.localObject);
            });
          }
          const allData = assetData.concat(offlineData);
          setAssetData(allData.slice() || []);
        });
      }
      setLoading(false);
    });
  };

  const fetchOnlineData = async () => {
    setOnline(true);

    assetDataQuery(surveyingOrganization).then((records) => {
      let offlineData = [];

      getData('offlineAssetIDForms').then((offlineAssetData) => {
        if (offlineAssetData !== null) {
          Object.entries(offlineAssetData).forEach(([key, value]) => { //eslint-disable-line
            offlineData = offlineData.concat(value.localObject);
          });
        }
      });

      const allData = records.concat(offlineData);
      setAssetData(allData.slice());
      setLoading(false);
    });
  };

  const fetchData = (onLine, qry) => {
    // remove this line if no offline too - 82
    if (!onLine) fetchOfflineData();
    if (onLine) fetchOnlineData(qry);
  };

  // probably not needed, this is all specific to the id form
  const filterOfflineList = () => assetData.filter(
    (listItem) => {
      // const listItemJSON = listItem.toJSON();
      const name = listItem.name || ' ';
      return name.toLowerCase().includes(query.toLowerCase());
    }
  );

  const onChangeSearch = (input) => {
    setLoading(true);

    if (input === '') setLoading(false);

    clearTimeout(searchTimeout);

    setQuery(input);

    setSearchTimeout(setTimeout(() => {
      fetchData(online, input);
    }, 1000));
  };

  const onSelectAsset = (listItem) => {
    setSelectedAsset(listItem);
    setQuery('');
  };

  const renderItem = ({ item }) => (
    <View>
      <Button onPress={() => onSelectAsset(item)} contentStyle={{ marginRight: 5 }}>
        <Text style={{ marginRight: 10 }}>{item.name}</Text>

        <View style={{
          backgroundColor: '#f8380e',
          width: 1,
          height: 10,
          paddingLeft: 10,
          marginTop: 'auto',
          marginBottom: 'auto',
          borderRadius: 20
        }}
        />
      </Button>
    </View>
  );

  return (
    <View>
      <Headline style={styles.header}>{I18n.t('assetSearchbar.searchIndividual')}</Headline>
      <Searchbar
        placeholder={I18n.t('assetSearchbar.placeholder')}
        onChangeText={onChangeSearch}
        value={query}
      />
      {!online
        && <Button onPress={() => fetchData(false, '')}>{I18n.t('global.refresh')}</Button>}
      {loading
        && <Spinner color="blue" />}
      {query !== '' && (
        <FlatList
          data={filterOfflineList(assetData)}
          renderItem={renderItem}
          keyExtractor={(item) => item.objectId}
        />
      )}
    </View>
  );
}
Example #20
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
SettingsHome = ({
  logOut, settingsView, setSettingsView, setSettings,
  surveyingOrganization, scrollViewScroll, setScrollViewScroll
}) => {
  const [accountSettingsView, setAccountSettingsView] = useState('');
  const inputs = [
    {
      key: 'NamePhoneEmail',
      label: I18n.t('accountSettings.namePhoneEmail')
    },
    {
      key: 'ChangePassword',
      label: I18n.t('accountSettings.changePassword')
    },
    {
      key: 'FindRecords',
      label: I18n.t('accountSettings.findRecords')
    },
    {
      key: 'Language',
      label: I18n.t('accountSettings.language')
    },
    {
      key: 'OfflineData',
      label: I18n.t('accountSettings.offlineData')
    }
  ];

  return (
    <View>
      {settingsView === 'Settings' && accountSettingsView === '' && (
        <View>
          <View style={{ flexDirection: 'row', marginLeft: 'auto', marginRight: 'auto' }}>
            <View style={{ paddingRight: '5%' }}>
              <Button mode="contained">{I18n.t('accountSettings.settings')}</Button>
            </View>
            <View style={{ paddingLeft: '5%' }}>
              <Button onPress={() => setSettingsView('Support')}>
                {I18n.t('accountSettings.support')}
              </Button>
            </View>
          </View>
          <View style={{ paddingLeft: '5%', paddingRight: '5%', paddingTop: 20 }}>
            <Headline style={{ fontWeight: 'bold' }}>{I18n.t('accountSettings.accountSettings')}</Headline>
            <View style={styles.horizontalLineGray} />
            {inputs.length && inputs.map((input) => (
              <View key={input.key}>
                <View style={{ flexDirection: 'row' }}>
                  <Text style={styles.text}>{input.label}</Text>
                  <IconButton
                    icon="chevron-right"
                    size={30}
                    color={theme.colors.primary}
                    style={{ marginLeft: 'auto', marginTop: -5, marginBottom: -10 }}
                    onPress={() => {
                      setAccountSettingsView(input.key);
                    }}
                  />
                </View>
                <View style={styles.horizontalLineGray} />
              </View>
            ))}
          </View>
          <Button onPress={() => {
            setSettings(false);
          }}
          >
            {I18n.t('accountSettings.back')}
          </Button>
          <Button mode="contained" onPress={logOut} style={{ marginTop: 20, marginLeft: '5%', marginRight: '5%' }}>{I18n.t('accountSettings.logout')}</Button>
        </View>
      )}
      {accountSettingsView !== '' && (
        <View>
          <AccountSettings
            accountSettingsView={accountSettingsView}
            setAccountSettingsView={setAccountSettingsView}
            surveyingOrganization={surveyingOrganization}
            scrollViewScroll={scrollViewScroll}
            setScrollViewScroll={setScrollViewScroll}
          />
        </View>
      )}
    </View>
  );
}
Example #21
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
Password = () => {
  const [submitting, setSubmitting] = useState(false);
  const [currentState, setCurrentState] = useState('');
  const [newState, setNewState] = useState('');

  const wrongCredentials = () => {
    Alert.alert(
      I18n.t('global.error'),
      I18n.t('passwordSettings.wrongCreds'), [
        { text: 'OK' }
      ],
      { cancelable: true }
    );
  };

  const handleFailedAttempt = () => {
    Alert.alert(
      I18n.t('global.error'),
      I18n.t('passwordSettings.errorMessage'), [
        { text: 'OK' }
      ],
      { cancelable: true }
    );
  };

  const handleSucccessfullAttempt = () => {
    Alert.alert(
      I18n.t('global.success'),
      I18n.t('passwordSettings.successMessage'), [
        { text: 'OK' }
      ],
      { cancelable: true }
    );
  };

  const changePassword = async () => {
    setSubmitting(true);
    const currentUser = await getData('currentUser');

    if (currentState !== currentUser.password) {
      setSubmitting(false);
      wrongCredentials();
    } else {
      const user = await Parse.User.logIn(currentUser.username, currentUser.password);
      user.set('password', newState);

      const submitAction = () => {
        setTimeout(() => {
          setSubmitting(false);
          handleSucccessfullAttempt();
        }, 1000);
      };

      await user.save().then(async () => {
        currentUser.password = newState;
        await storeData(currentUser, 'currentUser').then(() => {
          submitAction();
        }, (error) => {
          console.log(error); //eslint-disable-line
          setSubmitting(false);
          handleFailedAttempt();
        });
      }, (error) => {
        console.log(error); //eslint-disable-line
        setSubmitting(false);
        handleFailedAttempt();
      });
    }
  };

  return (
    <View>
      <Headline>{I18n.t('passwordSettings.changePassword')}</Headline>
      <View style={styles.horizontalLinePrimary} />
      <View style={styles.lineContainer}>
        <Text style={styles.text}>{I18n.t('passwordSettings.currentPassword')}</Text>
        <TextInput mode="outlined" onChangeText={(text) => setCurrentState(text)} />
      </View>
      <View style={styles.lineContainer}>
        <Text style={styles.text}>{I18n.t('passwordSettings.newPassword')}</Text>
        <TextInput mode="outlined" onChangeText={(text) => setNewState(text)} />
      </View>
      {submitting ? (
        <ActivityIndicator
          size="large"
          color={theme.colors.primary}
        />
      ) : (
        <Button mode="contained" onPress={() => changePassword()}>{I18n.t('passwordSettings.changePassword')}</Button>
      )}
    </View>
  );
}
Example #22
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
NamePhoneEmail = () => {
  useEffect(() => {
    async function setUserInformation() {
      const currentUser = await getData('currentUser');
      setObjectId(currentUser.objectId);
      const fname = currentUser.firstname;
      const lname = currentUser.lastname;
      const phoneNumber = currentUser.phonenumber;
      const { email } = currentUser;

      setUserObject({
        firstName: fname,
        lastName: lname,
        phoneNumber,
        email
      });
    }
    setUserInformation().then(() => {
      setInputs([
        {
          label: I18n.t('namePhoneEmailSettings.userInformation.fname'),
          value: userObject.firstName,
          key: 'firstName'
        },
        {
          label: I18n.t('namePhoneEmailSettings.userInformation.lname'),
          value: userObject.lastName,
          key: 'lastName'
        },
        {
          label: I18n.t('namePhoneEmailSettings.userInformation.phoneNumber'),
          value: userObject.phoneNumber,
          key: 'phoneNumber'
        },
        {
          label: I18n.t('namePhoneEmailSettings.userInformation.email'),
          value: userObject.email,
          key: 'email'
        }
      ]);
      setUpdated(false);
    });
  }, [updated]);

  const [userObject, setUserObject] = useState({});
  const [edit, setEdit] = useState('');
  const [inputs, setInputs] = useState([]);
  const [objectId, setObjectId] = useState('');
  const [updated, setUpdated] = useState(false);
  const [submitting, setSubmitting] = useState(false);

  const updateUserObject = (key, text) => {
    const copyUserObject = userObject;
    copyUserObject[key] = text;
    setUserObject(copyUserObject);
  };

  const handleFailedAttempt = () => {
    Alert.alert(
      I18n.t('global.error'),
      I18n.t('namePhoneEmailSettings.errorMessage'), [
        { text: 'OK' }
      ],
      { cancelable: true }
    );
  };

  const handleSucccessfullAttempt = () => {
    Alert.alert(
      I18n.t('global.success'),
      I18n.t('namePhoneEmailSettings.successMessage'), [
        { text: 'OK' }
      ],
      { cancelable: true }
    );
  };

  const updateUser = async () => {
    setSubmitting(true);
    const postParams = {
      objectId,
      firstname: userObject.firstName,
      lastname: userObject.lastName,
      email: userObject.email,
      phonenumber: userObject.phoneNumber
    };
    const currentUser = await getData('currentUser');

    const user = await Parse.User.logIn(currentUser.username, currentUser.password);
    for (const key in postParams) { //eslint-disable-line
      user.set(String(key), postParams[key]);
    }

    const submitAction = () => {
      setTimeout(() => {
        setSubmitting(false);
        handleSucccessfullAttempt();
      }, 1000);
    };

    await user.save().then(async (updatedUser) => {
      await storeData(updatedUser, 'currentUser').then(() => {
        setUpdated(true);
        submitAction();
      }, (error) => {
        console.log(error); //eslint-disable-line
        setSubmitting(false);
        handleFailedAttempt();
      });
    }, (error) => {
      console.log(error); //eslint-disable-line
      setSubmitting(false);
      handleFailedAttempt();
    });
  };

  return (
    <View>
      <Headline>{I18n.t('namePhoneEmailSettings.namePhoneEmail')}</Headline>
      <View style={styles.horizontalLinePrimary} />
      {inputs.length > 0 && inputs.map((result) => (
        <View key={result.key}>
          <Text style={styles.text}>{result.label}</Text>
          <View>
            {edit !== result.key && (
              <View style={styles.textContainer}>
                <Text style={styles.text}>{userObject[result.key]}</Text>
                <Button
                  style={{ marginLeft: 'auto' }}
                  onPress={() => {
                    setEdit(result.key);
                  }}
                >
                  {I18n.t('findRecordSettings.edit')}
                </Button>
              </View>
            )}
            {edit === result.key && (
              <View style={styles.textContainer}>
                <TextInput
                  style={{ flex: 3 }}
                  placeholder={result.value}
                  mode="outlined"
                  onChangeText={(text) => updateUserObject(result.key, text)}
                />
                <View style={styles.buttonContainer}>
                  <IconButton
                    icon="check"
                    size={25}
                    color={theme.colors.primary}
                    style={styles.svg}
                    onPress={() => {
                      setEdit('');
                    }}
                  />
                  <IconButton
                    icon="window-close"
                    size={25}
                    color={theme.colors.primary}
                    style={styles.svg}
                    onPress={() => {
                      setEdit('');
                    }}
                  />
                </View>
              </View>
            )}
          </View>
          <View style={styles.horizontalLineGray} />

        </View>
      ))}
      {submitting ? (
        <ActivityIndicator
          size="large"
          color={theme.colors.primary}
        />
      ) : (
        <Button onPress={() => updateUser()}>{I18n.t('global.submit')}</Button>
      )}
    </View>
  );
}
Example #23
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
FindRecords = () => {
  useEffect(() => {
    async function setUserInformation() {
      const storedLimit = await getData('findRecordsLimit');
      const currentLimit = storedLimit === null || storedLimit === undefined ? 2000 : storedLimit;
      const residentData = await getData('residentData');
      const residentDataCount = residentData.length;

      setCurrentData({
        currentLimit,
        residentDataCount
      });
    }
    setUserInformation().then(() => {
      setInputs([
        {
          label: I18n.t('findRecordSettings.currentReccordsStored'),
          value: currentData.residentDataCount,
          key: 'residentDataCount',
          edit: false
        },
        {
          label: I18n.t('findRecordSettings.recordStorageLimit'),
          value: currentData.currentLimit,
          key: 'currentLimit',
          edit: true
        }
      ]);
      setUpdated(false);
    });
  }, [updated]);

  const handleFailedAttempt = () => {
    Alert.alert(
      I18n.t('global.error'),
      I18n.t('findRecordSettings.errorMessage'), [
        { text: I18n.t('global.ok') }
      ],
      { cancelable: true }
    );
  };

  const handleSucccessfullAttempt = () => {
    Alert.alert(
      I18n.t('global.success'),
      I18n.t('findRecordSettings.successMessage'), [
        { text: I18n.t('global.ok') }
      ],
      { cancelable: true }
    );
  };

  const updateUser = async () => {
    setSubmitting(true);

    const newLimit = currentData.currentLimit;

    const submitAction = () => {
      setTimeout(() => {
        setSubmitting(false);
        handleSucccessfullAttempt();
      }, 1000);
    };

    await storeData(newLimit, 'findRecordsLimit').then(() => {
      setUpdated(true);
      submitAction();
    }, (error) => {
      console.log(error); //eslint-disable-line
      setSubmitting(false);
      handleFailedAttempt();
    });
  };

  const updateCurrentData = (key, text) => {
    const copyUserObject = currentData;
    copyUserObject[key] = text;
    setCurrentData(copyUserObject);
  };

  const [currentData, setCurrentData] = useState({});
  const [edit, setEdit] = useState('');
  const [inputs, setInputs] = useState([]);
  const [updated, setUpdated] = useState(false);
  const [submitting, setSubmitting] = useState(false);

  return (
    <View>
      <Headline>{I18n.t('findRecordSettings.findRecords')}</Headline>
      <View style={styles.horizontalLinePrimary} />
      {inputs.length > 0 && inputs.map((result) => (
        <View key={result.key}>
          <Text style={styles.text}>{result.label}</Text>
          <View>
            {edit !== result.key && (
              <View style={styles.textContainer}>
                <Text style={styles.text}>{currentData[result.key]}</Text>
                {result.edit === true && (
                  <Button
                    style={{ marginLeft: 'auto' }}
                    onPress={() => {
                      setEdit(result.key);
                    }}
                  >
                    {I18n.t('findRecordSettings.edit')}
                  </Button>
                )}
              </View>
            )}
            {edit === result.key && (
              <View style={styles.textContainer}>
                <TextInput
                  style={{ flex: 3 }}
                  placeholder={result.value}
                  mode="outlined"
                  onChangeText={(text) => updateCurrentData(result.key, text)}
                />
                <View style={styles.buttonContainer}>
                  <IconButton
                    icon="check"
                    size={25}
                    color={theme.colors.primary}
                    style={styles.svg}
                    onPress={() => {
                      setEdit('');
                    }}
                  />
                  <IconButton
                    icon="window-close"
                    size={25}
                    color={theme.colors.primary}
                    style={styles.svg}
                    onPress={() => {
                      setEdit('');
                    }}
                  />
                </View>
              </View>
            )}
          </View>
          <View style={styles.horizontalLineGray} />

        </View>
      ))}
      {submitting ? (
        <ActivityIndicator
          size="large"
          color={theme.colors.primary}
        />
      ) : (
        <Button onPress={() => updateUser()}>{I18n.t('global.submit')}</Button>
      )}
    </View>
  );
}
Example #24
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
ResidentIdSearchbar = ({ surveyee, setSurveyee, surveyingOrganization }) => {
  const [query, setQuery] = useState('');
  const [residentsData, setResidentsData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [online, setOnline] = useState(true);
  const [searchTimeout, setSearchTimeout] = useState(null);
  const { residentOfflineData } = useContext(OfflineContext);

  useEffect(() => {
    checkOnlineStatus().then(async (connected) => {
      if (connected) fetchData(true, '');
      if (!connected) fetchData(false, '');
    });
  }, [surveyingOrganization]);

  const fetchOfflineData = async () => {
    setOnline(false);

    return residentOfflineData().then((residents) => {
      setResidentsData(residents);
      setLoading(false);
    });
  };

  const fetchOnlineData = async (qry) => {
    setOnline(true);

    const records = await parseSearch(surveyingOrganization, qry);

    let offlineData = [];

    await getData('offlineIDForms').then((offlineResidentData) => {
      if (offlineResidentData !== null) {
        Object.entries(offlineResidentData).forEach(([key, value]) => { //eslint-disable-line
          offlineData = offlineData.concat(value.localObject);
        });
      }
    });

    const allData = records.concat(offlineData);
    setResidentsData(allData.slice());
    setLoading(false);
  };

  const fetchData = (onLine, qry) => {
    if (!onLine) fetchOfflineData();
    if (onLine) fetchOnlineData(qry);
  };

  const filterOfflineList = () => residentsData.filter(
    (listItem) => {
      const fname = listItem.fname || ' ';
      const lname = listItem.lname || ' ';
      const nickname = listItem.nickname || ' ';
      return fname.toLowerCase().includes(query.toLowerCase())
        || lname
          .toLowerCase()
          .includes(query.toLowerCase())
        || `${fname} ${lname}`
          .toLowerCase()
          .includes(query.toLowerCase())
        || nickname
          .toLowerCase()
          .includes(query.toLowerCase());
    }
  );

  const onChangeSearch = (input) => {
    setLoading(true);

    if (input === '') setLoading(false);

    clearTimeout(searchTimeout);

    setQuery(input);

    setSearchTimeout(setTimeout(() => {
      fetchData(online, input);
    }, 1000));
  };

  const onSelectSurveyee = (listItem) => {
    setSurveyee(listItem);
    setQuery('');
  };

  const renderItem = ({ item }) => (
    <View>
      <Button onPress={() => onSelectSurveyee(item)} contentStyle={{ marginRight: 5 }}>
        <Text style={{ marginRight: 10 }}>{`${item?.fname || ''} ${item?.lname || ''}`}</Text>
        {/* offline IDform */}
        {item.objectId.includes('PatientID-') && (
          <View style={{
            backgroundColor: '#f8380e',
            width: 1,
            height: 10,
            paddingLeft: 10,
            marginTop: 'auto',
            marginBottom: 'auto',
            borderRadius: 20
          }}
          />
        )}
      </Button>
    </View>
  );

  return (
    <View>
      <Headline style={styles.header}>{I18n.t('residentIdSearchbar.searchIndividual')}</Headline>
      <Searchbar
        placeholder={I18n.t('findResident.typeHere')}
        onChangeText={onChangeSearch}
        value={query}
      />
      {!online
        && <Button onPress={() => fetchData(false, '')}>{I18n.t('global.refresh')}</Button>}
      {loading
        && <Spinner color="blue" />}

      {query !== '' && (
        <FlatList
          data={online ? residentsData : filterOfflineList(residentsData)}
          renderItem={renderItem}
          keyExtractor={(item) => item.objectId}
        />
      )}

      {surveyee && surveyee.objectId && (
        <ResidentCard resident={surveyee} />
      )}
    </View>
  );
}
Example #25
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
Header = ({
  setSettings
}) => {
  const { header, headerText, headerIcon } = styles;
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [volunteerDate, setVolunteerDate] = useState('');
  const [volunteerGreeting, setVolunteerGreeting] = useState('');
  const [offlineForms, setOfflineForms] = useState(false);
  const [offlineFormCount, setOfflineFormCount] = useState(0);
  const [submission, setSubmission] = useState(null);
  const [showCounts, setShowCounts] = useState(false);
  const { populateResidentDataCache, isLoading: isOfflineLoading } = useContext(OfflineContext);

  const volunteerLength = (object) => {
    const date = new Date(object.createdAt);
    const convertedDate = date.toDateString();
    return convertedDate;
  };

  const calculateTime = (name) => {
    const today = new Date();
    const curHr = today.getHours();

    if (curHr < 12) {
      setVolunteerGreeting(`${I18n.t('header.goodMorning')} ${name}!` || I18n.t('header.goodMorning!'));
    } else if (curHr < 18) {
      setVolunteerGreeting(`${I18n.t('header.goodAfternoon')} ${name}!` || I18n.t('header.goodAfternoon!'));
    } else {
      setVolunteerGreeting(`${I18n.t('header.goodEvening')} ${name}!` || I18n.t('header.goodEvening!'));
    }
  };

  const count = async () => {
    getData('currentUser').then((user) => {
      calculateTime(user.firstname);
      setVolunteerDate(volunteerLength(user));
    });

    const idFormCount = await getData('offlineIDForms').then((idForms) => {
      if (idForms) {
        setOfflineForms(true);
        return idForms.length;
      }
      return 0;
    });

    const supplementaryCount = await getData('offlineSupForms').then((supForms) => {
      if (supForms) {
        setOfflineForms(true);
        return supForms.length;
      }
      return 0;
    });

    const assetIdFormCount = await getData('offlineAssetIDForms').then((assetIdForms) => {
      if (assetIdForms) {
        setOfflineForms(true);
        return assetIdForms.length;
      }
      return 0;
    });

    const assetSupForms = await getData('offlineAssetSupForms').then((assetSuppForms) => {
      if (assetSuppForms) {
        setOfflineForms(true);
        return assetSuppForms.length;
      }
      return 0;
    });

    const allFormOfflineCount = idFormCount + supplementaryCount + assetIdFormCount + assetSupForms;

    setOfflineFormCount(allFormOfflineCount);

    setOfflineForms(allFormOfflineCount > 0);

    setDrawerOpen(!drawerOpen);
  };

  const postOffline = async () => {
    const user = await getData('currentUser');

    const surveyUser = await surveyingUserFailsafe(user, undefined, isEmpty);
    const { organization } = user;
    const appVersion = await getData('appVersion') || '';
    const phoneOS = Platform.OS || '';

    const idFormsAsync = await getData('offlineIDForms');
    const supplementaryFormsAsync = await getData('offlineSupForms');
    const assetIdFormsAsync = await getData('offlineAssetIDForms');
    const assetSupFormsAsync = await getData('offlineAssetSupForms');
    const householdsAsync = await getData('offlineHouseholds');
    const householdRelationsAsync = await getData('offlineHouseholdsRelation');

    const offlineParams = {
      surveyData: idFormsAsync,
      supForms: supplementaryFormsAsync,
      households: householdsAsync,
      householdRelations: householdRelationsAsync,
      assetIdForms: assetIdFormsAsync,
      assetSupForms: assetSupFormsAsync,
      surveyingUser: surveyUser,
      surveyingOrganization: organization,
      parseUser: user.objectId,
      appVersion,
      phoneOS
    };
    checkOnlineStatus().then((connected) => {
      if (connected) {
        postOfflineForms(offlineParams).then(async (result) => {
          if (result) {
            await deleteData('offlineIDForms');
            await deleteData('offlineSupForms');
            await deleteData('offlineAssetIDForms');
            await deleteData('offlineAssetSupForms');
            await deleteData('offlineHouseholds');
            await deleteData('offlineHouseholdsRelation');
            setOfflineForms(false);
            setSubmission(true);
          } else {
            setSubmission(false);
          }
        }).catch((error) => {
          // handle session token error
          handleParseError(error, postOfflineForms).then(async (result) => {
            if (result) {
              await deleteData('offlineIDForms');
              await deleteData('offlineSupForms');
              await deleteData('offlineAssetIDForms');
              await deleteData('offlineAssetSupForms');
              await deleteData('offlineHouseholds');
              await deleteData('offlineHouseholdsRelation');
              setOfflineForms(false);
              setSubmission(true);
            } else {
              setSubmission(false);
            }
          }, () => {
            setSubmission(false);
          });
        });
      } else {
        setSubmission(false);
      }
    });
  };

  const cacheOfflineData = async () => {
    checkOnlineStatus().then(async (connected) => {
      if (connected) await populateResidentDataCache();
    });
  };

  const navToSettings = () => {
    setDrawerOpen(false);
    setSettings(true);
  };

  const navToCounts = () => {
    setShowCounts(true);
  };

  return (
    <View style={styles.container}>
      <View style={header}>
        <Text style={headerText}>{I18n.t('header.puente')}</Text>
        <View style={headerIcon}>
          <IconButton
            color={headerIcon.color}
            size={30}
          />
        </View>
        <View style={headerIcon}>
          <IconButton
            icon="tune"
            color={headerIcon.color}
            size={30}
            onPress={navToSettings}
          />
        </View>
      </View>
      {drawerOpen === true
        && (
          <View>
            {showCounts === false ? (
              <View>
                <Headline style={styles.calculationText}>
                  {volunteerGreeting}
                  <Emoji name="coffee" />
                </Headline>
                <View style={{ flexDirection: 'row', alignSelf: 'center' }}>
                  <Text style={styles.calculationText}>{`${I18n.t('header.volunteerSince')}\n${volunteerDate}`}</Text>
                </View>
                {offlineForms ? (
                  <Button onPress={postOffline}>
                    {I18n.t('header.submitOffline')}
                  </Button>
                ) : (
                  <Button disabled>{I18n.t('header.submitOffline')}</Button>
                )}
                {isOfflineLoading ? (
                  <Spinner color="blue" />
                ) : (
                  <Button onPress={cacheOfflineData}>{I18n.t('header.populateOffline')}</Button>
                )}
                {submission === false && (
                  <View>
                    <Text style={styles.calculationText}>{I18n.t('header.failedAttempt')}</Text>
                    <Text style={{ alignSelf: 'center' }}>{I18n.t('header.tryAgain')}</Text>
                    <Button onPress={() => setSubmission(null)}>{I18n.t('header.ok')}</Button>
                  </View>
                )}
                {submission === true && (
                  <View>
                    <Text style={styles.calculationText}>{I18n.t('header.success')}</Text>
                    <Text style={{ alignSelf: 'center' }}>
                      {I18n.t('header.justSubmitted')}
                      {' '}
                      {offlineFormCount}
                      {' '}
                      {offlineFormCount > 1 && (
                        <Text>{I18n.t('header.forms')}</Text>)}
                      {offlineFormCount === 1 && (
                        <Text>{I18n.t('header.form')}</Text>)}
                    </Text>
                    <Button onPress={() => setSubmission(null)}>{I18n.t('header.ok')}</Button>
                  </View>
                )}
                <View style={{ flexDirection: 'row' }}>
                  <Button
                    style={styles.calculationTextLeft}
                    onPress={navToSettings}
                  >
                    {I18n.t('header.settingsPage')}
                  </Button>
                  <Button
                    style={styles.calculationTextRight}
                    onPress={navToCounts}
                  >
                    {I18n.t('header.surveysCollected')}
                  </Button>
                </View>
              </View>
            ) : (
              <FormCounts
                setShowCounts={setShowCounts}
              />
            )}
          </View>
        )}
      <IconButton
        size={3}
        style={{
          width: 70, backgroundColor: 'grey', alignSelf: 'center', opacity: 0.5
        }}
        onPress={count}
      />

    </View>
  );
}
Example #26
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
PaperInputPicker = ({
  data, formikProps, scrollViewScroll, setScrollViewScroll, surveyingOrganization,
  customForm, config, loopsAdded, setLoopsAdded,
  ...rest
}) => {
  const {
    label, formikKey, fieldType, sideLabel
  } = data;

  const {
    handleChange, handleBlur, errors, setFieldValue, values
  } = formikProps;

  const translatedLabel = customForm ? label : I18n.t(label);
  const translatedLabelSide = customForm ? sideLabel : I18n.t(sideLabel);

  const addArrayVal = (result) => {
    if (values[formikKey] || values[formikKey] === []) {
      setFieldValue(formikKey, values[formikKey].concat([result.value]));
    } else {
      setFieldValue(formikKey, [result.value]);
    }
  };

  const [cameraVisible, setCameraVisible] = React.useState(false);
  const [pictureUris, setPictureUris] = React.useState({});
  const [image, setImage] = React.useState(null);

  const [additionalQuestions, setAdditionalQuestions] = React.useState([]);

  return (
    <>
      {fieldType === 'input' && (
        <View style={stylesDefault.container} key={formikKey}>
          {translatedLabel.length > 30
            && <Text style={stylesDefault.label}>{translatedLabel}</Text>}
          <TextInput
            label={translatedLabel.length > 30 ? '' : translatedLabel}
            onChangeText={handleChange(formikKey)}
            onBlur={handleBlur(formikKey)}
            {...rest} //eslint-disable-line
            mode="outlined"
            theme={stylesPaper}
            style={stylesDefault.label}
          />
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'numberInput' && (
        <View style={stylesDefault.container} key={formikKey}>
          {translatedLabel.length > 30
            && (
              <Text style={[stylesDefault.label, {
                bottom: -15, zIndex: 1, left: 5, padding: 5
              }]}
              >
                {translatedLabel}
              </Text>
            )}
          <TextInput
            label={translatedLabel.length > 30 ? '' : translatedLabel}
            onChangeText={handleChange(formikKey)}
            onBlur={handleBlur(formikKey)}
            {...rest} //eslint-disable-line
            mode="outlined"
            keyboardType="numeric"
            theme={stylesPaper}
            style={stylesDefault.label}
          />
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'inputSideLabel' && (
        <View style={stylesDefault.container} key={formikKey}>
          <View style={{ flexDirection: 'row' }}>
            <TextInput
              label={translatedLabel}
              onChangeText={handleChange(formikKey)}
              onBlur={handleBlur(formikKey)}
              {...rest} //eslint-disable-line
              mode="outlined"
              theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
              style={{ flex: 1 }}
            />
            <Text style={styleX.sideLabel}>{translatedLabelSide}</Text>
          </View>
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'inputSideLabelNum' && (
        <View style={stylesDefault} key={formikKey}>
          <View style={{ flexDirection: 'row' }}>
            <TextInput
              label={translatedLabel}
              onChangeText={handleChange(formikKey)}
              onBlur={handleBlur(formikKey)}
              {...rest} //eslint-disable-line
              mode="outlined"
              keyboardType="numeric"
              theme={stylesPaper}
              style={{ flex: 1 }}
            />
            <Text style={styleX.sideLabel}>{translatedLabelSide}</Text>
          </View>
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'inputSideLabelTextQuestNumber' && (
        <View style={stylesDefault} key={formikKey}>
          <Text style={stylesDefault.label}>{translatedLabel}</Text>
          <View style={{ flexDirection: 'row' }}>
            <TextInput
              onChangeText={handleChange(formikKey)}
              onBlur={handleBlur(formikKey)}
              {...rest} //eslint-disable-line
              mode="outlined"
              keyboardType="numeric"
              theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
              style={{ flex: 1 }}
            />
            <Text style={styleX.sideLabel}>{translatedLabelSide}</Text>
          </View>
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'inputSideBySideLabel' && (
        <View style={stylesDefault} key={formikKey}>
          <View style={{ flexDirection: 'row' }}>
            <TextInput
              label={translatedLabel}
              onChangeText={handleChange(formikKey)}
              onBlur={handleBlur(formikKey)}
              {...rest} //eslint-disable-line
              mode="outlined"
              theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
              style={{ flex: 1 }}
            />
            <Text style={styleX.sideLabel}>{translatedLabelSide}</Text>
            <TextInput
              label={translatedLabel}
              onChangeText={handleChange(formikKey)}
              onBlur={handleBlur(formikKey)}
              {...rest} //eslint-disable-line
              mode="outlined"
              theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
              style={{ flex: 1 }}
            />
          </View>
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'select' && (
        <View key={formikKey} style={stylesDefault.container}>
          <Text style={[layout.selectLabel, stylesDefault.label]}>{translatedLabel}</Text>
          <View style={layout.buttonGroupContainer}>
            {data.options.map((result) => (
              <View key={result.value}>
                {/* selected value */}
                {result.value === values[formikKey] && (
                  <TouchableWithoutFeedback OnPress={() => setFieldValue(formikKey, result.value)}>
                    <View style={styleButton.selected}>

                      <View style={styles.button}>
                        <Text style={{ color: 'white' }}>{customForm ? result.label : I18n.t(result.label)}</Text>
                      </View>

                    </View>
                  </TouchableWithoutFeedback>
                )}
                {/* non-selected value */}
                {result.value !== values[formikKey] && (
                  <TouchableWithoutFeedback
                    onPress={() => setFieldValue(formikKey, result.value)}
                  >
                    <View style={styleButton.unselected}>
                      <Text style={{ color: theme.colors.primary }}>
                        {customForm ? result.label : I18n.t(result.label)}
                      </Text>
                    </View>

                  </TouchableWithoutFeedback>
                )}
              </View>
            ))}
          </View>
          {/* text input option along with select option */}
          {data.options.map((result) => (
            <View key={result.value}>
              {result.text === true && result.value === values[formikKey] && (
                <View style={stylesDefault} key={result.textKey}>
                  {result.textQuestion !== undefined && result.textQuestion.length > 0 && (
                    <Text>{customForm ? result.textQuestion : I18n.t(result.textQuestion)}</Text>
                  )}
                  <TextInput
                    label={customForm ? result.label : I18n.t(result.label)}
                    onChangeText={handleChange(result.textKey)}
                    onBlur={handleBlur(result.textKey)}
                    {...rest} //eslint-disable-line
                    mode="outlined"
                    theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
                  />
                  <Text style={{ color: 'red' }}>
                    {errors[result.textKey]}
                  </Text>
                </View>
              )}
            </View>
          ))}
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'selectMulti' && (
        <View key={formikKey} style={stylesDefault.container}>
          <Text style={[layout.selectLabel, stylesDefault.label]}>{translatedLabel}</Text>
          <View style={layout.buttonGroupContainer}>
            {data.options.map((result) => (
              <View key={result.value}>
                {/* selected value */}
                {values[formikKey] && values[formikKey].includes(result.value) && (
                  <View>
                    <TouchableWithoutFeedback
                      onPress={() => {
                        const test = values[formikKey].filter((item) => item !== result.value);
                        setFieldValue(formikKey, test);
                      }}
                    >
                      <View style={styleButton.selected}>
                        <View style={styles.button}>
                          <Text style={{ color: 'white' }}>{customForm ? result.label : I18n.t(result.label)}</Text>
                        </View>
                      </View>
                    </TouchableWithoutFeedback>
                  </View>
                )}
                {/* non-selected value */}
                {(!values[formikKey] || !(values[formikKey]).includes(result.value)) && (
                  <View style={stylesDefault}>
                    <TouchableWithoutFeedback
                      onPress={() => addArrayVal(result)}
                    >
                      <View style={styleButton.unselected}>
                        <Text style={{ color: theme.colors.primary }}>
                          {customForm ? result.label : I18n.t(result.label)}
                        </Text>
                      </View>
                    </TouchableWithoutFeedback>
                  </View>
                )}
              </View>
            ))}
          </View>
          {/* text input option along with select option */}
          {data.options.map((result) => (
            <View key={result.value}>
              {result.text === true && values[formikKey]
                && values[formikKey].includes(result.value) && (
                  <View style={stylesDefault} key={result.textKey}>
                    {result.textQuestion !== undefined && result.textQuestion.length > 0 && (
                      <Text>{customForm ? result.textQuestion : I18n.t(result.textQuestion)}</Text>
                    )}
                    <TextInput
                      label={customForm ? result.label : I18n.t(result.label)}
                      onChangeText={handleChange(result.textKey)}
                      onBlur={handleBlur(result.textKey)}
                      {...rest} //eslint-disable-line
                      mode="outlined"
                      theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
                    />
                    <Text style={{ color: 'red' }}>
                      {errors[result.textKey]}
                    </Text>
                  </View>
              )}
            </View>
          ))}
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'autofill' && (
        <View key={formikKey}>
          <AutoFill
            parameter={data.parameter}
            formikProps={formikProps}
            formikKey={formikKey}
            label={label}
            translatedLabel={translatedLabel}
            scrollViewScroll={scrollViewScroll}
            setScrollViewScroll={setScrollViewScroll}
          />
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'autofillms' && (
        <View key={formikKey}>
          <AutoFillMS
            parameter={data.parameter}
            formikProps={formikProps}
            formikKey={formikKey}
            label={label}
            translatedLabel={translatedLabel}
            scrollViewScroll={scrollViewScroll}
            setScrollViewScroll={setScrollViewScroll}
          />
          <Text style={{ color: 'red' }}>
            {errors[formikKey]}
          </Text>
        </View>
      )}
      {fieldType === 'geolocation' && (
        <Geolocation
          errors={errors}
          formikKey={formikKey}
          setFieldValue={setFieldValue}
        />
      )}
      {fieldType === 'household' && (
        <View key={formikKey}>
          <HouseholdManager
            formikProps={formikProps}
            formikKey={formikKey}
            surveyingOrganization={surveyingOrganization}
            values={values}
          />
        </View>
      )}
      {fieldType === 'header' && (
        <View key={translatedLabel} style={stylesDefault.container}>
          <Headline style={stylesDefault.header}>{translatedLabel}</Headline>
          <View
            style={stylesDefault.horizontalLine}
          />
        </View>
      )}
      {fieldType === 'multiInputRow' && (
        <View style={stylesDefault.container}>
          <Text style={stylesDefault.label}>{translatedLabel}</Text>
          <View style={stylesDefault.multiInputContainer}>
            {data.options.map((result) => (result.textSplit ? (
              <View key={`${result}`} style={{ flex: 1 }}>
                <Text style={styleX.textSplit}>{result.label}</Text>
              </View>
            ) : (
              <View key={result.value} style={stylesDefault.inputItem}>
                <TextInput
                  label={customForm ? result.label : I18n.t(result.label)}
                  onChangeText={handleChange(customForm ? result.label : I18n.t(result.label))}
                  onBlur={handleBlur(customForm ? result.label : I18n.t(result.label))}
                  {...rest} //eslint-disable-line
                  mode="outlined"
                  theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
                />
                <Text style={{ color: 'red' }}>
                  {errors[customForm ? result.label : I18n.t(result.label)]}
                </Text>
              </View>
            )))}
          </View>
        </View>
      )}
      {fieldType === 'multiInputRowNum' && (
      <View style={stylesDefault.container}>
        <Text style={stylesDefault.label}>{translatedLabel}</Text>
        <View style={stylesDefault.multiInputContainer}>
          {data.options.map((result) => (result.textSplit ? (
            <View key={`${result}`} style={{ flex: 1 }}>
              <Text style={styleX.textSplit}>{result.label}</Text>
            </View>
          ) : (
            <View key={result.value} style={stylesDefault.inputItem}>
              <TextInput
                label={customForm ? result.label : I18n.t(result.label)}
                onChangeText={handleChange(result.value)}
                onBlur={handleBlur(result.value)}
                    {...rest} //eslint-disable-line
                mode="outlined"
                keyboardType="numeric"
                maxLength={result.maxLength ? result.maxLength : null}
                theme={{ colors: { placeholder: theme.colors.primary }, text: 'black' }}
              />
              <Text style={{ color: 'red' }}>
                {errors[result.value]}
              </Text>
            </View>
          )))}
        </View>
      </View>
      )}
      {fieldType === 'photo' && (
        <View style={stylesDefault.container}>
          {!cameraVisible && image === null && (
            <View>
              <Text style={stylesDefault.labelImage}>{translatedLabel}</Text>
              <Button onPress={() => setCameraVisible(true)}>{I18n.t('paperButton.takePhoto')}</Button>
              <UseCameraRoll
                pictureUris={pictureUris}
                setPictureUris={setPictureUris}
                formikProps={formikProps}
                formikKey={formikKey}
                image={image}
                setImage={setImage}
              />
            </View>
          )}
          {!cameraVisible && image !== null && (
            <View>
              <Text style={stylesDefault.labelImage}>{translatedLabel}</Text>
              <Image source={{ uri: image }} style={{ width: 'auto', height: 400 }} />
              <Button onPress={() => {
                setCameraVisible(true);
              }}
              >
                {I18n.t('paperButton.takePhoto')}
              </Button>
              <UseCameraRoll
                pictureUris={pictureUris}
                setPictureUris={setPictureUris}
                formikProps={formikProps}
                formikKey={formikKey}
                image={image}
                setImage={setImage}
              />
            </View>
          )}
          {cameraVisible && (
            <View>
              <Text style={stylesDefault.labelImage}>{label}</Text>
              <UseCamera
                cameraVisible={cameraVisible}
                setCameraVisible={setCameraVisible}
                pictureUris={pictureUris}
                setPictureUris={setPictureUris}
                formikProps={formikProps}
                formikKey={formikKey}
                image={image}
                setImage={setImage}
              />
            </View>
          )}
        </View>
      )}
      {fieldType === 'loop' && (
      <View key={formikKey}>
        {additionalQuestions !== undefined && additionalQuestions.length !== 0
              && additionalQuestions.map((question) => (
                <PaperInputPicker
                  data={question}
                  formikProps={formikProps}
                  customForm={customForm}
                  config={config}
                  loopsAdded={loopsAdded}
                  setLoopsAdded={setLoopsAdded}
                  surveyingOrganization={surveyingOrganization}
                  scrollViewScroll={scrollViewScroll}
                  setScrollViewScroll={setScrollViewScroll}
                />
              ))}
        <Looper
          data={data}
          config={config}
          additionalQuestions={additionalQuestions}
          setAdditionalQuestions={setAdditionalQuestions}
          translatedLabel={translatedLabel}
          loopsAdded={loopsAdded}
          setLoopsAdded={setLoopsAdded}
        />
      </View>
      )}
      {/* relies on function to clean the values prior to submission */}
      {fieldType === 'loopSameForm' && (
        <View key={formikKey}>
          {additionalQuestions !== undefined && additionalQuestions.length !== 0
              && additionalQuestions.map((question) => (
                <PaperInputPicker
                  data={question}
                  formikProps={formikProps}
                  customForm={customForm}
                  config={config}
                  surveyingOrganization={surveyingOrganization}
                  scrollViewScroll={scrollViewScroll}
                  setScrollViewScroll={setScrollViewScroll}
                />
              ))}
          <Looper
            data={data}
            config={config}
            additionalQuestions={additionalQuestions}
            setAdditionalQuestions={setAdditionalQuestions}
            translatedLabel={translatedLabel}
            sameForm
          />
        </View>
      )}

    </>
  );
}
Example #27
Source File: index.js    From puente-reactnative-collect with MIT License 4 votes vote down vote up
FindResidents = ({
  selectPerson, setSelectPerson, organization, puenteForms, navigateToNewRecord,
  surveyee, setSurveyee, setView
}) => {
  const [query, setQuery] = useState('');
  const [residentsData, setResidentsData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [online, setOnline] = useState(true);
  const [searchTimeout, setSearchTimeout] = useState(null);
  const { residentOfflineData } = useContext(OfflineContext);

  useEffect(() => {
    checkOnlineStatus().then(async (connected) => {
      if (connected) fetchData(true, '');
      if (!connected) fetchData(false, '');
    });
  }, [organization]);

  const fetchOfflineData = () => {
    setOnline(false);
    return residentOfflineData().then((residents) => {
      setResidentsData(residents);
      setLoading(false);
    });
  };

  const fetchOnlineData = async (qry) => {
    setOnline(true);

    const records = await parseSearch(organization, qry);

    let offlineData = [];

    await getData('offlineIDForms').then((offlineResidentData) => {
      if (offlineResidentData !== null) {
        Object.entries(offlineResidentData).forEach(([key, value]) => { //eslint-disable-line
          offlineData = offlineData.concat(value.localObject);
        });
      }
    });

    const allData = records.concat(offlineData);
    setResidentsData(allData.slice());
    setLoading(false);
  };

  const fetchData = (onLine, qry) => {
    if (!onLine) fetchOfflineData();
    if (onLine) fetchOnlineData(qry);
  };

  const filterOfflineList = () => residentsData.filter(
    (listItem) => {
      const fname = listItem.fname || ' ';
      const lname = listItem.lname || ' ';
      const nickname = listItem.nickname || ' ';
      return fname.toLowerCase().includes(query.toLowerCase())
        || lname
          .toLowerCase()
          .includes(query.toLowerCase())
        || `${fname} ${lname}`
          .toLowerCase()
          .includes(query.toLowerCase())
        || nickname
          .toLowerCase()
          .includes(query.toLowerCase());
    }
  );

  const onChangeSearch = (input) => {
    setLoading(true);

    if (input === '') setLoading(false);

    clearTimeout(searchTimeout);

    setQuery(input);

    setSearchTimeout(setTimeout(() => {
      fetchData(online, input);
    }, 1000));
  };

  const onSelectPerson = (listItem) => {
    setSelectPerson(listItem);
    setQuery('');
  };

  const renderItem = ({ item }) => (
    <View key={item.objectId}>
      <ResidentCard
        resident={item}
        onSelectPerson={onSelectPerson}
      />
    </View>
  );

  return (
    <View>
      <View style={styles.container}>
        {!selectPerson && (
          <>
            <Headline style={styles.header}>{I18n.t('findResident.searchIndividual')}</Headline>
            <Searchbar
              placeholder={I18n.t('findResident.typeHere')}
              onChangeText={onChangeSearch}
              value={query}
            />
          </>
        )}

        {!online
          && <Button onPress={() => fetchData(false, '')}>{I18n.t('global.refresh')}</Button>}
        {loading
          && <Spinner color="blue" />}

        {!selectPerson
          && (
            <FlatList
              data={online ? residentsData : filterOfflineList(residentsData)}
              renderItem={renderItem}
              keyExtractor={(item) => item.objectId}
            />
          )}
      </View>

      {selectPerson && (
        <ResidentPage
          fname={selectPerson.fname}
          lname={selectPerson.lname}
          nickname={selectPerson.nickname}
          city={selectPerson.city}
          license={selectPerson.license}
          picture={selectPerson.picture}
          selectPerson={selectPerson}
          setSelectPerson={setSelectPerson}
          puenteForms={puenteForms}
          navigateToNewRecord={navigateToNewRecord}
          surveyee={surveyee}
          setSurveyee={setSurveyee}
          setView={setView}
        />
      )}
    </View>
  );
}