react-native-elements#Button TypeScript Examples

The following examples show how to use react-native-elements#Button. 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: Hotel.tsx    From wuhan2020-frontend-react-native-app with MIT License 6 votes vote down vote up
function Hotel({ item }: PropTypes) {
  const [visible, setVisible] = useState(false);
  const title = `${item.name} (${item.city})`;

  return (
    <Card title={title}>
      <View style={{ paddingHorizontal: 30, paddingTop: 10 }}>
        <View style={styles.subtitleContainer}>
          <Text style={[styles.subtitle, { fontSize: 14 }]}>{item.city}</Text>
          <Text style={styles.subtitle}>
            发布于{moment(item.date).fromNow()}
          </Text>
        </View>
        <ContactList data={item.contacts} />
        <Address {...item} />
        <Button
          type="outline"
          title="查看详情"
          onPress={() => setVisible(true)}
        />
        <WebViewModal
          uri={item.url}
          title={`${item.name}`}
          visible={visible}
          onClose={() => setVisible(false)}
        />
      </View>
    </Card>
  );
}
Example #2
Source File: APIClientUploadScreen.tsx    From react-native-network-client with Apache License 2.0 6 votes vote down vote up
UploadButton = (props: UploadButtonProps) => {
    const hasEndpoint = Boolean(props.endpoint);
    const hasFileUri = Boolean(props.fileUri);

    if (!hasEndpoint || !hasFileUri) {
        return null;
    }

    let title;
    let onPress;
    if (props.status === undefined) {
        title = "Upload File";
        onPress = () => props.upload();
    } else if (props.status === UploadStatus.UPLOADING) {
        title = "Cancel Upload";
        onPress = () => props.cancelUpload();
    } else if (props.status === UploadStatus.FAILED) {
        title = "Reset";
        onPress = () => props.resetState();
    }

    return (
        <View style={{ flex: 1 }}>
            <View style={{ flex: 1, padding: 10 }}>
                <Button title={title} onPress={onPress} />
            </View>
        </View>
    );
}
Example #3
Source File: CartFooter.tsx    From magento_react_native_graphql with MIT License 6 votes vote down vote up
CartFooter = ({
  grandTotal,
  handlePlaceOrder,
}: Props): React.ReactElement => {
  const { theme } = useContext(ThemeContext);
  const containerStyle = useMemo(
    () => ({
      backgroundColor: theme.colors?.white,
      borderColor: theme.colors?.divider,
    }),
    [theme],
  );
  return (
    <View style={[styles.container, containerStyle]}>
      {grandTotal && (
        <Text h4>{`${translate('common.total')} : ${formatPrice(
          grandTotal,
        )}`}</Text>
      )}
      <Button
        containerStyle={styles.placeOrder}
        title={translate('cartScreen.placeOrderButton')}
        onPress={handlePlaceOrder}
      />
    </View>
  );
}
Example #4
Source File: APIClientDownloadScreen.tsx    From react-native-network-client with Apache License 2.0 6 votes vote down vote up
DownloadButton = (props: DownloadButtonProps) => {
    const hasEndpoint = Boolean(props.endpoint);
    const hasFilePath = Boolean(props.filePath);

    if (!hasEndpoint || !hasFilePath) {
        return null;
    }

    let title;
    let onPress;
    if (props.status === undefined) {
        title = "Download File";
        onPress = () => props.download();
    } else if (props.status === DownloadStatus.DOWNLOADING) {
        title = "Cancel Download";
        onPress = () => props.cancelDownload();
    } else if (props.status === DownloadStatus.FAILED) {
        title = "Reset";
        onPress = () => props.resetState();
    }

    return (
        <View style={{ flex: 1 }}>
            <View style={{ flex: 1, padding: 10 }}>
                <Button title={title} onPress={onPress} />
            </View>
        </View>
    );
}
Example #5
Source File: ProfileScreen.tsx    From magento_react_native_graphql with MIT License 6 votes vote down vote up
ProfileScreen = ({ navigation }: Props): React.ReactElement => {
  const { getCustomer, data, loading, error } = useCustomer();
  const { logout } = useLogout();

  useEffect(() => {
    getCustomer();
  }, []);

  const handleLogout = () => {
    logout();
    navigation.jumpTo(Routes.NAVIGATION_TO_HOME_SCREEN);
  };

  if (error?.message) {
    return (
      <View>
        <Text>{error.message}</Text>
        <Button title={translate('common.logout')} onPress={handleLogout} />
      </View>
    );
  }

  return (
    <GenericTemplate loading={loading}>
      <Text>
        {translate('profileScreen.greeting', {
          name: data?.customer?.firstName ?? translate('common.user'),
        })}
      </Text>
      <Button title={translate('common.logout')} onPress={handleLogout} />
    </GenericTemplate>
  );
}
Example #6
Source File: Consultation.tsx    From wuhan2020-frontend-react-native-app with MIT License 6 votes vote down vote up
function Consultation({ item }: PropTypes) {
  const [visible, setVisible] = useState(false);

  return (
    <Card title={`${item.name}`}>
      <View style={styles.subtitleContainer}>
        <Text style={styles.subtitle}>发布于{moment(item.date).fromNow()}</Text>
      </View>
      <ContactList data={item.contacts} />
      <View>
        <H3 title="内容" />
        <Text style={{ marginVertical: 5 }}>{item.remark}</Text>
      </View>

      <View style={{ paddingHorizontal: 30, paddingTop: 10 }}>
        <Button
          type="outline"
          title="查看详情"
          onPress={() => setVisible(true)}
        />
        <WebViewModal
          uri={item.url}
          title={`${item.name}`}
          visible={visible}
          onClose={() => setVisible(false)}
        />
      </View>
    </Card>
  );
}
Example #7
Source File: AlphaWarning.tsx    From ito-app with GNU General Public License v3.0 6 votes vote down vote up
AlphaWarning: React.FC<AlphaWarningProps> = ({navigation}) => {
  const {t} = useTranslation();

  return (
    <View style={styles.container}>
      <View style={styles.logoWrapper}>
        <Text style={styles.logo}>ito</Text>
        <Text style={styles.subtitle}>track infections, not people!</Text>
        <AlphaNotice
          rootStyle={styles.alphaNoticeRoot}
          textStyle={styles.alphaNoticeText}
        />
      </View>
      <View>
        <Text style={styles.generalText}>{t('alphaWarning.demoPurpose')}</Text>
        <Text style={styles.generalText}>
          {t('alphaWarning.notFullyImplemented')}
        </Text>
        <Text style={styles.generalText}>{t('alphaWarning.review')}</Text>
      </View>
      <Text
        style={[styles.generalText, styles.githubLink]}
        onPress={(): Promise<void> =>
          Linking.openURL('https://github.com/ito-org/ito-app/issues')
        }>
        https://github.com/ito-org/ito-app/issues
      </Text>
      <View style={styles.bottomButtonContainer}>
        <Button
          title={t('alphaWarning.start')}
          onPress={(): void => navigation.navigate('Onboarding')}
          titleStyle={styles.buttonHowTitle}
          buttonStyle={styles.buttonHow}
        />
      </View>
    </View>
  );
}
Example #8
Source File: Cart.component.tsx    From react-native-woocommerce with MIT License 6 votes vote down vote up
Browse = (props: Props): JSX.Element => {
  const {
    products,
    resetCart,
    total,
    handleCheckoutPress
  } = props;

  return (
    <>
      <View style={styles.cartOverview}>
        <View style={styles.leftCartOverview}>
          <Icon
            reverse
            name="trash-alt"
            type="font-awesome-5"
            onPress={(): void => resetCart()}
          />
          <Text style={styles.textTotal}>{`Total:\n${toAmount(total)}`}</Text>
        </View>
        <Button
          title="Checkout"
          onPress={(): void => handleCheckoutPress()}
        />
      </View>
      <FlatList
        contentContainerStyle={styles.container}
        data={products}
        renderItem={_renderProduct(props)}
        keyExtractor={(item): string => `${item.id}`}
        numColumns={2}
      />
    </>
  );
}
Example #9
Source File: Logistic.tsx    From wuhan2020-frontend-react-native-app with MIT License 6 votes vote down vote up
function Logistic({ item }: PropTypes) {
  const [visible, setVisible] = useState(false);

  const title = `${item.name} - (${item.from} - ${item.dest})`;
  return (
    <Card title={title}>
      <View style={styles.subtitleContainer}>
        <Text style={styles.subtitle}>发布于{moment(item.date).fromNow()}</Text>
      </View>
      <ContactList data={item.contacts} />
      <Remark remark={item.remark} />

      <View>
        <H3 title="可否载人" />
        <Text style={{ marginVertical: 5 }}>
          {item.allowPersonal ? '是' : '否'}
        </Text>
      </View>
      <View style={{ paddingHorizontal: 30, paddingTop: 10 }}>
        <Button
          type="outline"
          title="查看详情"
          onPress={() => setVisible(true)}
        />
        <WebViewModal
          uri={item.url}
          title={title}
          visible={visible}
          onClose={() => setVisible(false)}
        />
      </View>
    </Card>
  );
}
Example #10
Source File: DetailScreen.tsx    From react-native-sdk with MIT License 6 votes vote down vote up
render() {
    const coffee = this.props.route.params.coffee
    return (
      <View style={styles.container}>
        <Image resizeMode="contain" style={styles.image} source={coffee.icon} />
        <Text style={styles.text}>{coffee.name}. {coffee.subtitle}</Text>
        <Button buttonStyle={styles.button} titleStyle={styles.buttonText} title="Buy Now" onPress={this.buyTapped} />
      </View>
    )
  }
