Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add participating stores to Rewards screen #129

Merged
merged 14 commits into from
Apr 30, 2020
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={() =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I click this, it doesn't show the map marker as selected.

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 @@ -229,8 +229,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 @@ -341,7 +342,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, 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