diff --git a/components/BaseComponents.js b/components/BaseComponents.js
index 1211e38b..72f5be0b 100644
--- a/components/BaseComponents.js
+++ b/components/BaseComponents.js
@@ -24,6 +24,17 @@ export const NavButton = styled.TouchableOpacity`
justify-content: center;
`;
+export const CircleIconContainer = styled.View`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 40px;
+ width: 40px;
+ padding: 8px;
+ border-radius: 20px;
+ background-color: ${props => props.color || Colors.lighterGreen};
+`;
+
export const ButtonContainer = styled.TouchableOpacity``;
// TODO @tommypoa Replace top / bottom 25%
export const ButtonLabel = styled(TextButton)`
diff --git a/components/CircleIcon.js b/components/CircleIcon.js
new file mode 100644
index 00000000..736a38eb
--- /dev/null
+++ b/components/CircleIcon.js
@@ -0,0 +1,19 @@
+import { FontAwesome5 } from '@expo/vector-icons';
+import React from 'react';
+import { CircleIconContainer } from './BaseComponents';
+
+export default class CircleIcon extends React.Component {
+ render() {
+ return (
+
+
+
+ );
+ }
+}
diff --git a/components/resources/ResourceCategoryBar.js b/components/resources/ResourceCategoryBar.js
index 350a46ed..f93154d8 100644
--- a/components/resources/ResourceCategoryBar.js
+++ b/components/resources/ResourceCategoryBar.js
@@ -1,21 +1,18 @@
import React from 'react';
-
-import {
- CategoryCard,
- CategoryIcon,
- HeadingContainer
-} from '../../styled/resources';
+import Colors from '../../assets/Colors';
+import { CategoryCard, HeadingContainer } from '../../styled/resources';
import { Title } from '../BaseComponents';
-import { FontAwesome5 } from '@expo/vector-icons';
+import CircleIcon from '../CircleIcon';
class ResourceCategoryBar extends React.Component {
render() {
return (
-
-
-
-
+
{this.props.title}
diff --git a/components/rewards/PointsHistory.js b/components/rewards/PointsHistory.js
index 3cd9d0a4..88bea445 100644
--- a/components/rewards/PointsHistory.js
+++ b/components/rewards/PointsHistory.js
@@ -1,38 +1,31 @@
import React from 'react';
-import { Button, ScrollView, StyleSheet, Text, View } from 'react-native';
+import { ScrollView, View } from 'react-native';
import { Overline } from '../BaseComponents';
import Transaction from './Transaction';
/**
* @prop
* */
-const styles = StyleSheet.create({
- signOutButton: {
- fontSize: 20,
- paddingVertical: 15
- }
-});
-
function PointsHistory({ transactions, user, updates, navigation }) {
// Only display if transactions have mounted
// TODO @kennethlien fix spacing at line 44
if (transactions) {
return (
-
-
-
- Recent Transactions
- {transactions.map(transaction => (
-
- ))}
-
-
-
+
+
+ Recent Transactions
+
+ {transactions.map(transaction => (
+
+ ))}
+
);
}
// else return
diff --git a/components/rewards/RewardsCard.js b/components/rewards/RewardsCard.js
index 85dfc9b0..fb08869b 100644
--- a/components/rewards/RewardsCard.js
+++ b/components/rewards/RewardsCard.js
@@ -1,25 +1,21 @@
import React from 'react';
+import Colors from '../../assets/Colors';
import {
- RewardsCardContainer,
RewardDescriptionContainer,
- StarIcon
+ RewardsCardContainer
} from '../../styled/rewards';
-import { Subhead, Caption } from '../BaseComponents';
-import { FontAwesome5 } from '@expo/vector-icons';
-import Colors from '../../assets/Colors';
+import { Caption, Subhead } from '../BaseComponents';
+import CircleIcon from '../CircleIcon';
class RewardsCard extends React.Component {
render() {
return (
-
-
-
+
$5 Reward
1000 points
diff --git a/components/rewards/RewardsHome.js b/components/rewards/RewardsHome.js
index 4146186d..249585bb 100644
--- a/components/rewards/RewardsHome.js
+++ b/components/rewards/RewardsHome.js
@@ -1,13 +1,13 @@
import React from 'react';
-import { View, ScrollView } from 'react-native';
-import { Body, Overline, Title } from '../BaseComponents';
+import { ScrollView } from 'react-native';
+import { ProgressBar } from 'react-native-paper';
+import Colors from '../../assets/Colors';
import {
- RewardsProgressContainer,
- AvailiableRewardsContainer
+ AvailableRewardsContainer,
+ RewardsProgressContainer
} from '../../styled/rewards';
-import { ProgressBar } from 'react-native-paper';
+import { Body, Overline, Title } from '../BaseComponents';
import RewardsCard from './RewardsCard';
-import Colors from '../../assets/Colors';
/**
* @prop
@@ -23,35 +23,38 @@ function createList(N) {
function RewardsHome({ user }) {
return (
-
-
-
-
- REWARD PROGRESS
-
-
- {parseInt(user.points) % 1000} / 1000
-
-
-
- Earn {`${1000 - (parseInt(user.points) % 1000)}`} points to unlock
- your next $5 reward
-
-
- AVAILIABLE REWARDS ({Math.floor(parseInt(user.points) / 1000)})
-
-
-
- {createList(Math.floor(parseInt(user.points) / 1000)).map(a => (
-
- ))}
-
-
-
+
+
+
+ Reward Progress
+
+
+ {parseInt(user.points) % 1000} / 1000
+
+
+
+ Earn {`${1000 - (parseInt(user.points) % 1000)}`} points to unlock
+ your next $5 reward
+
+
+ Available Rewards ({Math.floor(parseInt(user.points) / 1000)})
+
+
+
+ {createList(Math.floor(parseInt(user.points) / 1000)).map(a => (
+
+ ))}
+
+
);
}
diff --git a/components/rewards/Transaction.js b/components/rewards/Transaction.js
index 0e7925e9..42164a86 100644
--- a/components/rewards/Transaction.js
+++ b/components/rewards/Transaction.js
@@ -1,33 +1,40 @@
-import { FontAwesome5 } from '@expo/vector-icons';
import React from 'react';
-import { TouchableOpacity } from 'react-native';
-import {
- Card,
- ContentContainer,
- IconContainer
-} from '../../styled/transaction';
-import { Caption, Body } from '../../components/BaseComponents';
+import Colors from '../../assets/Colors';
+import { displayDollarValue } from '../../lib/rewardsUtils';
+import { Card, ContentContainer } from '../../styled/transaction';
+import { Caption, Subhead } from '../BaseComponents';
+import CircleIcon from '../CircleIcon';
/**
* @prop
* */
function Transaction(props) {
- const { date, storeName, points } = props;
+ const { date, storeName, pointsEarned, totalSale } = props;
+ const options = {
+ weekday: 'short',
+ year: 'numeric',
+ month: 'short',
+ day: 'numeric'
+ };
return (
-
-
-
-
-
-
-
- {date.toLocaleDateString()} @ {storeName}
-
- {points} Points Redeemed
-
-
-
+
+
+
+
+ {date.toLocaleDateString('en-US', options)} • {storeName}
+
+ {pointsEarned} points earned
+
+ for {displayDollarValue(totalSale ? totalSale : 0)} of healthy
+ products
+
+
+
);
}
diff --git a/lib/rewardsUtils.js b/lib/rewardsUtils.js
index 282de18f..6e6e8d25 100644
--- a/lib/rewardsUtils.js
+++ b/lib/rewardsUtils.js
@@ -7,16 +7,23 @@ function createTransactionData(record) {
customer: transaction.Customer,
// TODO not entirely sure why this was converted to a Date object
date: new Date(transaction.Date),
- points: transaction['Points Rewarded'],
+ pointsEarned: transaction['Points Earned'],
storeName: transaction['Store Name'],
productsPurchased: transaction['Products Purchased'],
phone: transaction['Customer Lookup (Phone #)'],
clerk: transaction.Clerk,
itemsRedeemed: transaction['Items Redeemed'],
customerName: transaction['Customer Name'],
- receipts: transaction.Receipts
+ totalSale: transaction['Total Price']
};
}
+export function displayDollarValue(amount, positive = true) {
+ const dollarValue = '$'.concat(amount.toFixed(2).toString());
+ if (positive) {
+ return dollarValue;
+ }
+ return '-'.concat(dollarValue);
+}
// Calls Airtable API to return a promise that
// will resolve to be a user record.
diff --git a/navigation/AppNavigator.js b/navigation/AppNavigator.js
index 8b01df7a..af6f2f92 100644
--- a/navigation/AppNavigator.js
+++ b/navigation/AppNavigator.js
@@ -1,15 +1,16 @@
import React from 'react';
-import { AsyncStorage, View, TouchableOpacity, Linking } from 'react-native';
+import { AsyncStorage, Linking, TouchableOpacity, View } from 'react-native';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createDrawerNavigator, DrawerItems } from 'react-navigation-drawer';
import { createStackNavigator } from 'react-navigation-stack';
-import WelcomeScreen from '../screens/auth/WelcomeScreen';
+import Colors from '../assets/Colors';
import { Title } from '../components/BaseComponents';
+import { getUser } from '../lib/rewardsUtils';
import LoginScreen from '../screens/auth/LoginScreen';
import SignUpScreen from '../screens/auth/SignUpScreen';
-import Colors from '../assets/Colors';
-import { getUser } from '../lib/rewardsUtils';
-import { RewardsStack, StoresStack, ResourcesStack } from './StackNavigators';
+import WelcomeScreen from '../screens/auth/WelcomeScreen';
+import RewardsScreen from '../screens/rewards/RewardsScreen';
+import { ResourcesStack, RootStack, StoresStack } from './StackNavigators';
const AuthStack = createStackNavigator({
Welcome: WelcomeScreen,
@@ -119,6 +120,13 @@ export class DrawerContent extends React.Component {
const MyDrawerNavigator = createDrawerNavigator(
{
+ Root: {
+ screen: RootStack,
+ navigationOptions: () => ({
+ title: 'Root',
+ drawerLabel: () => null
+ })
+ },
Stores: {
screen: StoresStack,
navigationOptions: () => ({
@@ -126,9 +134,9 @@ const MyDrawerNavigator = createDrawerNavigator(
})
},
Rewards: {
- screen: RewardsStack,
+ screen: props => ,
navigationOptions: () => ({
- title: 'Your Profile',
+ title: 'Points History',
drawerLockMode: 'locked-closed'
})
},
diff --git a/navigation/StackNavigators.js b/navigation/StackNavigators.js
index 48ca453f..63e34278 100644
--- a/navigation/StackNavigators.js
+++ b/navigation/StackNavigators.js
@@ -1,16 +1,13 @@
-import { createStackNavigator } from 'react-navigation-stack';
import { Platform } from 'react-native';
-
+import { createStackNavigator } from 'react-navigation-stack';
import MapScreen from '../screens/map/MapScreen';
-import RewardsScreen from '../screens/rewards/RewardsScreen';
-import ReceiptScanner from '../screens/rewards/Camera';
-
import ProductDetailsScreen from '../screens/map/ProductDetailsScreen';
import ProductsScreen from '../screens/map/ProductsScreen';
import StoreListScreen from '../screens/map/StoreListScreen';
-import NewsScreen from '../screens/news/NewsScreen';
import NewsDetailsScreen from '../screens/news/NewsDetailsScreen';
+import NewsScreen from '../screens/news/NewsScreen';
import ResourcesScreen from '../screens/resources/ResourcesScreen';
+import RewardsScreen from '../screens/rewards/RewardsScreen';
const config = Platform.select({
web: { headerMode: 'screen' },
@@ -31,18 +28,21 @@ StoresStack.navigationOptions = {
drawerLabel: 'Stores'
};
-export const RewardsStack = createStackNavigator(
+export const RootStack = createStackNavigator(
{
- RewardsHome: RewardsScreen,
- Camera: ReceiptScanner
+ MainStack: {
+ screen: StoresStack
+ },
+ RewardsOverlay: {
+ screen: RewardsScreen
+ }
},
- config
+ {
+ headerMode: 'none',
+ mode: 'modal'
+ }
);
-RewardsStack.navigationOptions = {
- drawerLabel: 'Points History'
-};
-
export const NewsStack = createStackNavigator(
{
News: NewsScreen,
diff --git a/screens/map/MapScreen.js b/screens/map/MapScreen.js
index f2d9373c..55851ad1 100644
--- a/screens/map/MapScreen.js
+++ b/screens/map/MapScreen.js
@@ -1,9 +1,9 @@
+import { FontAwesome5 } from '@expo/vector-icons';
import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';
import convertDistance from 'geolib/es/convertDistance';
import getDistance from 'geolib/es/getDistance';
import React from 'react';
-import { FontAwesome5 } from '@expo/vector-icons';
import {
Dimensions,
SafeAreaView,
@@ -13,17 +13,17 @@ import {
} from 'react-native';
import MapView, { Marker } from 'react-native-maps';
import BottomSheet from 'reanimated-bottom-sheet';
+import Colors from '../../assets/Colors';
+import { Subhead } from '../../components/BaseComponents';
import Hamburger from '../../components/Hamburger';
import StoreProducts from '../../components/product/StoreProducts';
import { getProductData, getStoreData } from '../../lib/mapUtils';
-import { Subhead } from '../../components/BaseComponents';
import {
- SearchBar,
BottomSheetContainer,
BottomSheetHeaderContainer,
- DragBar
+ DragBar,
+ SearchBar
} from '../../styled/store';
-import Colors from '../../assets/Colors';
const { width } = Dimensions.get('window'); // full width
@@ -256,7 +256,7 @@ export default class MapScreen extends React.Component {
alignItems: 'center',
justifyContent: 'center'
}}
- onPress={() => this.props.navigation.navigate('Rewards')}>
+ onPress={() => this.props.navigation.navigate('RewardsOverlay')}>
Your Rewards
diff --git a/screens/rewards/RewardsScreen.js b/screens/rewards/RewardsScreen.js
index 1d3577d7..8e3a9e64 100644
--- a/screens/rewards/RewardsScreen.js
+++ b/screens/rewards/RewardsScreen.js
@@ -2,7 +2,8 @@ import { FontAwesome5 } from '@expo/vector-icons';
import React from 'react';
import { AsyncStorage, Dimensions } from 'react-native';
import { TabBar, TabView } from 'react-native-tab-view';
-import { Title } from '../../components/BaseComponents';
+import Colors from '../../assets/Colors';
+import { BigTitle } from '../../components/BaseComponents';
import PointsHistory from '../../components/rewards/PointsHistory';
import RewardsHome from '../../components/rewards/RewardsHome';
import { getCustomerTransactions, getUser } from '../../lib/rewardsUtils';
@@ -16,6 +17,7 @@ const routes = [
export default class RewardsScreen extends React.Component {
constructor(props) {
super(props);
+ const tab = this.props.tab || 0;
this.state = {
user: {
id: null,
@@ -25,7 +27,7 @@ export default class RewardsScreen extends React.Component {
transactions: [],
refreshing: false,
updates: false,
- index: 0,
+ index: tab,
routes
};
}
@@ -131,6 +133,7 @@ export default class RewardsScreen extends React.Component {
@@ -141,18 +144,17 @@ export default class RewardsScreen extends React.Component {
return (
- this.props.navigation.navigate('Stores')}>
+ this.props.navigation.goBack()}>
-
Healthy Rewards
-
+
({
- contentContainerStyle: {
- paddingTop: 30
- }
-}))`
- flex: 1;
- background-color: #fff;
-`;
-
export const RewardsCardContainer = styled.View`
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
border-radius: 9px;
@@ -34,28 +25,18 @@ export const RewardsCardContainer = styled.View`
background-color: ${Colors.lightestGreen};
`;
-export const StarIcon = styled.View`
- align-items: center;
- justify-content: center;
- height: 40px;
- width: 40px;
- border-radius: 20px;
- background-color: #fff;
- flex-direction: row;
-`;
-
export const RewardDescriptionContainer = styled.View`
flex-direction: column;
margin-left: 8px;
`;
export const RewardsProgressContainer = styled.View`
- margin: 1% 5%;
+ margin: 8px 0;
flex-direction: column;
`;
-export const AvailiableRewardsContainer = styled.View`
- margin: 1% 5%;
+export const AvailableRewardsContainer = styled.View`
+ margin: 8px 0;
display: flex
width: 100%
flex-direction: row;
@@ -63,80 +44,39 @@ export const AvailiableRewardsContainer = styled.View`
justify-content: flex-start;
`;
-export const ContentText = styled(Subhead)``;
-
-export const ContentText2 = styled(Caption)``;
-
-export const RewardsTitle = styled.View`
- font-size: 17px;
- font-weight: bold;
- color: rgba(13, 99, 139, 0.8);
- line-height: 24px;
- text-align: center;
-`;
export const TopTab = styled.View`
- position: absolute;
- height: 190px;
- top: 0px;
background-color: ${Colors.primaryGreen};
- flex-direction: row;
- width: 100%;
- font-size: 30px;
- align-items: flex-end;
-`;
-// TODO @anniero98 figure out how to pass styles to third-party components (TabView, TabBar)
-export const StyledTabView = styled.View`
- flex: 1;
- margin-top: 150px;
+ padding-top: 80px;
+ flex-direction: column;
`;
+// box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
export const styles = StyleSheet.create({
tabView: {
- flex: 1,
- marginTop: 150
+ flex: 1
},
tabBar: {
- backgroundColor: '#008550',
- elevation: 0,
+ backgroundColor: Colors.primaryGreen,
+ elevation: 2,
borderBottomWidth: 0,
- height: 50
+ height: 50,
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 3 },
+ shadowOpacity: 0.2,
+ shadowRadius: 3,
+ justifyContent: 'flex-end'
},
tabBarLabel: {
- color: 'white',
+ color: Colors.lightest,
textTransform: 'capitalize',
fontSize: 16,
- fontWeight: 'bold'
+ fontFamily: 'poppins-medium',
+ paddingLeft: 4,
+ paddingRight: 4
},
tabBarIndicator: {
- backgroundColor: '#fff',
- height: 2.5
- },
- tabBarInfoContainer: {
- position: 'absolute',
- bottom: 150,
- left: 0,
- right: 0,
- ...Platform.select({
- ios: {
- shadowColor: 'black',
- shadowOffset: { width: 0, height: 3 },
- shadowOpacity: 0.1,
- shadowRadius: 3
- },
- android: {
- elevation: 20
- }
- }),
- alignItems: 'center',
- backgroundColor: '#fbfbfb',
- paddingVertical: 20
- },
- navigationFilename: {
- marginTop: 5
- },
- getStartedContainer: {
- alignItems: 'center',
- marginHorizontal: 50,
- paddingVertical: 20
+ backgroundColor: Colors.lightest,
+ height: 2,
+ borderRadius: 10
}
});
diff --git a/styled/transaction.js b/styled/transaction.js
index f71b270e..babeb80d 100644
--- a/styled/transaction.js
+++ b/styled/transaction.js
@@ -1,41 +1,23 @@
import styled from 'styled-components/native';
-import { PoppinsText } from './shared';
+import Colors from '../assets/Colors';
export const Card = styled.View`
- box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
- border-style: solid;
- border-radius: 4px;
border-width: 1px;
- border-color: grey;
- padding: 20px;
- margin: 2% 5%;
+ border-radius: 4px;
+ box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
+ box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.12);
+ box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.14);
+ border-color: ${Colors.lighter};
+ background-color: ${Colors.lightest};
+ margin: 8px 0;
+ padding: 16px 8px;
flex-direction: row;
-`;
-
-export const IconContainer = styled.View`
- flex: 1;
- flex-direction: column;
+ justify-content: space-between;
`;
export const ContentContainer = styled.View`
- flex: 4;
flex-direction: column;
-`;
-
-export const MainText = styled(PoppinsText)`
- font-style: normal;
- font-weight: normal;
- font-size: 16px;
- line-height: 24px;
- display: flex;
- align-items: center;
- color: rgba(0, 0, 0, 0.8);
-`;
-
-export const Overline = styled(PoppinsText)`
- font-style: normal;
- font-weight: 500;
- font-size: 12px;
- line-height: 16px;
- color: #999999;
+ margin-left: 12px;
+ flex: 1;
+ justify-content: flex-start;
`;