Example #11
Source File: draft-item.tsx    From bext with MIT License 6 votes vote down vote up
DraftItem: FC<{
  draft: Draft;
  onDelete: () => void;
  onPress: () => void;
}> = ({ draft, onDelete, onPress }) => {
  const updateAt = useMemo(
    () => dayjs(draft.update_at).format('LLL'),
    [draft.update_at],
  );

  return (
    <ListItem.Swipeable
      bottomDivider
      onPress={onPress}
      rightContent={
        <Button
          title="删除"
          buttonStyle={styles.deleteButton}
          icon={{ name: 'delete', color: 'white' }}
          onPress={onDelete}
        />
      }
    >
      <ListItem.Content>
        <ListItem.Title>{draft.name}</ListItem.Title>
        <ListItem.Subtitle>更新于 {updateAt}</ListItem.Subtitle>
      </ListItem.Content>
      <ListItem.Chevron />
    </ListItem.Swipeable>
  );
}
Example #12
Source File: ProductItem.component.tsx    From RNWCShop with GNU General Public License v3.0 6 votes vote down vote up
_renderCartDetail = ({
  product,
  quantity = 0,
  subQuantity = noop,
  addQuantity = noop,
  removeFromCart = noop
}: Props): JSX.Element => (
  <>
    <View style={styles.actionView}>
      <Icon
        name="minus"
        type="font-awesome-5"
        onPress={(): void => subQuantity(product.id)}
      />
      <Text>Quantity: {quantity}</Text>
      <Icon
        name="plus"
        type="font-awesome-5"
        onPress={(): void => addQuantity(product.id)}
      />
    </View>
    <Button title="Remove" onPress={(): void => removeFromCart(product.id)} />
  </>
)
Example #13
Source File: ProductItem.component.tsx    From react-native-woocommerce with MIT License 6 votes vote down vote up
_renderCartDetail = ({
  product,
  quantity = 0,
  subQuantity,
  addQuantity,
  removeFromCart
}: Props): JSX.Element => (
  <>
    <View style={styles.actionView}>
      <Icon
        name='minus'
        type='font-awesome-5'
        onPress={(): void => subQuantity(product.id)}
      />
      <Text>Quantity: {quantity}</Text>
      <Icon
        name='plus'
        type='font-awesome-5'
        onPress={(): void => addQuantity(product.id)}
      />
    </View>
    <Button
      title="Remove"
      onPress={(): void => removeFromCart(product.id)}
    />
  </>
)
Example #14
Source File: AgreementPolicy.tsx    From SQUID with MIT License 5 votes vote down vote up
AgreementPolicy = () => {
  const navigation = useNavigation()
  return (
    <SafeAreaView style={styles.container}>
      <StatusBar backgroundColor={'white'} barStyle="light-content" />
      <FormHeader>
        <View style={styles.header}>
          <Text style={styles.title}>{I18n.t('term_and_conditions')}</Text>
          <Text style={styles.subtitle}>{I18n.t('before_usage')}</Text>
          <Text style={styles.subtitle}>{I18n.t('please_accept_terms')}</Text>
        </View>
      </FormHeader>
      <View style={styles.content}>
        <ScrollView
          contentContainerStyle={{
            flexGrow: 1,
            paddingVertical: 16,
          }}
        >
          <View style={{ paddingHorizontal: 24 }}>
            <Text style={styles.agreement}>{getAgreementText()} </Text>
          </View>
        </ScrollView>
      </View>
      {/* <CheckBox
        title="ฉันยอมรับ{I18n.t('term_and_conditions')}"
        containerStyle={{
          backgroundColor: 'transparent',
          borderWidth: 0,
          marginBottom: 16,
        }}
        checked={agree}
        onPress={() => setAgree(!agree)}
        checkedColor={COLORS.BLUE}
        textStyle={{ color: COLORS.BLACK_1, fontSize: FONT_SIZES[600], fontWeight:'normal'}}
        fontFamily={FONT_BOLD}
      /> */}
      <View style={styles.footer}>
        <PrimaryButton
          // disabled={!agree}
          title={I18n.t('accept')}
          style={{ width: '100%' }}
          containerStyle={{ width: '100%', marginTop: normalize(16) }}
          onPress={() => {
            applicationState.setData('skipRegistration', true)
            navigation.navigate('Onboarding')
          }}
        />
        <Button
          type="outline"
          title={I18n.t('deny')}
          style={{ width: '100%' }}
          titleStyle={{
            fontFamily: FONT_MED,
            fontSize: FONT_SIZES[600],
            lineHeight: 30,
          }}
          containerStyle={{ width: '100%', marginTop: 8 }}
          onPress={() => {
            navigation.pop()
          }}
        />
      </View>
    </SafeAreaView>
  )
}
Example #15
Source File: Hospital.tsx    From wuhan2020-frontend-react-native-app with MIT License 5 votes vote down vote up
function Hospital({ item }: PropTypes) {
  const { supplies } = item;
  const [visible, setVisible] = useState(false);
  return (
    <Card title={item.name}>
      <View style={styles.subtitleContainer}>
        <Text style={[styles.subtitle, { fontSize: 14 }]}>
          {item.city} - {item.province || ''}
        </Text>
        <Text style={styles.subtitle}>{item.district}</Text>
      </View>
      <View style={styles.supplyContainer}>
        <View>
          {supplies.slice(0, 3).map(supply => (
            <Supply item={supply} />
          ))}
          {supplies.length - 3 > 0 ? (
            <Text style={styles.supplyInfo}>
              +{supplies.length - 3}项其他物资
            </Text>
          ) : null}
        </View>
      </View>
      <View style={{ paddingHorizontal: 30, paddingTop: 10 }}>
        <Button
          type="outline"
          title="查看详情"
          onPress={() => setVisible(true)}
        />
        <Modal
          animationType="fade"
          presentationStyle="formSheet"
          transparent={false}
          onDismiss={() => {
            setVisible(false);
          }}
          onRequestClose={() => {
            setVisible(false);
          }}
          visible={visible}>
          <View style={{ padding: 16, justifyContent: 'space-between' }}>
            <View style={{ height: height - 150 }}>
              <HospitalDetail item={item} />
            </View>
            <View>
              <Button
                title="关闭详情"
                onPress={() => {
                  setVisible(false);
                }}
              />
            </View>
          </View>
        </Modal>
      </View>
    </Card>
  );
}
Example #16
Source File: Camera.tsx    From save-food with MIT License 5 votes vote down vote up
Camera = ({ navigation }: Props) => {
	const cameraRef = useRef<any>()

	const [loading, setLoading] = useState<boolean>(false)
	const [buttonTitle, setButtonTitle] = useState<string>()

	const takePhotoHandler = async () => {
		setLoading(true)
		const takePhoto = navigation.getParam('takePhoto', undefined)

		if (cameraRef.current && takePhoto) {
			await cameraRef.current.takePictureAsync({
				onPictureSaved: ({ uri }: { uri: string }) => {
					takePhoto(uri)
					navigation.goBack()
				},
			})
		}
	}

	useEffect(() => {
		const buttonTitle = navigation.getParam('buttonTitle', undefined)

		if (buttonTitle) {
			setButtonTitle(buttonTitle)
		} else {
			navigation.goBack()
		}

		return () => {
			setLoading(false)
		}
	}, [])

	return (
		<CameraComponent
			style={styles.camera}
			ratio='16:9'
			type={CameraComponent.Constants.Type.back}
			ref={cameraRef}
		>
			<Icon onPress={() => navigation.goBack()} variant='exitIcon' />

			{loading && (
				<View style={styles.loading}>
					<Spinner bgColor='transparency' size={64} />
				</View>
			)}

			<View style={[styles.takePhotoButtonWrapper, shadow]}>
				<Button
					disabled={loading}
					onPress={takePhotoHandler}
					buttonStyle={styles.takeFoodButton}
					titleStyle={styles.takeFoodButtonTitle}
					title={buttonTitle}
				/>
			</View>
		</CameraComponent>
	)
}
Example #17
Source File: RecommendationList.tsx    From wuhan2020-frontend-react-native-app with MIT License 5 votes vote down vote up
function Entry(props: EntryPropsType) {
  const [visible, setVisible] = useState(false);
  const [loadingWebview, setLoading] = useState(true);

  return (
    <View>
      <ListItem
        onPress={() => setVisible(true)}
        Component={TouchableOpacity}
        title={<Text style={{ fontWeight: '800' }}>{props.title}</Text>}
        subtitle={
          <Text style={{ fontSize: 12, paddingTop: 3 }}>
            修改时间:
            {formatDate(props.modifyTime)} from {props.operator}
          </Text>
        }
        leftAvatar={{ source: { uri: props.imgUrl } }}
        rightIcon={{ name: 'unfold-more' }}
      />
      <Modal
        animationType="fade"
        presentationStyle="pageSheet"
        visible={visible}
        onDismiss={() => {
          setVisible(false);
        }}
        onRequestClose={() => {
          setVisible(false);
        }}>
        <View style={{ padding: 16, justifyContent: 'space-between' }}>
          {loadingWebview ? (
            <ActivityIndicator size="large" color="red" />
          ) : null}
          <View style={{ height: height - 150 }}>
            <WebView
              onLoad={() => setLoading(true)}
              onLoadEnd={() => setLoading(false)}
              source={{ uri: props.linkUrl }}
            />
          </View>
          <View>
            <Button
              buttonStyle={styles.button}
              title="关闭预览"
              onPress={() => {
                setVisible(false);
              }}
            />
          </View>
        </View>
      </Modal>
    </View>
  );
}
Example #18
Source File: LoginScreen.tsx    From magento_react_native_graphql with MIT License 5 votes vote down vote up
LoginScreen = ({ navigation }: Props): React.ReactElement => {
  const {
    values,
    loading,
    data,
    error,
    handleChange,
    handleSubmit,
  } = useLogin();

  useEffect(() => {
    if (data?.generateCustomerToken?.token) {
      showMessage({
        message: translate('common.success'),
        description: translate('loginScreen.successMessage'),
        type: 'success',
      });
      navigation.navigate(Routes.NAVIGATION_TO_HOME_SCREEN);
    }
  }, [data]);

  useEffect(() => {
    if (error) {
      showMessage({
        message: translate('common.error'),
        description: error.message ?? translate('errors.genericError'),
        type: 'danger',
      });
    }
  }, [error]);

  return (
    <GenericTemplate style={styles.container}>
      <Input
        value={values.email}
        editable={!loading}
        leftIcon={{ name: 'email' }}
        placeholder="[email protected]"
        label={translate('common.email')}
        onChangeText={handleChange('email')}
      />
      <Input
        secureTextEntry={values.secureTextEntry}
        editable={!loading}
        value={values.password}
        leftIcon={{ name: 'lock' }}
        rightIcon={{
          name: values.secureTextEntry ? 'eye' : 'eye-off',
          type: 'material-community',
          onPress: handleChange('secureTextEntry').bind(
            {},
            !values.secureTextEntry,
          ),
        }}
        label={translate('common.password')}
        onChangeText={handleChange('password')}
        placeholder={translate('common.password')}
      />
      <Button
        loading={loading}
        onPress={handleSubmit}
        title={translate('common.login')}
        containerStyle={styles.submitButton}
      />
      <Button
        type="clear"
        disabled={loading}
        title={translate('loginScreen.noAccount')}
        onPress={() => navigation.navigate(Routes.NAVIGATION_TO_SIGNUP_SCREEN)}
      />
    </GenericTemplate>
  );
}
Example #19
Source File: Webview.tsx    From wuhan2020-frontend-react-native-app with MIT License 5 votes vote down vote up
function WebViewModal({
  uri,
  title,
  visible,
  onClose,
}: {
  uri: string;
  title: string;
  visible: boolean;
  onClose: () => void;
}) {
  const [loadingWebview, setLoading] = useState(true);

  return (
    <Modal
      animationType="fade"
      presentationStyle="pageSheet"
      visible={visible}
      onDismiss={onClose}
      onRequestClose={onClose}>
      <View style={{ padding: 16, justifyContent: 'space-between' }}>
        <View style={{ height: height - 150 }}>
          <H1 title={title} />
          {loadingWebview ? (
            <View style={{ paddingVertical: 20 }}>
              <Loader />
            </View>
          ) : null}
          <WebView
            onLoad={() => setLoading(true)}
            onLoadEnd={() => setLoading(false)}
            source={{ uri }}
          />
        </View>
        <View>
          <Button
            buttonStyle={styles.button}
            title="关闭预览"
            onPress={onClose}
          />
        </View>
      </View>
    </Modal>
  );
}
Example #20
Source File: MattermostClientUploadScreen.tsx    From react-native-network-client with Apache License 2.0 5 votes vote down vote up
UploadButton = (props: UploadButtonProps) => {
    const hasChannelId = Boolean(props.channelId);
    const hasSessionId = Boolean(props.sessionId);
    const hasFileUri = Boolean(props.fileUri);

    if (!hasChannelId || !hasFileUri) {
        return null;
    }

    let title;
    let onPress;
    let error;
    let reset;
    if (!hasSessionId) {
        title = "Create Upload Session";
        onPress = () => props.createUploadSession();
    } else if (props.status === undefined) {
        title = "Upload File";
        onPress = () => props.upload();
    } else if (props.status === UploadStatus.UPLOADING) {
        title = "Cancel Upload";
        onPress = () => props.cancelUpload();
    } else if (props.status === UploadStatus.FAILED) {
        title = "Resume";
        onPress = () => props.resumeUpload();
        error = "Upload error";
        reset = true;
    } else if (props.status === UploadStatus.COMPLETED) {
        title = "Post";
        onPress = () => props.post();
    } else if (props.status === UploadStatus.POST_FAILED) {
        title = "Retry post";
        onPress = () => props.post();
    }

    return (
        <View style={{ flex: 1 }}>
            {error && (
                <Text
                    style={{
                        color: "red",
                        alignSelf: "center",
                        padding: 10,
                    }}
                >
                    {error}
                </Text>
            )}
            <View
                style={{
                    flex: 1,
                    flexDirection: "row",
                    justifyContent: "space-evenly",
                }}
            >
                <View style={{ flex: 1, paddingHorizontal: 10 }}>
                    <Button title={title} onPress={onPress} />
                </View>
                {reset && (
                    <View style={{ flex: 1, paddingHorizontal: 10 }}>
                        <Button title="Reset" onPress={props.resetState} />
                    </View>
                )}
            </View>
        </View>
    );
}
Example #21
Source File: Detail.component.tsx    From RNWCShop with GNU General Public License v3.0 5 votes vote down vote up
render(): JSX.Element {
    const {
      product,
      imagesShown,
      handleShowImages,
      addToCart = () => {}
    } = this.props;
    const {
      name,
      images,
      description,
      price,
      average_rating: rating
    } = product;

    return (
      <ScrollView style={styles.wrapper}>
        <Carousel
          ref={this._setCarousel}
          sliderWidth={screenWidth}
          sliderHeight={screenWidth}
          itemWidth={screenWidth - 60}
          data={this._mapImages(images)}
          renderItem={this._renderImageItem(handleShowImages)}
          hasParallaxImages
        />
        <View style={styles.detail}>
          <Text style={styles.textTitle}>{name}</Text>
          <Text style={styles.textPrice}>{toAmount(price)}</Text>
          <HTML html={description} textSelectable />
          <View style={styles.rating}>
            <Text style={styles.textSubHeading}>Rating:</Text>
            <Text style={styles.textRating}>{rating}</Text>
            <Rating readonly imageSize={20} startingValue={Number(rating)} />
          </View>
          <Button
            icon={{
              name: 'cart-plus',
              type: 'font-awesome-5',
              color: 'white',
              size: 16
            }}
            title="Add to cart"
            onPress={(): void => addToCart(product)}
          />
        </View>
        <Modal visible={imagesShown} transparent>
          {this._renderImages(images, handleShowImages)}
        </Modal>
      </ScrollView>
    );
  }
