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 |
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 |
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 |
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 |
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 |
/**
* @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 |
/**
* @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 |
/**
* @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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
/**
* @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 |
/**
* @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 |
/**
* @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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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>
);
}