From 45b508bbcfedb7934c82a16e2b91e0edee67a763 Mon Sep 17 00:00:00 2001 From: joebochill Date: Sat, 13 Oct 2018 20:04:26 -0400 Subject: [PATCH 01/17] implemented anonymous access with restrictions --- src/actions/PackageActions.js | 8 +- src/components/CustomDrawer.js | 17 ++-- src/components/Header/Header.js | 76 ++++++++++++++++++ src/components/Modal/TokenExpire.js | 4 +- src/components/screens/About.js | 47 ++--------- src/components/screens/Blog.js | 31 ++----- src/components/screens/Blogs.js | 30 ++----- src/components/screens/Help.js | 50 +----------- src/components/screens/Lesson.js | 30 ++----- src/components/screens/Lessons.js | 120 ++++++++++++---------------- src/components/screens/Login.js | 26 ++++-- src/components/screens/Order.js | 81 ++++++++----------- src/components/screens/Redeem.js | 105 ++++++++++-------------- src/components/screens/Register.js | 2 +- src/components/screens/Tip.js | 31 ++----- src/components/screens/Tips.js | 36 ++------- src/constants/index.js | 8 +- src/navigators/AppNavigator.js | 75 +++++++++++------ src/reducers/reducers.js | 12 ++- src/utils/utils.js | 15 ++++ 20 files changed, 359 insertions(+), 445 deletions(-) create mode 100644 src/components/Header/Header.js diff --git a/src/actions/PackageActions.js b/src/actions/PackageActions.js index f18f6737..dc16e272 100644 --- a/src/actions/PackageActions.js +++ b/src/actions/PackageActions.js @@ -4,15 +4,11 @@ import {BASEURL, AUTH, failure, success, checkTimeout} from './actions.js'; export const GET_PACKAGES = {REQUEST: 'GET_PACKAGES', SUCCESS: 'GET_PACKAGES_SUCCESS', FAIL: 'GET_PACKAGES_FAIL'}; /* Retrieves List of available lesson packages and prices */ -export function getPackages(token){ +export function getPackages(token = null){ return (dispatch) => { dispatch({type:GET_PACKAGES.REQUEST}); - return fetch(BASEURL+'packages', { - headers: { - [AUTH]: 'Bearer ' + token - } - }) + return fetch(BASEURL+'packages') .then((response) => { switch(response.status) { case 200: diff --git a/src/components/CustomDrawer.js b/src/components/CustomDrawer.js index e6dca11e..bf82256a 100644 --- a/src/components/CustomDrawer.js +++ b/src/components/CustomDrawer.js @@ -6,6 +6,7 @@ import {requestLogout, requestDataFromToken} from '../actions/LoginActions'; import {getTips} from '../actions/TipActions'; import {getBlogs} from '../actions/BlogActions'; +import {getPackages} from '../actions/PackageActions'; import { setTargetRoute} from '../actions/actions'; import LogoutWarning from './Modal/TokenExpire'; @@ -38,7 +39,8 @@ function mapDispatchToProps(dispatch){ showLogoutWarning: (show) => dispatch(showLogoutWarning(show)), setTargetRoute: (loc, extra) => dispatch(setTargetRoute(loc, extra)), getTips: (token = null) => dispatch(getTips(token)), - getBlogs: (token = null) => dispatch(getBlogs(token)) + getBlogs: (token = null) => dispatch(getBlogs(token)), + getPackages: (token = null) => dispatch(getPackages(token)) } } @@ -57,6 +59,7 @@ class CustomDrawer extends React.Component { // load the tips of the month and blogs as soon as we load the app this.props.getTips(); this.props.getBlogs(); + this.props.getPackages(); } componentDidMount(){ AppState.addEventListener('change', this._handleAppStateChange); @@ -135,7 +138,6 @@ class CustomDrawer extends React.Component { {this.props.username ? 'Welcome, ' + this.props.username + '!' : ''} - {this.props.token && this.props.navigation.navigate('Order')}/> - } - {!this.props.token && } this.props.navigation.navigate('Blogs')}/> - this.props.requestLogout(this.props.token)}/> + } + {!this.props.token && + this.props.navigation.push('Auth')}/> + } this.props.navigation.navigate('Help')}/> {dispatch(requestLogout(token))} + }; +} + +class CustomHeader extends React.Component { + render() { + return ( +
this.props.navigation.pop() : + () => this.props.navigation.navigate('DrawerOpen') + }} + centerComponent={{ + text: this.props.title, + style: { color: colors.white, fontSize: verticalScale(18) } + }} + rightComponent={{ + icon: this.props.token ? 'exit-to-app' : 'person', + underlayColor:colors.transparent, + color: colors.white, + containerStyle:styles.headerIcon, + onPress: !this.props.token ? + () => this.props.navigation.push('Auth') : + () => Alert.alert( + 'Log Out', + 'Are you sure you want to log out?', + [ + {text: 'Cancel'}, + {text: 'Log Out', + onPress: () => { + this.props.logout(this.props.token); + } + } + ] + ) + }} + /> + ); + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(CustomHeader); diff --git a/src/components/Modal/TokenExpire.js b/src/components/Modal/TokenExpire.js index 49b6833b..609072f5 100644 --- a/src/components/Modal/TokenExpire.js +++ b/src/components/Modal/TokenExpire.js @@ -97,9 +97,9 @@ class TokenExpireModal extends React.Component { {'Session Expiration In: ' + this.state.time} - Your session is about to expire. Click below to stay logged in. + Your session is about to expire. Click below to stay signed in. + } {this.state.waiting && -
this.props.navigation.navigate('DrawerOpen') - }} - centerComponent={{ text: 'Order Lessons', style: { color: colors.white, fontSize: verticalScale(18) } }} - /> +
{(this.props.purchaseFail || this.state.iap_error) && There was an error processing your purchase. Please try again later or contact info@swingessentials.com for more information. @@ -250,7 +237,7 @@ class Order extends React.Component{ + + + + {this.props.children} + + + + + ); + } +} + +export default TutorialModal; \ No newline at end of file diff --git a/src/components/screens/Lessons.js b/src/components/screens/Lessons.js index c7342241..7b53641f 100644 --- a/src/components/screens/Lessons.js +++ b/src/components/screens/Lessons.js @@ -1,8 +1,9 @@ import React from 'react'; import {connect} from 'react-redux'; -import {Alert, Text, View, ScrollView, FlatList, RefreshControl, Platform} from 'react-native'; +import {Alert, Text, View, ScrollView, FlatList, RefreshControl, StyleSheet, Platform} from 'react-native'; import {Button, Header} from 'react-native-elements'; +import Tutorial from '../Tutorial/Lessons'; import styles, {colors, spacing, altStyles} from '../../styles/index'; import {scale, verticalScale} from '../../styles/dimension'; @@ -30,7 +31,8 @@ class Lessons extends React.Component{ constructor(props){ super(props); this.state={ - refreshing: false + refreshing: false, + showTutorial: false } } componentDidMount(){ @@ -95,8 +97,8 @@ class Lessons extends React.Component{ onPress: () => this.props.navigation.navigate('DrawerOpen') }} centerComponent={{ text: 'Your Lessons', style: { color: colors.white, fontSize: verticalScale(18) } }} - //rightComponent={{ icon: 'settings',underlayColor:colors.transparent, color: colors.white, containerStyle:styles.headerIcon, - // onPress: () => {this.props.navigation.push('Settings')}}} + rightComponent={{ icon: 'settings',underlayColor:colors.transparent, color: colors.white, containerStyle:styles.headerIcon, + onPress: () => {this.setState({showTutorial: !this.state.showTutorial})}}} /> item.request_id} /> - + + this.setState({showTutorial: false})}/> ); diff --git a/src/styles/index.js b/src/styles/index.js index 79f886f7..027056ce 100644 --- a/src/styles/index.js +++ b/src/styles/index.js @@ -6,6 +6,7 @@ export const colors = { white: '#ffffff', purple: '#231f61', lightPurple: 'rgba(35,31,97,0.8)', + flatPurple: 'rgba(79,76,129,1)', veryLightPurple: 'rgba(35,31,97,0.6)', borderGrey: '#c1c1c1', backgroundGrey: '#f0f0f0', @@ -164,6 +165,14 @@ export default StyleSheet.create({ }, centered:{ alignItems: 'center', - justifyContent: 'center' + justifyContent: 'center', + }, + tutorial:{ + alignSelf: 'stretch', + justifyContent: 'center', + padding: spacing.large + }, + tutorialText:{ + } }); \ No newline at end of file diff --git a/src/utils/utils.js b/src/utils/utils.js index 0766952f..b8095154 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -13,4 +13,14 @@ export function formatText(text){ return arr.map((val, index) => {val} ); +} + +export function getDate(unix){ + let day = new Date(unix); + let dd = day.getUTCDate(); + let mm = day.getUTCMonth()+1; + let yyyy = day.getUTCFullYear(); + if(dd<10){dd='0'+dd;} + if(mm<10) {mm='0'+mm;} + return (yyyy + '-' + mm + '-' + dd); } \ No newline at end of file From b12d5e5a8621ee596c5a7d06fa5e266b7d8cdca8 Mon Sep 17 00:00:00 2001 From: joebochill Date: Sun, 14 Oct 2018 00:42:43 -0400 Subject: [PATCH 03/17] built out carousel-style tutorial --- package-lock.json | 18 +++++ package.json | 1 + src/components/Tutorial/Flat.js | 53 +++++++++++++ src/components/Tutorial/Lessons.js | 123 ++++++++++++++++++++--------- src/components/screens/Lessons.js | 12 ++- src/styles/dimension.js | 2 +- 6 files changed, 168 insertions(+), 41 deletions(-) create mode 100644 src/components/Tutorial/Flat.js diff --git a/package-lock.json b/package-lock.json index d8462aa4..cd1e075a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6213,6 +6213,15 @@ "prop-types": "15.6.2" } }, + "react-addons-shallow-compare": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react-addons-shallow-compare/-/react-addons-shallow-compare-15.6.2.tgz", + "integrity": "sha1-GYoAuR/DdiPbZKKP0XtZa6NicC8=", + "requires": { + "fbjs": "0.8.17", + "object-assign": "4.1.1" + } + }, "react-clone-referenced-element": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz", @@ -6410,6 +6419,15 @@ "hoist-non-react-statics": "2.5.5" } }, + "react-native-snap-carousel": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/react-native-snap-carousel/-/react-native-snap-carousel-3.7.5.tgz", + "integrity": "sha512-t0/wkjA4Doehv3QTcmzO56G7paGtYsvJgw9XrFI7GCDLK7MrHTiN22ROuJOxMy61nPetyjDAS0Qa3XMl8K7rVQ==", + "requires": { + "prop-types": "15.6.2", + "react-addons-shallow-compare": "15.6.2" + } + }, "react-native-splash-screen": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/react-native-splash-screen/-/react-native-splash-screen-3.0.9.tgz", diff --git a/package.json b/package.json index dbd33a7d..8a0a8ba7 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "react-native-image-picker": "^0.26.10", "react-native-keychain": "^3.0.0", "react-native-modal": "^6.5.0", + "react-native-snap-carousel": "^3.7.5", "react-native-splash-screen": "3.0.9", "react-native-touch-id": "^4.0.4", "react-native-vector-icons": "^4.6.0", diff --git a/src/components/Tutorial/Flat.js b/src/components/Tutorial/Flat.js new file mode 100644 index 00000000..a844b87c --- /dev/null +++ b/src/components/Tutorial/Flat.js @@ -0,0 +1,53 @@ +import React from 'react'; +import { Text, View, FlatList, StyleSheet } from 'react-native'; +import {Button} from 'react-native-elements'; + +import styles, {colors, spacing} from '../../styles/index'; +import {scale} from '../../styles/dimension'; +import CardRow from '../Card/CardRow'; +import Tutorial from './Tutorial'; +import {getDate} from '../../utils/utils'; + +import {APP_VERSION} from '../../constants/index'; + +class LessonsTutorial extends React.Component { + doneWithTutorial(){ + AsyncStorage.setItem('@SwingEssentials:tutorial_lessons', APP_VERSION); + this.props.close(); + } + render() { + return ( + this.doneWithTutorial()}> + + {'Welcome to Swing Essentials!'} + When you have submitted your golf swing for analysis, your lessons will appear in this list. + + Lesson History + + } + data={[ + {date: getDate(Date.now())},{date: getDate(Date.now()-24*60*60*1000)},{date: getDate(Date.now()-7*24*60*60*1000)} + ]} + renderItem={({item, index}) => + + } + keyExtractor={(item, index) => index} + /> +