Example #22
Source File: ResponseErrorOverlay.tsx    From react-native-network-client with Apache License 2.0 5 votes vote down vote up
ResponseErrorOverlay = ({
    error,
    visible,
    setVisible,
}: ResponseErrorOverlayProps) => {
    const hide = () => setVisible(false);

    return (
        <Overlay
            isVisible={visible}
            onBackdropPress={hide}
            overlayStyle={{ marginHorizontal: 20, marginVertical: 40 }}
            testID="response_error_overlay"
        >
            <>
                <Button title="Close" onPress={hide} />
                <Text h2 style={{ alignSelf: "center" }}>
                    Error
                </Text>
                <Text h4>Code</Text>
                <Text testID="response_error_overlay.error.code.text">
                    {error?.code}
                </Text>
                <Divider />
                <Text h4>Message</Text>
                <Text testID="response_error_overlay.error.message.text">
                    {error?.message}
                </Text>
                <Divider />
                <Text h4>Domain</Text>
                <Text testID="response_error_overlay.error.domain.text">
                    {error?.domain}
                </Text>
                <Divider />
                <Text h4>User Info</Text>
                <Text testID="response_error_overlay.error.user_info.text">
                    {JSON.stringify(error?.userInfo)}
                </Text>
                <Divider />
                <Text h4>Native Stack</Text>
                <ScrollView>
                    <Text testID="response_error_overlay.error.native_stack.text">
                        {JSON.stringify(
                            error?.nativeStackAndroid || error?.nativeStackIOS
                        )}
                    </Text>
                </ScrollView>
            </>
        </Overlay>
    );
}
Example #23
Source File: Food.tsx    From save-food with MIT License 4 votes vote down vote up
Food = ({ navigation }: Props) => {
	const { useSubscribe } = useSettingsContext()
	const settings = useSubscribe((s) => s.settings)
	const translations = useSubscribe((s) => ({ ...s.translations.Food, ...s.translations.common }))

	const [savedData, setSavedData] = useState<WastedFood>(initialData)
	const [templateData, setTemplateData] = useState<WastedFood>(initialData)
	const [loading, setLoading] = useState(true)
	const [saveFoodBeforeModalHide, setSaveFoodBeforeModalHide] = useState(false)
	const [hasChanges, setHasChanges] = useState(false)
	const [showModal, setShowModal] = useState(false)
	const [modalType, setModalType] = useState<ModalType>('id')
	const [modalContent, setModalContent] = useState<ReactNode>()
	const [controls, setControls] = useState<InputsControl>({
		name: {
			label: translations.foodNameLabel,
			required: true,
			characterRestriction: 70,
		},
		quantity: {
			label: translations.quantityLabel,
			keyboardType: 'numeric',
			required: true,
			characterRestriction: 5,
			number: true,
			positiveNumber: true,
			precision: 0,
		},
		price: {
			label: translations.priceLabel,
			keyboardType: 'numeric',
			required: true,
			characterRestriction: 7,
			number: true,
			positiveNumber: true,
			precision: 2,
		},
	})

	const correctPrice = !!(savedData.price && !controls.price.error)
	const quantitySuffixes = [translations.grams, translations.milliliters]

	const setFood = () => {
		const savedData = {
			id: navigation.getParam('id', undefined),
			image: navigation.getParam('image', undefined),
			name: navigation.getParam('name', ''),
			quantity: navigation.getParam('quantity', 0),
			price: navigation.getParam('price', 0),
			paid: navigation.getParam('paid', 0),
			productQuantity: navigation.getParam('productQuantity', 1),
			quantitySuffixIndex: navigation.getParam('quantitySuffixIndex', 1),
			percentage: navigation.getParam('percentage', 100),
			selected: navigation.getParam('selected', 1),
		}

		setSavedData(savedData)
		setTemplateData(savedData)
		setLoading(false)
	}

	const QuantitySuffixButtons = () => {
		const [value, setValue] = useState(savedData.quantitySuffixIndex)

		return (
			<ButtonGroup
				onPress={(index) => {
					setSavedData({
						...savedData,
						quantitySuffixIndex: index,
					})
					setValue(index)
				}}
				selectedIndex={value}
				buttons={quantitySuffixes}
				selectedButtonStyle={styles.selectedButtonStyle}
			/>
		)
	}

	const setContent = (type: ModalType) => {
		if (type === 'discardChanges') {
			setModalContent(
				<Text style={styles.discardChanges}>{translations.discardChangesDescription}</Text>,
			)
		} else {
			setModalContent(
				<View style={styles.modalContentWrapper}>
					<Input
						inputConfig={controls[type]}
						translations={translations}
						value={templateData[type]}
						changed={(value, control) => {
							setTemplateData({
								...templateData,
								[type]: value,
							})
							setControls({
								...controls,
								[type]: control,
							})
						}}
					/>
					{type === 'quantity' && <QuantitySuffixButtons />}
				</View>,
			)
		}

		setShowModal(true)
		setModalType(type)
	}

	const saveChange = () => {
		if (modalType === 'discardChanges') {
			return
		}

		if (checkValidation(controls[modalType], templateData[modalType] ?? '')) {
			const preparedData = prepareData(
				{ ...savedData, [modalType]: templateData[modalType] },
				controls,
			)

			setTemplateData(preparedData)
			setSavedData(preparedData)

			setHasChanges(true)
			setShowModal(false)
		}
	}

	const changePercentageHandler = (percent: number) => {
		setSavedData({ ...savedData, percentage: +percent.toFixed(0) })
		setHasChanges(true)
	}

	const cancelChange = () => {
		if (modalType === 'discardChanges') {
			return
		}

		setTemplateData(savedData)
		setShowModal(false)
	}

	const toggleModal = (type?: ModalType) => {
		if (!showModal && type) {
			setContent(type)
		} else {
			setShowModal(false)
		}
	}

	const takePhoto = (uri: string) => {
		setSavedData({
			...savedData,
			image: uri,
		})
		setHasChanges(true)
	}

	const toggleCamera = async () => {
		const { status } = await Camera.requestPermissionsAsync()

		if (status === 'granted') {
			navigation.navigate('Camera', {
				buttonTitle: translations.takePhoto,
				takePhoto,
			})
		} else {
			showErrorMessage('permissionError')
		}
	}

	const showErrorMessage = (type: 'priceError' | 'permissionError') => {
		if (type === 'priceError') {
			const message: MessageOptions = {
				message: translations.noPriceTitle,
				description: translations.noPriceDescription,
				type: 'warning',
				icon: { icon: 'warning', position: 'left' },
				duration: 2500,
			}

			showMessage(message)
		}
		if (type === 'permissionError') {
			const message: MessageOptions = {
				message: translations.permissionErrorTitle,
				description: translations.permissionErrorCamera,
				type: 'danger',
				icon: { icon: 'danger', position: 'left' },
				duration: 2500,
			}

			showMessage(message)
		}
	}

	const exitHandler = () => {
		if (hasChanges && correctPrice) {
			setContent('discardChanges')
		} else {
			navigation.goBack()
		}
	}

	const getModalButtons = (): ModalButtonType[] => {
		if (modalType === 'discardChanges') {
			return [
				{
					text: translations.yes,
					onPress: () => {
						setShowModal(false)
						navigation.goBack()
					},
				},
				{
					text: translations.save,
					onPress: () => {
						setSaveFoodBeforeModalHide(true)
						setShowModal(false)
					},
				},
				{ text: translations.cancel, onPress: () => setShowModal(false) },
			]
		}
		return [
			{ text: translations.save, onPress: saveChange },
			{ text: translations.cancel, onPress: cancelChange },
		]
	}

	const checkErrorHandler = () => {
		if (!correctPrice) {
			showErrorMessage('priceError')
		}
	}

	const saveFoodHandler = async () => {
		await saveFood(savedData)
		navigation.replace('List')
	}

	useEffect(() => {
		setFood()
	}, [])

	if (loading) {
		return <Spinner size={64} />
	}

	return (
		<Background>
			<Header
				leftComponent={<Icon onPress={exitHandler} variant='backIcon' />}
				centerComponent={
					<Text style={styles.headerTitle}>
						{savedData.id ? translations.editFood : translations.newFood}
					</Text>
				}
			/>

			<Modal
				visible={showModal}
				toggleModal={toggleModal}
				title={translations[modalType]}
				buttons={getModalButtons()}
				onModalHide={async () => {
					if (saveFoodBeforeModalHide) {
						await saveFoodHandler()
					}
				}}
			>
				{modalContent}
			</Modal>

			<View style={styles.contentWrapper}>
				<ScrollView>
					<View style={styles.imageContainer}>
						<TouchableOpacity onPress={toggleCamera}>
							<View style={styles.imageWrapper}>
								<Image style={styles.image} source={getImage(savedData.image)} />

								<View style={styles.tapImage}>
									<Text style={styles.tapImageText}>{translations.tapToChange}</Text>
								</View>
							</View>
						</TouchableOpacity>
					</View>

					<View style={styles.infoWindowsContainer}>
						<InfoWindow
							color1={whiteColor}
							color2={orangeGradient}
							title={translations.name}
							value={
								!savedData.name || savedData.name === '' ? translations.noData : savedData.name
							}
							onPress={() => toggleModal('name')}
						/>
						<InfoWindow
							color1={whiteColor}
							color2={orangeGradient}
							title={translations.quantity}
							value={
								savedData.quantity
									? `${+savedData.quantity} ${getQuantitySuffix(savedData.quantitySuffixIndex)}`
									: '0'
							}
							onPress={() => toggleModal('quantity')}
						/>
						<InfoWindow
							color1={whiteColor}
							color2={redGradient}
							title={translations.price}
							value={`${savedData.price ? +savedData.price : 0} ${settings.currency}`}
							onPress={() => toggleModal('price')}
						/>

						<View style={styles.sliderContainer}>
							<Text style={styles.percentInfo}>{translations.percentInfo}</Text>
							<Slider
								style={styles.slider}
								thumbStyle={styles.sliderThumbStyle}
								thumbTintColor={blackColor}
								minimumTrackTintColor={darkColor}
								maximumTrackTintColor={grayColor}
								minimumValue={1}
								maximumValue={100}
								value={savedData.percentage}
								onValueChange={(value: number) => changePercentageHandler(value)}
							/>
							<Text style={styles.percent}>{savedData.percentage}%</Text>
						</View>
					</View>

					<View style={styles.saveButtonContainer}>
						<TouchableOpacity onPress={checkErrorHandler}>
							<Button
								buttonStyle={styles.saveButton}
								titleStyle={styles.saveButtonTitle}
								disabled={!correctPrice}
								type='outline'
								title={translations.save}
								onPress={saveFoodHandler}
							/>
						</TouchableOpacity>
					</View>
				</ScrollView>
			</View>
		</Background>
	)
}
Example #24
Source File: QuestionaireSummary.tsx    From SQUID with MIT License 4 votes vote down vote up
QuestionaireSummary = ({ navigation }) => {
  const resetTo = useResetTo()
  const inset = useSafeArea()
  const { qrData, qrState, error, refreshQR } = useSelfQR()
  // useEffect(() => {
  //   resetTo({ routeName: 'MainApp' })
  // }, [])
  return (
    <Container>
      <StatusBar backgroundColor="#00A0D7" barStyle="light-content" />
      <FormHeader whiteLogo style={{ paddingTop: inset.top }} />
      {qrState === QR_STATE.LOADING ? (
        <ActivityIndicator />
      ) : (
        <Content style={{ marginBottom: inset.bottom }}>
          <Image
            source={require('./assets/smile-doctor.png')}
            style={{
              width: Math.floor(Dimensions.get('window').width * 0.5),
              height: Math.floor(
                (1578 / 1370) * Dimensions.get('window').width * 0.5,
              ),
            }}
            resizeMode="cover"
          />
          <Card>
            <Text
              style={{
                fontSize: isSmallDevice? FONT_SIZES[800]:FONT_SIZES[900],
                fontFamily: FONT_BOLD,
                color: qrData.getStatusColor(),
              }}
            >
              {qrData.getLabel()}
            </Text>
            <Text
              style={{
                fontSize: FONT_SIZES[600],
                fontFamily: FONT_FAMILY,
                color: 'black',
              }}
            >
              {I18n.t('doc_will_give_u_qr')}
            </Text>
            <Text
              style={{
                fontSize: FONT_SIZES[600],
                fontFamily: FONT_FAMILY,
                color: 'black',
              }}
            >
              {I18n.t('for_risk_assessment')}
            </Text>
            <Text
              style={{
                fontSize: FONT_SIZES[600],
                marginTop: 8,
                marginBottom: 4,
                fontFamily: FONT_FAMILY,
                color: '#576675',
              }}
            >
              {I18n.t('risk_level')}
            </Text>
            <RiskLevel level={qrData.getLevel()} />
            <View
              style={{
                marginTop: 4,
                alignSelf: 'stretch',
              }}
            >
              <PrimaryButton
                title={I18n.t('receive_qr_code')}
                style={{
                  width: '100%',
                }}
                containerStyle={{
                  width: '100%',
                }}
                onPress={async () => {
                  resetTo({ routeName: 'MainApp' })
                }}
              />
              <Button
                title={I18n.t('do_questionaire_again')}
                style={{
                  width: '100%',
                }}
                type="clear"
                titleStyle={{
                  fontFamily: FONT_FAMILY,
                  fontSize: FONT_SIZES[600]
                }}
                containerStyle={{
                  marginTop: 4,
                  width: '100%',
                }}
                onPress={async () => {
                  resetTo({ routeName: 'Questionaire' })
                }}
              />
            </View>
          </Card>
        </Content>
      )}
    </Container>
  )
}
Example #25
Source File: dev.tsx    From bext with MIT License 4 votes vote down vote up
DevScreen: FC = () => {
  const [loading, setLoading] = useState(true);
  const { params } = useRoute<any>();
  const { id, modify } = params || {};
  const { data: draft, mutate } = useRequest(
    async () => {
      try {
        return await getDraft(id);
      } catch (error) {}
    },
    {
      ready: !!id,
    },
  );
  useUpdateEffect(() => {
    if (draft?.id) {
      updateUrl(draft.id, draft.url || '');
    }
  }, [draft?.url, draft?.id]);

  const navigation = useNavigation();
  useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => (loading ? <Text>加载中...</Text> : null),
      ...(draft?.name ? { title: draft.name } : null),
    });
  }, [navigation, loading, draft?.name]);
  const [modalVisible, setModalVisible] = useState(false);
  const { script } = useDebug();
  const webView = useRef<WebView>(null);

  const onMessage = (msg: string = '{}') => {
    try {
      const data = JSON.parse(msg);
      switch (data.type) {
        case 'save':
          updateJson(id, JSON.stringify(data.payload));
          break;
        case 'ready':
          webView.current?.injectJavaScript(`
            if (window.injectDraft) {
              window.injectDraft(decodeURIComponent("${encodeURIComponent(
                draft?.json || '{}',
              )}"));
            }
            true;
          `);
          break;
        case 'debug':
          setModalVisible(true);
          script.current = data.payload;
          break;
        default:
          break;
      }
    } catch (error) {}
  };

  const navigateToDebug = () => {
    navigation.navigate(
      'debug' as never,
      {
        url: draft?.url,
      } as never,
    );
    setModalVisible(false);
  };

  return (
    <>
      <Overlay
        transparent
        isVisible={modalVisible}
        onBackdropPress={() => setModalVisible(false)}
        overlayStyle={styles.overlay}
      >
        <Input
          label="输入窗口链接"
          value={draft?.url}
          onChangeText={(url) => mutate((old) => ({ ...old, url } as any))}
        />
        <Button title="确定" disabled={!draft?.url} onPress={navigateToDebug} />
      </Overlay>
      <WebView
        ref={webView}
        originWhitelist={['*']}
        source={{
          uri: `${BEXT_ORIGIN}${
            modify
              ? '/meta?from=dev&devPath=%2Fdev%2Fscript-m'
              : '/dev/script-m'
          }`,
        }}
        onLoad={() => setLoading(false)}
        onMessage={(e) => onMessage(e.nativeEvent.data)}
      />
    </>
  );
}
Example #26
Source File: Home.tsx    From wuhan2020-frontend-react-native-app with MIT License 4 votes vote down vote up
function Map() {
  const { data, refresh, timeout } = useContext(DataContext);
  const [selectedIndex, setIndex] = useState(0);
  const filter = filterList[selectedIndex];
  const [refreshing, setRefreshing] = useState(false);

  let mapData = data || [];

  const total = {
    confirmedCount: 0,
    curedCount: 0,
    deadCount: 0,
  };

  const webviewRef = useRef(null);

  useEffect(function() {
    if (webviewRef.current) {
      webviewRef.current.setOption({
        title: {
          text: `疫情地图${titleMap[filter]}`,
        },
        tooltip: {
          trigger: 'item',
          formatter: '{b}',
        },
        visualMap: {
          pieces: piecesMap[filter],
          showLabel: true,
          realtime: true,
          inRange: {
            color: ['yellow', 'red'],
          },
        },
        series: [
          {
            name: '中国',
            type: 'map',
            map: 'china',
            selectedMode: 'single', //multiple多选
            itemStyle: {
              normal: {
                label: {
                  show: false,
                  textStyle: {
                    color: '#231816',
                  },
                },
                areaStyle: { color: '#B1D0EC' },
                color: '#B1D0EC',
                borderColor: '#bbb',
              },
              emphasis: {
                label: {
                  show: false,
                  textStyle: {
                    color: '#fa4f04',
                  },
                },
              },
            },
            data: mapData,
          },
        ],
      });
    }
  });

  const onRefresh = useCallback(() => {
    setRefreshing(true);

    refresh();
    wait(2000).then(() => setRefreshing(false));
  }, [refreshing, refresh]);

  if (data) {
    let formatted = [];

    data.getAreaStat.forEach(entry => {
      total.confirmedCount = total.confirmedCount + entry.confirmedCount;
      total.curedCount = total.curedCount + entry.curedCount;
      total.deadCount = total.deadCount + entry.deadCount;

      formatted = formatted.concat([
        {
          name: entry.provinceShortName,
          value: entry[filter],
        },
      ]);
    });

    mapData = formatted;
  }

  const option = {
    title: {
      text: `疫情地图${titleMap[filter]}`,
    },
    tooltip: {
      trigger: 'item',
      formatter: '{b}',
    },
    visualMap: {
      pieces: piecesMap[filter],
      showLabel: true,
      realtime: true,
      inRange: {
        color: ['yellow', 'red'],
      },
    },
    series: [
      {
        name: '中国',
        type: 'map',
        map: 'china',
        selectedMode: 'single', //multiple多选
        itemStyle: {
          normal: {
            label: {
              show: false,
              textStyle: {
                color: '#231816',
              },
            },
            areaStyle: { color: '#B1D0EC' },
            color: '#B1D0EC',
            borderColor: '#bbb',
          },
          emphasis: {
            label: {
              show: false,
              textStyle: {
                color: '#fa4f04',
              },
            },
          },
        },
        data: mapData,
      },
    ],
  };

  if (timeout) {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <View
          style={{ justifyContent: 'center', alignItems: 'center', flex: 1 }}>
          <Text
            style={{
              color: colors.primary,
              fontSize: 18,
              paddingVertical: 20,
            }}>
            数据载入失败?
          </Text>
          <Button type="outline" onPress={refresh} title="点击重试" />
        </View>
      </SafeAreaView>
    );
  }

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <ScrollView
        style={{
          flex: 1,
        }}
        refreshControl={
          <RefreshControl
            tintColor="pink"
            refreshing={refreshing}
            onRefresh={onRefresh}
          />
        }>
        <View style={{ backgroundColor: 'white' }}>
          {mapData.length ? (
            <View style={{ flex: 1 }}>
              <View style={{ height: 300 }}>
                <ECharts
                  ref={webviewRef}
                  option={option}
                  backgroundColor="#fcfcfc"
                />
              </View>
              <ButtonGroup
                selectedButtonStyle={styles.buttonGroup}
                onPress={setIndex}
                selectedIndex={selectedIndex}
                buttons={[
                  `确诊 (${total.confirmedCount})`,
                  `治愈 (${total.curedCount})`,
                  `致死 (${total.deadCount})`,
                ]}
                containerStyle={{ height: 50 }}
              />
              {data && data.getTimelineService && (
                <Timeline data={data.getTimelineService} />
              )}
              {data && data.getIndexRecommendList && (
                <RecommendationList data={data.getIndexRecommendList} />
              )}
            </View>
          ) : (
            <View style={{ flex: 1, width, height }}>
              <Loader
                size="large"
                color="red"
                style={{ marginTop: height / 3 }}
              />
            </View>
          )}
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}
Example #27
Source File: Checkout.component.tsx    From RNWCShop with GNU General Public License v3.0 4 votes vote down vote up
_renderForm = ({ handleCheckoutSubmit }: Props): JSX.Element => (
  <Formik
    initialValues={{
      first_name: '',
      last_name: '',
      address_1: '',
      address_2: '',
      city: '',
      state: '',
      postcode: '',
      country: '',
      email: '',
      phone: ''
    }}
    onSubmit={(values): void => handleCheckoutSubmit(values)}>
    {({ handleChange, handleBlur, handleSubmit, values }): JSX.Element => (
      <>
        <Input
          label="First Name"
          placeholder="James"
          onChangeText={handleChange('first_name')}
          onBlur={handleBlur('first_name')}
          value={values.first_name}
        />
        <Input
          label="Last Name"
          placeholder="Moriarty"
          onChangeText={handleChange('last_name')}
          onBlur={handleBlur('last_name')}
          value={values.last_name}
        />
        <Input
          label="Address 1"
          placeholder="221B Baker Street"
          onChangeText={handleChange('address_1')}
          onBlur={handleBlur('address_1')}
          value={values.address_1}
        />
        <Input
          label="Address 2"
          onChangeText={handleChange('address_2')}
          onBlur={handleBlur('address_2')}
          value={values.address_2}
        />
        <Input
          label="City"
          placeholder="Birmingham"
          onChangeText={handleChange('city')}
          onBlur={handleBlur('city')}
          value={values.city}
        />
        <Input
          label="State"
          placeholder="West Midlands"
          onChangeText={handleChange('state')}
          onBlur={handleBlur('state')}
          value={values.state}
        />
        <Input
          label="Post Code"
          placeholder="NW1 6XE"
          onChangeText={handleChange('postcode')}
          onBlur={handleBlur('postcode')}
          value={values.postcode}
        />
        <Input
          label="Country"
          placeholder="United Kingdom"
          onChangeText={handleChange('country')}
          onBlur={handleBlur('country')}
          value={values.country}
        />
        <Input
          label="Email"
          placeholder="[email protected]"
          onChangeText={handleChange('email')}
          onBlur={handleBlur('email')}
          value={values.email}
        />
        <Input
          label="Phone"
          placeholder="+628123456789"
          onChangeText={handleChange('phone')}
          onBlur={handleBlur('phone')}
          value={values.phone}
        />
        <Button
          // @ts-ignore
          onPress={handleSubmit}
          title="Proceed to payment"
        />
      </>
    )}
  </Formik>
)
Example #28
Source File: Checkout.component.tsx    From react-native-woocommerce with MIT License 4 votes vote down vote up
_renderForm = ({ handleCheckoutSubmit }: Props): JSX.Element => (
  <Formik
    initialValues={{
      first_name: '',
      last_name: '',
      address_1: '',
      address_2: '',
      city: '',
      state: '',
      postcode: '',
      country: '',
      email: '',
      phone: '',
    }}
    onSubmit={(values): void => handleCheckoutSubmit(values)}
  >
    {({
      handleChange,
      handleBlur,
      handleSubmit,
      values
    }): JSX.Element => (
      <>
        <Input
          label="First Name"
          placeholder="James"
          onChangeText={handleChange('first_name')}
          onBlur={handleBlur('first_name')}
          value={values.first_name}/>
        <Input
          label="Last Name"
          placeholder="Moriarty"
          onChangeText={handleChange('last_name')}
          onBlur={handleBlur('last_name')}
          value={values.last_name}/>
        <Input
          label="Address 1"
          placeholder="221B Baker Street"
          onChangeText={handleChange('address_1')}
          onBlur={handleBlur('address_1')}
          value={values.address_1}/>
        <Input
          label="Address 2"
          onChangeText={handleChange('address_2')}
          onBlur={handleBlur('address_2')}
          value={values.address_2}/>
        <Input
          label="City"
          placeholder="Birmingham"
          onChangeText={handleChange('city')}
          onBlur={handleBlur('city')}
          value={values.city}/>
        <Input
          label="State"
          placeholder="West Midlands"
          onChangeText={handleChange('state')}
          onBlur={handleBlur('state')}
          value={values.state}/>
        <Input
          label="Post Code"
          placeholder="NW1 6XE"
          onChangeText={handleChange('postcode')}
          onBlur={handleBlur('postcode')}
          value={values.postcode}/>
        <Input
          label="Country"
          placeholder="United Kingdom"
          onChangeText={handleChange('country')}
          onBlur={handleBlur('country')}
          value={values.country}/>
        <Input
          label="Email"
          placeholder="[email protected]"
          onChangeText={handleChange('email')}
          onBlur={handleBlur('email')}
          value={values.email}/>
        <Input
          label="Phone"
          placeholder="+628123456789"
          onChangeText={handleChange('phone')}
          onBlur={handleBlur('phone')}
          value={values.phone}/>
        <Button
          // @ts-ignore
          onPress={handleSubmit}
          title="Proceed to payment"
        />
      </>
    )}
  </Formik>
)
Example #29
Source File: HomeBluetooth.tsx    From ito-app with GNU General Public License v3.0 4 votes vote down vote up
HomeBluetooth: React.FC<{
  navigation: HomeBluetoothScreenNavigationProp;
}> = ({navigation}) => {
  const {t} = useTranslation();
  const [distances, setDistances] = useState<never[]>([]);
  const [showIDMatch, setIDMatchShow] = useState<boolean>(false);
  const [hasSeenIDMatch, setIDMatchSeen] = useState<boolean>(false);
  const emitter = useRef<NativeEventEmitter | null>(null);
  const latestFetchTime = NativeModules.ItoBluetooth.getLatestFetchTime();
  console.log('Latest fetch time:', latestFetchTime);
  const latestFetchDate =
    latestFetchTime === -1 ? null : new Date(latestFetchTime * 1000);
  const latestFetch =
    latestFetchDate === null
      ? t('home.never')
      : `${t('home.today')} ${latestFetchDate.toTimeString().substr(0, 5)}`;
  useEffect(() => {
    console.log('Setting distance event listener');
    emitter.current = new NativeEventEmitter(NativeModules.ItoBluetooth);
    const listener = (ds: never[]): void => {
      console.log('Distances changed:', ds);
      setDistances(ds);
    };
    emitter.current.addListener('onDistancesChanged', listener);
    return (): void => {
      if (emitter.current) {
        emitter.current.removeListener('onDistancesChanged', listener);
        emitter.current = null;
      }
    };
  }, [distances.length]);

  useEffect(() => {
    function refresh(): void {
      if (NativeModules.ItoBluetooth.isPossiblyInfected() && !hasSeenIDMatch) {
        setIDMatchShow(true);
      }
    }
    const interval = setInterval(refresh, 2500);
    return (): void => clearInterval(interval);
  }, [navigation, hasSeenIDMatch]);

  const closeIDMatch = (): void => {
    setIDMatchShow(false);
    setIDMatchSeen(true);
  };

  const r1Distances = distances.filter((d) => d <= 1.5);
  const r2Distances = distances.filter((d) => d > 1.5 && d <= 5);
  const r3Distances = distances.filter((d) => d > 5);
  // let contactDescription;
  let contactStyles;
  if (distances.length === 0) {
    contactStyles = stylesNoContacts;
    // contactDescription = 'no contacts around you';
  } else if (distances.length <= 3) {
    contactStyles = stylesFewContacts;
    // contactDescription = 'just a few contacts around you';
  } else {
    contactStyles = stylesManyContacts;
    // contactDescription = 'many contacts around you';
  }
  let radius1Style;
  if (r1Distances.length < 1) {
    radius1Style = StyleSheet.flatten([
      styles.radius1,
      stylesNoContacts.radius1,
    ]);
  } else if (r1Distances.length >= 1 && r1Distances.length < 5) {
    radius1Style = StyleSheet.flatten([
      styles.radius1,
      stylesFewContacts.radius1,
    ]);
  } else {
    radius1Style = StyleSheet.flatten([
      styles.radius1,
      stylesManyContacts.radius1,
    ]);
  }
  let radius2Style;
  if (r1Distances.length >= 1) {
    radius2Style = StyleSheet.flatten([
      styles.radius2,
      stylesManyContacts.radius2,
    ]);
  } else if (r2Distances.length < 1) {
    radius2Style = StyleSheet.flatten([
      styles.radius2,
      stylesNoContacts.radius2,
    ]);
  } else if (r2Distances.length >= 1 && r2Distances.length < 5) {
    radius2Style = StyleSheet.flatten([
      styles.radius2,
      stylesFewContacts.radius2,
    ]);
  } else {
    radius2Style = StyleSheet.flatten([
      styles.radius2,
      stylesManyContacts.radius2,
    ]);
  }
  let radius3Style;
  if (r3Distances.length < 1) {
    radius3Style = StyleSheet.flatten([
      styles.radius3,
      stylesNoContacts.radius3,
    ]);
  } else if (r3Distances.length >= 1 && r3Distances.length < 5) {
    radius3Style = StyleSheet.flatten([
      styles.radius3,
      stylesFewContacts.radius3,
    ]);
  } else {
    radius3Style = StyleSheet.flatten([
      styles.radius3,
      stylesManyContacts.radius3,
    ]);
  }
  const contactsStyle = StyleSheet.flatten([
    styles.contacts,
    contactStyles.contacts,
  ]);
  const avgDistance = distances.length
    ? distances.reduce((prev, cur) => prev + cur, 0) / distances.length
    : null;
  const circle2Diameter =
    avgDistance === null ? 220 : 80 + Math.cbrt(avgDistance) * 100;

  return (
    <TouchableWithoutFeedback>
      <View style={global.container}>
        {showIDMatch && (
          <BlurBackground>
            <View style={styles.IDMatchPopup}>
              <Text style={styles.IDMatchText}>
                {t('home.alertContactDiscovered')}
              </Text>
              <BasicButton title={t('home.whatNext')} onPress={closeIDMatch} />
            </View>
          </BlurBackground>
        )}
        <Header
          showHelp={true}
          navigationButton={{
            title: 'new Home',
            fn: (): void => {
              navigation.navigate('Home');
            },
          }}
        />
        <View style={styles.lastFetchRow}>
          <Text style={styles.lastFetch}>
            {t('home.lastIdFetch')}: {latestFetch}
          </Text>
          <Icon name="refresh-ccw" size={18} style={styles.refreshIcon} />
        </View>
        <View style={styles.radiusContainer}>
          <Text style={radius1Style} />
          <Text
            style={[
              radius2Style,
              {
                width: circle2Diameter,
                height: circle2Diameter,
                borderRadius: circle2Diameter / 2,
                top: 185 - circle2Diameter / 2,
              },
            ]}
          />
          <Text style={radius3Style} />
        </View>
        <Text style={contactsStyle}>{`${distances.length} ${t(
          'home.contacts',
        )} (avg: ${
          avgDistance === null ? 'n/a' : `${avgDistance.toPrecision(2)}m`
        })`}</Text>
        <Button
          title={t('home.buttonTitleInfected')}
          onPress={(): void => navigation.navigate('Endangerment')}
          titleStyle={styles.buttonInfectedTitle}
          buttonStyle={styles.buttonInfected}
        />
      </View>
    </TouchableWithoutFeedback>
  );
}