Skip to content

Commit

Permalink
Add participating stores to Rewards screen (#129)
Browse files Browse the repository at this point in the history
* Add participating stores

* Add testing bypass back in dev mode

* Fix child key warning

* Wrap store names in TouchableOpacity

* Update for design changes

* Styling switches on guest mode
  • Loading branch information
annieyro authored Apr 30, 2020
1 parent 899ca38 commit fac5b52
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 27 deletions.
37 changes: 37 additions & 0 deletions components/rewards/ParticipatingStores.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useNavigation } from '@react-navigation/native';
import PropTypes from 'prop-types';
import React from 'react';
import { TouchableOpacity } from 'react-native';
import { ColumnContainer } from '../../styled/shared';
import { Overline, Subhead } from '../BaseComponents';

export default function ParticipatingStores({ participating, guest }) {
const navigation = useNavigation();
return (
<ColumnContainer
style={guest ? { marginLeft: 16, marginBottom: 24 } : { marginTop: 28 }}>
<Overline style={{}}>Participating Stores</Overline>
{participating.map((store) => {
return (
<TouchableOpacity key={store.id}>
<Subhead
style={{ marginLeft: 12 }}
onPress={() =>
navigation.navigate('Stores', {
currentStore: store,
})
}>
{store.storeName}
</Subhead>
</TouchableOpacity>
);
})}
<Subhead style={{ marginLeft: 12 }}>More stores coming soon!</Subhead>
</ColumnContainer>
);
}

ParticipatingStores.propTypes = {
participating: PropTypes.array.isRequired,
guest: PropTypes.bool.isRequired,
};
6 changes: 5 additions & 1 deletion components/rewards/RewardsHome.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import { FlatList, Image, ScrollView, View } from 'react-native';
import { ProgressBar } from 'react-native-paper';

import Colors from '../../constants/Colors';
import Window from '../../constants/Layout';
import { rewardDollarValue, rewardPointValue } from '../../constants/Rewards';
Expand All @@ -11,6 +12,7 @@ import {
RewardsProgressContainer,
} from '../../styled/rewards';
import { Body, Overline, Title } from '../BaseComponents';
import ParticipatingStores from './ParticipatingStores';
import RewardsCard from './RewardsCard';

