From aa0922117c53fbb8eb6ed90b97bd713ecae99d7e Mon Sep 17 00:00:00 2001 From: Annie Wang Date: Wed, 17 Jun 2020 21:00:10 -0400 Subject: [PATCH] Release 1.4.0 (#164) * Update signup bonus, add alert to Forgot Password * Update app name * Fix alignSelf for Android * Update alert copy * Update Snap Points to accommodate Android * Fix button alignment for Android * Bump version numbers to 1.4.0 * Update sign in to log in * Revert snap points updates * Update account error * Preload assets * Add force update to logout --- App.js | 6 +++ app.json | 10 ++-- constants/Rewards.js | 6 ++- navigation/DrawerContent.js | 13 ++--- screens/auth/LogInScreen.js | 7 ++- screens/auth/PasswordResetScreen.js | 73 +++++++++++++++++++---------- screens/auth/SignUpScreen.js | 4 +- screens/map/MapScreen.js | 6 +-- screens/rewards/RewardsScreen.js | 12 +++-- screens/settings/SettingsScreen.js | 5 +- styled/hamburger.js | 3 +- 11 files changed, 97 insertions(+), 48 deletions(-) diff --git a/App.js b/App.js index ac69a20a..acab69af 100644 --- a/App.js +++ b/App.js @@ -1,5 +1,6 @@ import { FontAwesome5 } from '@expo/vector-icons'; import { AppLoading } from 'expo'; +import { Asset } from 'expo-asset'; import * as Font from 'expo-font'; import React, { useState } from 'react'; import { Platform, StatusBar, StyleSheet, View } from 'react-native'; @@ -40,6 +41,11 @@ export default function App(props) { async function loadResourcesAsync() { await Promise.all([ + Asset.loadAsync([ + require('./assets/images/hc_start.png'), + require('./assets/images/Marker_Focused.png'), + require('./assets/images/Marker_Resting.png'), + ]), Font.loadAsync({ // This is the icon style we use ...FontAwesome5.font, diff --git a/app.json b/app.json index 67df09bc..dbb58290 100644 --- a/app.json +++ b/app.json @@ -1,11 +1,11 @@ { "expo": { - "name": "Healthy Corners Rewards", - "slug": "healthy-corners-rewards", + "name": "Healthy Corners", + "slug": "healthy-corners", "privacy": "public", "sdkVersion": "37.0.0", "platforms": ["ios", "android", "web"], - "version": "1.3.0", + "version": "1.4.0", "primaryColor": "#008550", "orientation": "portrait", "icon": "./assets/images/icon.png", @@ -21,7 +21,7 @@ "ios": { "bundleIdentifier": "org.calblueprint.HealthyCornersRewards", "googleServicesFile": "./GoogleService-Info.plist", - "buildNumber": "1.3.1", + "buildNumber": "1.4.0", "supportsTablet": true, "infoPlist": { "NSLocationWhenInUseUsageDescription": "To find nearby stores and see what products are available.", @@ -46,7 +46,7 @@ } }, "permissions": ["ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION"], - "versionCode": 5 + "versionCode": 6 }, "web": { "config": { diff --git a/constants/Rewards.js b/constants/Rewards.js index ecce6c4d..0e6f22ec 100644 --- a/constants/Rewards.js +++ b/constants/Rewards.js @@ -1,3 +1,7 @@ export const rewardDollarValue = 5; export const rewardPointValue = 500; -export const signUpBonus = 500; +// For customers who sign up directly from the app +export const newSignUpBonus = 500; + +// For customers who sign up in store, then log in on the app +export const storeSignUpBonus = 250; diff --git a/navigation/DrawerContent.js b/navigation/DrawerContent.js index ff7c853b..0bf265eb 100644 --- a/navigation/DrawerContent.js +++ b/navigation/DrawerContent.js @@ -1,5 +1,6 @@ import { DrawerItemList } from '@react-navigation/drawer'; import { useFocusEffect } from '@react-navigation/native'; +import { Updates } from 'expo'; import * as Analytics from 'expo-firebase-analytics'; import PropTypes from 'prop-types'; import React from 'react'; @@ -27,7 +28,9 @@ function DrawerContent(props) { props.navigation.navigate('Stores'); await AsyncStorage.clear(); Sentry.configureScope((scope) => scope.clear()); - props.navigation.navigate('Auth', { screen: 'LogIn' }); + props.navigation.navigate('Auth', { screen: 'LogIn', initial: false }); + // Temporary fix: force update to make sure the rewards footer refreshes + Updates.reload(); }; useFocusEffect( @@ -79,11 +82,9 @@ function DrawerContent(props) { action: 'componentDidMount', error: err, }); - Alert.alert( - 'This account has been removed', - 'You are logged into an account that no longer exists. You must log out and create a new account.', - [{ text: 'OK', onPress: () => logout() }] - ); + Alert.alert('Session Expired', 'Refresh the app and log in again.', [ + { text: 'OK', onPress: () => logout() }, + ]); } }; diff --git a/screens/auth/LogInScreen.js b/screens/auth/LogInScreen.js index a869c980..a16130c0 100644 --- a/screens/auth/LogInScreen.js +++ b/screens/auth/LogInScreen.js @@ -297,8 +297,13 @@ export default class LogInScreen extends React.Component { } error={this.state.errors[inputFields.PASSWORD]} /> + this.props.navigation.navigate('Reset', { forgot: true }) }> diff --git a/screens/auth/PasswordResetScreen.js b/screens/auth/PasswordResetScreen.js index 92beecd5..7d1b9c4d 100644 --- a/screens/auth/PasswordResetScreen.js +++ b/screens/auth/PasswordResetScreen.js @@ -14,7 +14,7 @@ import { Subtitle, } from '../../components/BaseComponents'; import Colors from '../../constants/Colors'; -import { signUpBonus } from '../../constants/Rewards'; +import { storeSignUpBonus } from '../../constants/Rewards'; import firebaseConfig from '../../firebase'; import { getCustomersByPhoneNumber, @@ -205,25 +205,48 @@ export default class PasswordResetScreen extends React.Component { ); if (customers.length === 1) { [customer] = customers; - if (!this.state.forgot) { - if (customer.password) { - Alert.alert( - '', - 'This phone number already has a password set. Log in to access your account.', - [ - { - text: 'Log In', - onPress: () => this.props.navigation.navigate('LogIn'), - }, - { - text: 'Cancel', - style: 'cancel', - }, - ] - ); - return false; - } + // If the customer is setting a password after registering in store through the Set a Password screen + if (!this.state.forgot && customer.password) { + Alert.alert( + '', + 'This phone number already has a password set. Log in to access your account.', + [ + { + text: 'Log In', + onPress: () => this.props.navigation.navigate('LogIn'), + }, + { + text: 'Cancel', + style: 'cancel', + }, + ] + ); + return false; } + // If the customer tries to set a password after registering store but goes through the Forgot Password screen + if (this.state.forgot && !customer.password) { + Alert.alert( + 'Phone number registered without a password', + `${ + this.state.values[inputFields.PHONENUM] + } does not have a password yet. Set a password to finish setting up your account.`, + [ + { + text: 'Set a password', + onPress: () => + this.props.navigation.dispatch( + StackActions.replace('Reset', { forgot: false }) + ), + }, + { + text: 'Cancel', + style: 'cancel', + }, + ] + ); + return false; + } + this.setState({ customer }); } else { const errorMsg = 'No account registered with this number'; @@ -251,9 +274,10 @@ export default class PasswordResetScreen extends React.Component { ); // Update the created record with the encrypted password await updateCustomers(this.state.customer.id, { password: encrypted }); + // Add the point bonus if the customer is setting up their account after registering in-store if (!this.state.forgot) { await updateCustomers(this.state.customer.id, { - points: (this.state.customer.points || 0) + signUpBonus, + points: (this.state.customer.points || 0) + storeSignUpBonus, }); } this.setState({ success: true }); @@ -287,15 +311,16 @@ export default class PasswordResetScreen extends React.Component { onPress={() => { if (this.state.verified) { Alert.alert( - 'Are you sure you want to go back? You will have to verify your phone number again.', - '', + 'Are you sure you want to leave?', + 'You will have to verify your phone number again.', [ { - text: 'Go back', + text: 'Leave', onPress: () => this.props.navigation.goBack(), + style: 'destructive', }, { - text: 'Cancel', + text: 'Stay', style: 'cancel', }, ] diff --git a/screens/auth/SignUpScreen.js b/screens/auth/SignUpScreen.js index e9cbaa6d..69490378 100644 --- a/screens/auth/SignUpScreen.js +++ b/screens/auth/SignUpScreen.js @@ -22,7 +22,7 @@ import { } from '../../components/BaseComponents'; import Colors from '../../constants/Colors'; import RecordIds from '../../constants/RecordIds'; -import { signUpBonus } from '../../constants/Rewards'; +import { newSignUpBonus } from '../../constants/Rewards'; import { env } from '../../environment'; import firebaseConfig from '../../firebase'; import { @@ -158,7 +158,7 @@ export default class SignUpScreen extends React.Component { name, phoneNumber, // 2020/4/29 update for Nam's launch - points: signUpBonus, + points: newSignUpBonus, pushTokenIds: pushTokenId ? [pushTokenId] : null, }); diff --git a/screens/map/MapScreen.js b/screens/map/MapScreen.js index d6ec8e80..253555e6 100644 --- a/screens/map/MapScreen.js +++ b/screens/map/MapScreen.js @@ -31,9 +31,7 @@ import { SearchBar, } from '../../styled/store'; -const minSnapPoint = 185; -const midSnapPoint = 325; -const maxSnapPoint = 488; +const snapPoints = [185, 325, 488]; const deltas = { latitudeDelta: 0.01, @@ -355,7 +353,7 @@ export default class MapScreen extends React.Component { enabledBottomClamp overdragResistanceFactor={1} enabledContentTapInteraction={false} - snapPoints={[maxSnapPoint, midSnapPoint, minSnapPoint]} + snapPoints={snapPoints} renderHeader={this.renderHeader} renderContent={this.renderContent} // eslint-disable-next-line no-return-assign diff --git a/screens/rewards/RewardsScreen.js b/screens/rewards/RewardsScreen.js index 8d966fae..950b0553 100644 --- a/screens/rewards/RewardsScreen.js +++ b/screens/rewards/RewardsScreen.js @@ -1,7 +1,8 @@ import { FontAwesome5 } from '@expo/vector-icons'; +import { Updates } from 'expo'; import PropTypes from 'prop-types'; import React from 'react'; -import { AsyncStorage, ScrollView, View } from 'react-native'; +import { Alert, AsyncStorage, ScrollView, View } from 'react-native'; import { TabBar, TabView } from 'react-native-tab-view'; import * as Sentry from 'sentry-expo'; import { @@ -49,9 +50,9 @@ export default class RewardsScreen extends React.Component { // Load customer record & transactions async componentDidMount() { - const customerId = await AsyncStorage.getItem('customerId'); - const isGuest = customerId === RecordIds.guestCustomerId; try { + const customerId = await AsyncStorage.getItem('customerId'); + const isGuest = customerId === RecordIds.guestCustomerId; const customer = await getCustomersById(customerId); const transactions = await getCustomerTransactions(customerId); const participating = await getStoreData(`NOT({Rewards Accepted} = '')`); @@ -70,6 +71,9 @@ export default class RewardsScreen extends React.Component { action: 'componentDidMount', error: err, }); + Alert.alert('Session Expired', 'Refresh the app and log in again.', [ + { text: 'OK', onPress: () => this._logout() }, + ]); } } @@ -78,6 +82,8 @@ export default class RewardsScreen extends React.Component { await AsyncStorage.clear(); Sentry.configureScope((scope) => scope.clear()); this.props.navigation.navigate('Auth', { screen: 'SignUp' }); + // Temporary fix: force update to make sure the rewards footer refreshes + Updates.reload(); }; renderScene = ({ route }) => { diff --git a/screens/settings/SettingsScreen.js b/screens/settings/SettingsScreen.js index e11e1ddd..9a51b95c 100644 --- a/screens/settings/SettingsScreen.js +++ b/screens/settings/SettingsScreen.js @@ -1,4 +1,5 @@ import { FontAwesome5 } from '@expo/vector-icons'; +import { Updates } from 'expo'; import Constants from 'expo-constants'; import PropTypes from 'prop-types'; import React from 'react'; @@ -80,6 +81,8 @@ export default class SettingsScreen extends React.Component { 'Auth', signUp ? { screen: 'SignUp' } : { screen: 'Welcome' } ); + // Temporary fix: force update to make sure the rewards footer refreshes + Updates.reload(); } }; @@ -97,7 +100,7 @@ export default class SettingsScreen extends React.Component { {this.state.isGuest && ( this._logout(true)} diff --git a/styled/hamburger.js b/styled/hamburger.js index 1f6c5c40..85be9c47 100644 --- a/styled/hamburger.js +++ b/styled/hamburger.js @@ -1,3 +1,4 @@ +import { Platform } from 'react-native'; import styled from 'styled-components/native'; import { NavButtonContainer } from '../components/BaseComponents'; import Colors from '../constants/Colors'; @@ -7,5 +8,5 @@ export const HamburgerButton = styled(NavButtonContainer)` background-color: ${Colors.bgLight}; box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.25); elevation: 12; - padding-top: 3px; + padding-top: ${Platform.OS === 'ios' ? '3px' : '1px'}; `;