/**
Expand All @@ -25,7 +27,7 @@ function createList(n) {
return list;
}

function RewardsHome({ customer }) {
function RewardsHome({ customer, participating }) {
const rewardsAvailable = parseInt(customer.points, 10) / rewardPointValue;
const pointsToNext = parseInt(customer.points, 10) % rewardPointValue;
return (
Expand Down Expand Up @@ -87,6 +89,7 @@ function RewardsHome({ customer }) {
}
/>
</AvailableRewardsContainer>
<ParticipatingStores participating={participating} guest={false} />
<View style={{ maxHeight: 600, marginTop: 12 }}>
<Image
source={require('../../assets/images/HowItWorks.png')}
Expand All @@ -103,6 +106,7 @@ function RewardsHome({ customer }) {

RewardsHome.propTypes = {
customer: PropTypes.object.isRequired,
participating: PropTypes.array.isRequired,
};

export default React.memo(RewardsHome);
15 changes: 8 additions & 7 deletions components/rewards/Transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import { View } from 'react-native';
import Colors from '../../constants/Colors';
import { rewardDollarValue, rewardPointValue } from '../../constants/Rewards';
import { displayDollarValue } from '../../lib/common';
import { ContentContainer, TransactionCard } from '../../styled/transaction';
import { Caption, Subhead } from '../BaseComponents';
Expand Down Expand Up @@ -29,8 +30,8 @@ function Transaction(props) {
return (
<View>
{/* Display rewards unlocked */}
{[...Array(rewardsUnlocked).keys()].map(() => (
<TransactionCard>
{[...Array(rewardsUnlocked).keys()].map((i) => (
<TransactionCard key={i}>
<CircleIcon
icon="star"
iconColor={Colors.primaryGreen}
Expand All @@ -40,9 +41,9 @@ function Transaction(props) {
<Caption color={Colors.secondaryText}>
{`${date.toLocaleDateString('en-US', options)}${storeName}`}
</Caption>
<Subhead>$5 reward unlocked</Subhead>
<Subhead>{`$${rewardDollarValue} reward unlocked`}</Subhead>
<Caption color={Colors.secondaryText}>
for 500 earned points
{`for ${rewardPointValue} earned points`}
</Caption>
</ContentContainer>
</TransactionCard>
Expand All @@ -67,8 +68,8 @@ function Transaction(props) {
</TransactionCard>

{/* Display rewards applied */}
{[...Array(rewardsApplied).keys()].map(() => (
<TransactionCard>
{[...Array(rewardsApplied).keys()].map((i) => (
<TransactionCard key={i}>
<CircleIcon
icon="star"
iconColor={Colors.primaryOrange}
Expand All @@ -78,7 +79,7 @@ function Transaction(props) {
<Caption color={Colors.secondaryText}>
{`${date.toLocaleDateString('en-US', options)}${storeName}`}
</Caption>
<Subhead>$5 reward redeemed</Subhead>
<Subhead>{`$${rewardDollarValue} reward redeemed`}</Subhead>
</ContentContainer>
</TransactionCard>
))}
Expand Down
1 change: 1 addition & 0 deletions components/store/StoreMarker.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import { Image } from 'react-native';

import { MarkerContainer, MarkerStoreName } from '../../styled/store';

function StoreMarker({ storeName, focused }) {
Expand Down
4 changes: 2 additions & 2 deletions lib/mapUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ function updateProductData(record) {

// Gets all records in Airtable from the Stores table
// Returns a promise that resolves to an array of Store objects
export async function getStoreData() {
const records = await getAllStores();
export async function getStoreData(filterByFormula = '') {
const records = await getAllStores(filterByFormula);
// Filter out the Clerk Training store
const stores = records
.filter((record) => record.id !== RecordIds.clerkTrainingStoreId)
Expand Down
1 change: 0 additions & 1 deletion screens/auth/LogInScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import PropTypes from 'prop-types';
import React from 'react';
import { AsyncStorage } from 'react-native';
import * as Sentry from 'sentry-expo';

import AuthTextField from '../../components/AuthTextField';
import {
BigTitle,
Expand Down
9 changes: 6 additions & 3 deletions screens/auth/SignUpScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as Analytics from 'expo-firebase-analytics';
import * as Permissions from 'expo-permissions';
import PropTypes from 'prop-types';
import React from 'react';
import { AsyncStorage, Keyboard } from 'react-native';
import { AsyncStorage, Button, Keyboard } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
import * as Sentry from 'sentry-expo';
import AuthTextField from '../../components/AuthTextField';
Expand All @@ -16,6 +16,7 @@ import {
} from '../../components/BaseComponents';
import Colors from '../../constants/Colors';
import RecordIds from '../../constants/RecordIds';
import { env } from '../../environment';
import {
createCustomers,
createPushTokens,
Expand Down Expand Up @@ -87,7 +88,7 @@ export default class SignUpScreen extends React.Component {
// Configures to use David Ro's test account
_devBypass = async () => {
// Doesn't enforce any resolution for this async call
await AsyncStorage.setItem('customerId', RecordIds.customerId);
await AsyncStorage.setItem('customerId', RecordIds.testCustomerId);
this.props.navigation.navigate('App');
};

Expand Down Expand Up @@ -342,7 +343,9 @@ export default class SignUpScreen extends React.Component {
disabled={!signUpPermission}>
<ButtonLabel color={Colors.lightest}>Sign Up</ButtonLabel>
</FilledButtonContainer>
{/* <Button title="Testing Bypass" onPress={() => this._devBypass()} /> */}
{env === 'dev' && (
<Button title="Testing Bypass" onPress={() => this._devBypass()} />
)}
</AuthScreenContainer>
</ScrollView>
);
Expand Down
1 change: 0 additions & 1 deletion screens/map/MapScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import React from 'react';
import { Alert, Image, StyleSheet, TouchableOpacity, View } from 'react-native';
import MapView, { Marker } from 'react-native-maps';
import BottomSheet from 'reanimated-bottom-sheet';

import { NavHeaderContainer, Subhead } from '../../components/BaseComponents';
import CenterLocation from '../../components/CenterLocation';
import Hamburger from '../../components/Hamburger';
Expand Down
1 change: 0 additions & 1 deletion screens/map/ProductsScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { FontAwesome5 } from '@expo/vector-icons';
import PropTypes from 'prop-types';
import React from 'react';
import { FlatList, View } from 'react-native';

import {
NavButton,
NavHeaderContainer,
Expand Down
4 changes: 2 additions & 2 deletions screens/map/StoreListScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default class StoreListScreen extends React.Component {

// TODO: fix warning involving using a callback function to look up current store.
// TODO @tommypoa or @anniero98 - move this into shared utils with StoreListScreen
storeDetailsTransition = (store) => {
mapTransition = (store) => {
this.state.navigation.navigate('Stores', {
currentStore: store,
});
Expand Down Expand Up @@ -295,7 +295,7 @@ export default class StoreListScreen extends React.Component {
<StoreCard
key={item.id}
store={item}
callBack={() => this.storeDetailsTransition(item)}
callBack={() => this.mapTransition(item)}
storeList
seeDistance={!this.state.showDefaultStore}
/>
Expand Down
43 changes: 34 additions & 9 deletions screens/rewards/RewardsScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ import {
NavButton,
NavHeaderContainer,
} from '../../components/BaseComponents';
import ParticipatingStores from '../../components/rewards/ParticipatingStores';
import PointsHistory from '../../components/rewards/PointsHistory';
import RewardsHome from '../../components/rewards/RewardsHome';
import Colors from '../../constants/Colors';
import RecordIds from '../../constants/RecordIds';
import { getCustomersById } from '../../lib/airtable/request';
import { logErrorToSentry } from '../../lib/logUtils';
import { getStoreData } from '../../lib/mapUtils';
import { getCustomerTransactions } from '../../lib/rewardsUtils';
import { styles } from '../../styled/rewards';

Expand All @@ -36,6 +39,7 @@ export default class RewardsScreen extends React.Component {
this.state = {
customer: null,
transactions: [],
participating: [],
// eslint-disable-next-line react/no-unused-state
index: tab,
// eslint-disable-next-line react/no-unused-state
Expand All @@ -48,15 +52,27 @@ export default class RewardsScreen extends React.Component {
// Load customer record & transactions
async componentDidMount() {
const customerId = await AsyncStorage.getItem('customerId');
const customer = await getCustomersById(customerId);
const isGuest = customerId === RecordIds.guestCustomerId;
const transactions = await getCustomerTransactions(customerId);
this.setState({
customer,
transactions,
isGuest,
isLoading: false,
});
try {
const customer = await getCustomersById(customerId);
const transactions = await getCustomerTransactions(customerId);
const participating = await getStoreData(`NOT({Rewards Accepted} = '')`);

this.setState({
isGuest,
customer,
transactions,
participating,
isLoading: false,
});
} catch (err) {
console.error(err);
logErrorToSentry({
screen: 'RewardsScreem',
action: 'componentDidMount',
error: err,
});
}
}

_logout = async () => {
Expand All @@ -68,7 +84,12 @@ export default class RewardsScreen extends React.Component {
renderScene = ({ route }) => {
switch (route.key) {
case 'home':
return <RewardsHome customer={this.state.customer} />;
return (
<RewardsHome
customer={this.state.customer}
participating={this.state.participating}
/>
);
case 'history':
return <PointsHistory transactions={this.state.transactions} />;
default:
Expand Down Expand Up @@ -127,6 +148,10 @@ export default class RewardsScreen extends React.Component {
}}
/>
</View>
<ParticipatingStores
participating={this.state.participating}
guest
/>
<FilledButtonContainer
style={{ marginBottom: 24, alignSelf: 'center' }}
color={Colors.primaryGreen}
Expand Down

0 comments on commit fac5b52

Please sign in to comment.