This commit is contained in:
Mike Fitzpatrick
2019-08-12 17:44:01 -04:00
parent 0f618fdd78
commit f0460a1b76
21 changed files with 432 additions and 78 deletions

View File

@@ -87,7 +87,7 @@ export const checkEmailAvailability = (email) => (dispatch) => {};
export const checkNomAvailability = (nomDeBid) => (dispatch) => {}; export const checkNomAvailability = (nomDeBid) => (dispatch) => {};
export const setNomDeBid = (nomDeBid) => (dispatch, getState) => { export const setNomDeBid = ({ nomDeBid }) => (dispatch, getState) => {
const id = getUserId(getState()); const id = getUserId(getState());
const auth = getAuthToken(getState()); const auth = getAuthToken(getState());

View File

@@ -24,9 +24,9 @@ export default class AppHeader extends Component {
return ( return (
<Header <Header
placement="left" placement="left"
leftComponent={<HeaderContentRight navigation={navigation} />}
centerComponent={<HeaderTitle navigation={navigation} />} centerComponent={<HeaderTitle navigation={navigation} />}
rightComponent={<HeaderContentLeft navigation={navigation} />} leftComponent={<HeaderContentLeft navigation={navigation} />}
rightComponent={<HeaderContentRight navigation={navigation} />}
/> />
); );
} }

View File

@@ -32,7 +32,11 @@ export default function HeaderContentLeft({
return <BackIcon action={_goBack} />; return <BackIcon action={_goBack} />;
} }
return <EventsIcon action={hasMultipleEvents ? _showEvents : null} />; if (hasMultipleEvents) {
return <EventsIcon action={_showEvents} />;
}
return null;
} }
HeaderContentLeft.propTypes = { HeaderContentLeft.propTypes = {

View File

@@ -8,7 +8,7 @@ export default function HeaderContentRight({ hideUserProfileButton, navigation }
return null; return null;
} }
return <UserProfileButton />; return <UserProfileButton navigation={navigation} />;
} }
HeaderContentRight.propTypes = { HeaderContentRight.propTypes = {

View File

@@ -8,6 +8,7 @@ import EventTitle from './EventTitle/EventTitle.container.js';
import styles from './HeaderTitle.styles.js'; import styles from './HeaderTitle.styles.js';
const STRINGS = { const STRINGS = {
EVENTS: 'Events',
PROFILE: 'Profile', PROFILE: 'Profile',
}; };
@@ -34,7 +35,7 @@ export default function HeaderTitle({
if (activeRoute === 'Events') { if (activeRoute === 'Events') {
return ( return (
<TouchableOpacity onPress={_goBack}> <TouchableOpacity onPress={_goBack}>
<Text style={styles.screenHeader}>{STRINGS.PROFILE}</Text> <Text style={styles.screenHeader}>{STRINGS.EVENTS}</Text>
</TouchableOpacity> </TouchableOpacity>
); );
} }

View File

@@ -13,8 +13,12 @@ export default function UserProfileButton({
navigation, navigation,
}) { }) {
const _goToProfile = () => { const _goToProfile = () => {
navigation.navigate('Profile'); if (isRegisteredAccount) {
return false; navigation.navigate('Profile');
return false;
}
navigation.navigate('SignInOrRegister');
}; };
return ( return (

View File

@@ -29,14 +29,14 @@ export default function EditNomDeBid({
setValidNom(result.available); setValidNom(result.available);
if (isStandalone) { if (isStandalone) {
updateNomDeBid(nomDeBid); updateNomDeBid({ nomDeBid });
} }
}); });
}; };
const _handleSubmitNom = () => { const _handleSubmitNom = () => {
if (isNomValid) { if (isNomValid) {
updateNomDeBid(newNom); updateNomDeBid({ newNom });
} }
}; };

View File

@@ -1,48 +1,57 @@
import { List } from 'immutable';
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, Text, TextInput, View } from 'react-native'; import { Button, Picker, ScrollView, Text, TextInput, View } from 'react-native';
import { Avatar } from 'react-native-elements'; import { Avatar } from 'react-native-elements';
import { getEmailAvailability, getNomAvailability } from '../../api/profile.js'; import { getEmailAvailability, getNomAvailability } from '../../api/profile.js';
import EditNomDeBid from './EditNomDeBid.js'; import EditNomDeBid from './EditNomDeBid.js';
import PhoneListInput from './PhoneInput/PhoneListInput.js';
import styles from './Profile.styles.js'; import styles from './Profile.styles.js';
const STRINGS = { const STRINGS = {
CANCEL: 'Cancel', CANCEL: 'Cancel',
NOM_HEADING: 'Nom de Bid',
PASSWORD_HEADING: 'Password',
PERSONAL_HEADING: 'A bit about you...',
SAVE_PROFILE: 'Save profile', SAVE_PROFILE: 'Save profile',
}; };
export default class EditProfile extends Component { export default class EditProfile extends Component {
static get propTypes() { static get propTypes() {
return { return {
addresses: PropTypes.array, addresses: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(List)]),
avatar: PropTypes.string, avatar: PropTypes.string,
cancelEditAction: PropTypes.func.isRequired, cancelEditAction: PropTypes.func.isRequired,
email: PropTypes.string, email: PropTypes.string,
firstName: PropTypes.string, firstName: PropTypes.string,
initials: PropTypes.string, initials: PropTypes.string,
isGeneratedNomDeBid: PropTypes.bool, isGeneratedNomDeBid: PropTypes.bool,
isRegsiteredAccount: PropTypes.bool,
lastName: PropTypes.string, lastName: PropTypes.string,
nomDeBid: PropTypes.string, nomDeBid: PropTypes.string,
phones: PropTypes.array, phones: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(List)]),
saveProfileAction: PropTypes.func.isRequired, saveProfileAction: PropTypes.func.isRequired,
saveProfileLabel: PropTypes.string, saveProfileLabel: PropTypes.string,
showPasswordEntry: PropTypes.bool,
}; };
} }
static get defaultProps() { static get defaultProps() {
return { return {
addresses: null, addresses: new List(),
avatar: null, avatar: null,
email: null, email: null,
firstName: null, firstName: null,
initials: null, initials: null,
isGeneratedNomDeBid: false, isGeneratedNomDeBid: false,
isRegsiteredAccount: false,
lastName: null, lastName: null,
nomDeBid: null, nomDeBid: null,
phones: null, phones: new List(),
saveProfileLabel: STRINGS.SAVE_PROFILE, saveProfileLabel: STRINGS.SAVE_PROFILE,
showPasswordEntry: false,
}; };
} }
@@ -59,6 +68,7 @@ export default class EditProfile extends Component {
invalidNomDeBid: false, invalidNomDeBid: false,
nomDeBid: this.props.nomDeBid, nomDeBid: this.props.nomDeBid,
password: this.props.password, password: this.props.password,
passwordsMismatch: false,
phones: this.props.phones, phones: this.props.phones,
}; };
@@ -67,15 +77,21 @@ export default class EditProfile extends Component {
} }
_validateEmail() { _validateEmail() {
getEmailAvailability(this.state.email, (result) => getEmailAvailability(this.state.email)
this.setState('invalidEmail', !result.available), .then(({ available = false }) =>
); this.setState('invalidEmail', !available),
);
} }
_validateNomDeBid() { _validateNomDeBid() {
getNomAvailability(this.state.nomDeBid, (result) => getNomAvailability(this.state.nomDeBid)
this.setState('invalidNomDeBid', !result.available), .then(({ available = false }) =>
); this.setState('invalidNomDeBid', !available),
);
}
_validatePasswordMatch(password) {
this.setState({ passwordsMismatch: this.state.password !== password });
} }
getProfileFromState() { getProfileFromState() {
@@ -106,6 +122,9 @@ export default class EditProfile extends Component {
} }
isFormComplete() { isFormComplete() {
const { showPasswordEntry } = this.props;
const { password } = this.state;
return ( return (
!this.state.invalidEmail && !this.state.invalidEmail &&
!this.state.invalidNomDeBid && !this.state.invalidNomDeBid &&
@@ -113,27 +132,28 @@ export default class EditProfile extends Component {
!!this.state.lastName && !!this.state.lastName &&
!!this.state.email && !!this.state.email &&
!!this.state.nomDeBid && !!this.state.nomDeBid &&
!!this.state.phones.length && !!this.state.phones.size &&
!!this.state.password ((showPasswordEntry && !!password) || !showPasswordEntry)
); );
} }
render() { render() {
const { isGeneratedNomDeBid } = this.props; const { isGeneratedNomDeBid, isRegsiteredAccount, showPasswordEntry } = this.props;
const { avatar, firstName, lastName } = this.state; const { addresses, avatar, firstName, lastName, phones } = this.state;
const addressesTitle = 'Addresses'; const addressesTitle = 'Addresses';
const numbersTitle = 'Numbers'; const numbersTitle = 'Numbers';
return ( return (
<View style={styles.profileFormWrap}> <ScrollView style={styles.profileFormWrap}>
<View style={styles.avatarWrap}> <View style={[styles.sectionWrap, styles.avatarWrap]}>
{avatar !== null ? ( {avatar !== null ? (
<Avatar source={{ uri: this.state.avatar }} showEditButton /> <Avatar source={{ uri: this.state.avatar }} showEditButton />
) : ( ) : (
<Avatar title={this.props.initials} showEditButton /> <Avatar title={this.props.initials} showEditButton />
)} )}
</View> </View>
<View style={styles.nameWrap}> <View style={[styles.sectionWrap, styles.nameWrap]}>
<Text style={styles.groupHeading}>{STRINGS.PERSONAL_HEADING}</Text>
<TextInput <TextInput
onChange={(text) => this.setState({ firstName: text })} onChange={(text) => this.setState({ firstName: text })}
placeholder="first name" placeholder="first name"
@@ -147,7 +167,7 @@ export default class EditProfile extends Component {
value={this.state.lastName} value={this.state.lastName}
/> />
</View> </View>
<View style={[styles.emailWrap, styles.requiredWrap]}> <View style={[styles.sectionWrap, styles.emailWrap, styles.requiredWrap]}>
<TextInput <TextInput
keyboardType="email-address" keyboardType="email-address"
onChangeText={(text) => this.setState({ email: text })} onChangeText={(text) => this.setState({ email: text })}
@@ -157,27 +177,45 @@ export default class EditProfile extends Component {
value={this.state.email} value={this.state.email}
/> />
</View> </View>
{isGeneratedNomDeBid && ( {showPasswordEntry && (
<View style={[styles.nomWrap, styles.requiredWrap]}> <View style={[styles.sectionWrap, styles.password, styles.requiredWrap]}>
<Text style={styles.groupHeading}>{STRINGS.PASSWORD_HEADING}</Text>
<TextInput
onChangeText={(text) => this.setState({ password: text })}
placeholder="password"
secureTextEntry
style={[styles.textInput, styles.requiredInput]}
/>
<TextInput
onEndEditing={(text) => this._validatePasswordMatch(text)}
placeholder="re-enter password"
secureTextEntry
style={[styles.textInput, styles.requiredInput]}
/>
</View>
)}
{(isGeneratedNomDeBid || !isRegsiteredAccount) && (
<View style={[styles.sectionWrap, styles.nomWrap, styles.requiredWrap]}>
<Text style={styles.groupHeading}>{STRINGS.NOM_HEADING}</Text>
<EditNomDeBid <EditNomDeBid
isGeneratedNomDeBid={isGeneratedNomDeBid} isGeneratedNomDeBid={isGeneratedNomDeBid}
isStandalone={false} isStandalone
nomDeBid={this.state.nomDeBid} nomDeBid={this.state.nomDeBid}
updateNomDeBid={(nomDeBid) => this.setState({ nomDeBid })} updateNomDeBid={(nomDeBid) => this.setState({ nomDeBid })}
/> />
</View> </View>
)} )}
<View style={styles.phonesWrap}> <View style={[styles.sectionWrap, styles.phonesWrap]}>
<Text style={[styles.groupLabel, styles.requiredLabel]}>{numbersTitle}</Text> <PhoneListInput
{this.props.phones.length > 0 && ( handleAdd={(phones) => this.setState({ phones })}
/* LIST PHONES */ handleDelete={(phones) => this.setState({ phones })}
<View /> handleEdit={(phones) => this.setState({ phones })}
)} phones={phones}
<Button title="Add number" onPress={() => false} /> />
</View> </View>
<View style={styles.addressesWrap}> <View style={[styles.sectionWrap, styles.addressesWrap]}>
<Text style={styles.groupLabel}>{addressesTitle}</Text> <Text style={styles.groupHeading}>{addressesTitle}</Text>
{this.props.addresses.length > 0 && ( {addresses !== null && addresses.size > 0 && (
/* LIST ADDRESSES */ /* LIST ADDRESSES */
<View /> <View />
)} )}
@@ -187,7 +225,7 @@ export default class EditProfile extends Component {
<Button title={this.props.saveProfileLabel} onPress={this.handleSubmit} /> <Button title={this.props.saveProfileLabel} onPress={this.handleSubmit} />
<Button title={STRINGS.CANCEL} onPress={this.handleCancel} /> <Button title={STRINGS.CANCEL} onPress={this.handleCancel} />
</View> </View>
</View> </ScrollView>
); );
} }
} }

View File

@@ -0,0 +1,110 @@
import { List } from 'immutable';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Button, Picker, Text, TextInput, View } from 'react-native';
import { PHONE_TYPE_DEFAULT, PHONE_TYPES } from '../../../constants/constants.js';
import PhoneListItem from './PhoneListItem.js';
import styles from '../Profile.styles.js';
const defaultState = {
editingIndex: null,
isEditing: false,
newPhone: null,
newPhoneType: PHONE_TYPE_DEFAULT,
};
export default class PhoneListInput extends Component {
static get propTypes() {
return {
handleAdd: PropTypes.func.isRequired,
handleDelete: PropTypes.func.isRequired,
handleEdit: PropTypes.func,
phones: PropTypes.instanceOf(List).isRequired,
};
};
static get defaultProps() {
return {
handleEdit: null,
};
};
constructor(props) {
super(props);
this.state = { ...defaultState };
}
handleAdd() {
const { phones } = this.props;
const { newPhone, newPhoneType } = this.state;
this.props.handleAdd(phones.push({ number: newPhone, label: newPhoneType }));
this.setState(defaultState);
}
handleEdit(index) {
const { phones } = this.props;
const { newPhone, newPhoneType } = this.state;
this.props.handleEdit(phones.set(index, { number: newPhone, label: newPhoneType }));
this.setState(defaultState);
}
handleEditStart(index) {
const toBeEdited = this.props.phones.get(index);
this.setState({
editingIndex: index,
isEditing: true,
newPhone: toBeEdited.get('number'),
newPhoneType: toBeEdited.get('label'),
});
}
handleEditCancel(index) {
this.setState(defaultState);
}
render() {
const { phones } = this.props;
const { isEditing, newPhone, newPhoneType } = this.state;
const numbersTitle = 'Numbers';
return (
<View>
<Text style={[styles.groupHeading, styles.requiredLabel]}>{numbersTitle}</Text>
{phones !== null && phones.size > 0 && (
<View style={styles.phoneList}>
{phones.map((phone, index) =>
<PhoneListItem
index={index}
label={phone.get('label')}
number={phone.get('number')}
handleDelete={this.props.handleDelete}
handleEdit={this.props.handleEdit ? this.handleEdit : null}
handleEditStart={this.handleEditStart}
/>
)}
</View>
)}
<TextInput
onChangeText={(text) => this.setState({ editingPhone: text })}
placeholder="phone number"
style={[styles.textInput, styles.requiredInput]}
value={this.state.newPhone}
/>
<Picker
onValueChange={(type, index) => this.setState({ newPhoneType: type })}
selectedValue={this.state.newPhoneType}
>
{PHONE_TYPES.map((type) => <Picker.Item label={type.label} value={type.value} />)}
</Picker>
<Button
disabled={!this.state.newPhone && !this.state.newPhoneType}
onPress={isEditing ? () => this.handleEdit(index) : this.handleAdd}
title={isEditing ? 'update' : 'add number'}
/>
</View>
);
}
}

View File

@@ -0,0 +1,37 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Text, View } from 'react-native';
import styles from '../Profile.styles.js';
export default function PhoneListItem({ index, label, number, handleDelete, handleEdit, handleEditStart }) {
return (
<View style={styles.listItem}>
<View style={styles.listValue}>
<Text style={styles.value}>{phone.get('number')}</Text>
<Text style={styles.label}>{phone.get('label')}</Text>
</View>
<View style={styles.listActions}>
{handleEdit !== null && <Button title={`Edit`} onPress={() => this.handleEditStart(index)} />}
<Button title={`X`} onPress={() => this.props.handleDelete(index)} />
</View>
</View>
);
}
PhoneListItem.propTypes = {
index: PropTypes.number.isRequired,
label: PropTypes.string.isRequired,
number: PropTypes.string.isRequired,
handleDelete: PropTypes.func.isRequired,
handleEdit: PropTypes.func,
handleEditStart: PropTypes.func.isRequired,
};
PhoneListItem.defaultProps = {
handleEdit: null,
};

View File

@@ -1,14 +1,15 @@
import { getProfile, isGeneratedNomDeBid } from '../../selectors/profile.js'; import { getProfile, isGeneratedNomDeBid, isRegisteredAccount } from '../../selectors/profile.js';
export const matchStateToProps = (state) => { export const matchStateToProps = (state) => {
const profile = getProfile(state); const profile = getProfile(state);
return { return {
addresses: profile.get('addresses').toArray(), addresses: profile.get('addresses'),
avatar: profile.get('avatar'), avatar: profile.get('avatar'),
email: profile.get('email'), email: profile.get('email'),
initials: profile.get('initials'), initials: profile.get('initials'),
isGeneratedNomDeBid: isGeneratedNomDeBid(state), isGeneratedNomDeBid: isGeneratedNomDeBid(state),
isRegisteredAccount: isRegisteredAccount(state),
nomDeBid: profile.get('nomDeBid'), nomDeBid: profile.get('nomDeBid'),
phones: profile.get('phones'), phones: profile.get('phones'),
}; };

View File

@@ -2,7 +2,35 @@ import { StyleSheet } from 'react-native';
export default StyleSheet.create({ export default StyleSheet.create({
container: { container: {
alignItems: 'flex-start',
backgroundColor: '#F5FCFF',
flex: 1, flex: 1,
justifyContent: 'center',
paddingLeft: 10,
paddingRight: 10,
},
sectionWrap: {
marginBottom: 15,
},
avatarWrap: {
marginBottom: 40,
marginTop: 30,
textAlign: 'center',
},
groupHeading: {
fontSize: 18,
fontWeight: 'bold',
margin: 10,
textAlign: 'center',
},
hintText: {
color: '#666666',
fontSize: 14,
margin: 5,
},
textInput: {
fontSize: 24,
margin: 10,
textAlign: 'center',
}, },
textInput: {},
}); });

View File

@@ -2,7 +2,6 @@ import { connect } from 'react-redux';
import { getProfile } from '../../selectors/profile.js'; import { getProfile } from '../../selectors/profile.js';
import { matchStateToProps as matchCommonStateProps } from './Profile.stateProps.js'; import { matchStateToProps as matchCommonStateProps } from './Profile.stateProps.js';
import { isRegisteredAccount } from '../../selectors/profile.js';
import ViewProfile from './ViewProfile.js'; import ViewProfile from './ViewProfile.js';
@@ -13,7 +12,6 @@ const matchStateToProps = (state) => {
return { return {
...commonProps, ...commonProps,
fullName: profile.get('fullName'), fullName: profile.get('fullName'),
isRegisteredAccount: isRegisteredAccount(state),
}; };
}; };

View File

@@ -1,6 +1,7 @@
import { List } from 'immutable';
import React, { useState } from 'react'; import React, { useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, Text, TextInput, View } from 'react-native'; import { Button, ScrollView, Text, TextInput, View } from 'react-native';
import { Avatar } from 'react-native-elements'; import { Avatar } from 'react-native-elements';
import EditNomDeBid from './EditNomDeBid.container.js'; import EditNomDeBid from './EditNomDeBid.container.js';
@@ -23,9 +24,9 @@ export default function ViewProfile({
nomDeBid, nomDeBid,
phones, phones,
}) { }) {
const _getSavedText = (count) => `${count} saved`; const _getSavedText = (count) => count > 0 ? `${count} saved` : 'None saved';
const addressesCountString = _getSavedText(addresses.length); const addressesCountString = _getSavedText(addresses.size);
const phonesCountString = _getSavedText(phones.length); const phonesCountString = _getSavedText(phones.size);
const [isEditingNom, setEditNom] = useState(false); const [isEditingNom, setEditNom] = useState(false);
@@ -34,7 +35,7 @@ export default function ViewProfile({
const numbersTitle = 'numbers'; const numbersTitle = 'numbers';
return ( return (
<View style={styles.profileFormWrap}> <ScrollView style={styles.profileFormWrap}>
<View style={styles.avatarWrap}> <View style={styles.avatarWrap}>
{avatar !== null ? ( {avatar !== null ? (
<Avatar source={{ uri: avatar }} /> <Avatar source={{ uri: avatar }} />
@@ -72,12 +73,12 @@ export default function ViewProfile({
<Button title={STRINGS.EDIT} onPress={editProfileAction} /> <Button title={STRINGS.EDIT} onPress={editProfileAction} />
</View> </View>
)} )}
</View> </ScrollView>
); );
} }
ViewProfile.propTypes = { ViewProfile.propTypes = {
addresses: PropTypes.array, addresses: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(List)]),
avatar: PropTypes.string, avatar: PropTypes.string,
editProfileAction: PropTypes.func, editProfileAction: PropTypes.func,
email: PropTypes.string, email: PropTypes.string,
@@ -86,11 +87,11 @@ ViewProfile.propTypes = {
isGeneratedNomDeBid: PropTypes.bool, isGeneratedNomDeBid: PropTypes.bool,
isRegisteredAccount: PropTypes.bool, isRegisteredAccount: PropTypes.bool,
nomDeBid: PropTypes.string, nomDeBid: PropTypes.string,
phones: PropTypes.array, phones: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(List)]),
}; };
ViewProfile.defaultProps = { ViewProfile.defaultProps = {
addresses: [], addresses: new List(),
avatar: null, avatar: null,
editProfileAction: null, editProfileAction: null,
email: null, email: null,
@@ -99,5 +100,5 @@ ViewProfile.defaultProps = {
isGeneratedNomDeBid: false, isGeneratedNomDeBid: false,
isRegisteredAccount: false, isRegisteredAccount: false,
nomDeBid: null, nomDeBid: null,
phones: [], phones: new List(),
}; };

View File

@@ -51,3 +51,11 @@ export const API_ENDPOINTS = {
export const PERMISSIONS = { export const PERMISSIONS = {
FACEBOOK: ['email', 'public_profile'], FACEBOOK: ['email', 'public_profile'],
}; };
export const PHONE_TYPES = {
HOME: { label: 'home', value: 'home' },
MOBILE: { label: 'mobile', value: 'mobile' },
WORK: { label: 'work', value: 'work' },
};
export const PHONE_TYPE_DEFAULT = PHONE_TYPES.HOME.value;

View File

@@ -13,9 +13,20 @@ import ImageDetail from './screens/ImageDetail.js';
import Item from './screens/Item.js'; import Item from './screens/Item.js';
import Marketplace from './screens/Marketplace.js'; import Marketplace from './screens/Marketplace.js';
import Profile from './screens/Profile.container.js'; import Profile from './screens/Profile.container.js';
import Register from './screens/Register.js'; import Register from './screens/Register.container.js';
import SignInOrRegister from './screens/SignInOrRegister.js'; import SignInOrRegister from './screens/SignInOrRegister.js';
const tabBarVisibility = ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible,
};
};
export const SignInOrRegisterStack = createStackNavigator({ export const SignInOrRegisterStack = createStackNavigator({
SignInOrRegister: { SignInOrRegister: {
screen: SignInOrRegister, screen: SignInOrRegister,
@@ -35,6 +46,33 @@ export const SignInOrRegisterStack = createStackNavigator({
}, },
}); });
SignInOrRegisterStack.navigationOptions = tabBarVisibility;
export const ProfileStack = createStackNavigator({
Profile: {
screen: Profile,
navigationOptions: ({ navigation }) => ({
header: <AppHeader navigation={navigation} />,
}),
},
SignInOrRegister: {
screen: SignInOrRegister,
navigationOptions: ({ navigation }) => ({
header: null,
gesturesEnabled: false,
}),
},
Register: {
screen: Register,
navigationOptions: ({ navigation }) => ({
header: null,
gesturesEnabled: false,
}),
},
});
ProfileStack.navigationOptions = tabBarVisibility;
export const AuctionStack = createStackNavigator({ export const AuctionStack = createStackNavigator({
Auction: { Auction: {
screen: Auction, screen: Auction,
@@ -60,6 +98,8 @@ export const AuctionStack = createStackNavigator({
}, },
}); });
AuctionStack.navigationOptions = tabBarVisibility;
export const BazaarStack = createStackNavigator({ export const BazaarStack = createStackNavigator({
Bazaar: { Bazaar: {
screen: Marketplace, screen: Marketplace,
@@ -93,12 +133,13 @@ export const BazaarStack = createStackNavigator({
}, },
}); });
BazaarStack.navigationOptions = tabBarVisibility;
export const EventsStack = createStackNavigator({ export const EventsStack = createStackNavigator({
Events: { Events: {
screen: Events, screen: Events,
navigationOptions: ({ navigation }) => ({ navigationOptions: ({ navigation }) => ({
header: <AppHeader navigation={navigation} />, header: <AppHeader navigation={navigation} />,
tabBarVisible: false,
gesturesEnabled: false, gesturesEnabled: false,
}), }),
}, },
@@ -106,12 +147,13 @@ export const EventsStack = createStackNavigator({
screen: Event, screen: Event,
navigationOptions: ({ navigation }) => ({ navigationOptions: ({ navigation }) => ({
header: <AppHeader navigation={navigation} />, header: <AppHeader navigation={navigation} />,
tabBarVisible: false,
gesturesEnabled: false, gesturesEnabled: false,
}), }),
}, },
}); });
EventsStack.navigationOptions = tabBarVisibility;
export const Tabs = createBottomTabNavigator({ export const Tabs = createBottomTabNavigator({
Event: { Event: {
screen: EventsStack, screen: EventsStack,
@@ -141,7 +183,7 @@ export const Tabs = createBottomTabNavigator({
}, },
}, },
Profile: { Profile: {
screen: Profile, screen: ProfileStack,
navigationOptions: { navigationOptions: {
tabBarLabel: 'Profile', tabBarLabel: 'Profile',
tabBarIcon: ({ tintColor }) => ( tabBarIcon: ({ tintColor }) => (
@@ -149,4 +191,4 @@ export const Tabs = createBottomTabNavigator({
), ),
}, },
}, },
}); }, { initialRouteName: 'Event' });

View File

@@ -9,7 +9,7 @@ import EventListItem from '../components/Events/EventListItem.container.js';
export default class Events extends Component { export default class Events extends Component {
static get propTypes() { static get propTypes() {
return { return {
events: PropTypes.instanceOf(List), events: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(List)]),
fetchEvents: PropTypes.func.isRequired, fetchEvents: PropTypes.func.isRequired,
setActiveEvent: PropTypes.func.isRequired, setActiveEvent: PropTypes.func.isRequired,
}; };
@@ -23,6 +23,7 @@ export default class Events extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this._renderEventListItem = this._renderEventListItem.bind(this);
this._setActiveEvent = this.setActiveEvent.bind(this); this._setActiveEvent = this.setActiveEvent.bind(this);
} }
@@ -32,9 +33,9 @@ export default class Events extends Component {
_keyExtractor = (event, index) => `${event.id}_${index}`; _keyExtractor = (event, index) => `${event.id}_${index}`;
_renderEventListItem = ({ event }) => ( _renderEventListItem({ event }) {
<EventListItem event={event} setActiveEvent={this.setActiveEvent} /> return <EventListItem event={event} setActiveEvent={this.setActiveEvent} />;
); };
render() { render() {
const { events } = this.props; const { events } = this.props;
@@ -50,7 +51,7 @@ export default class Events extends Component {
style={styles.eventList} style={styles.eventList}
/> />
) : ( ) : (
<ActivityIndicator animating={true} /> <ActivityIndicator animating={true} size="large" />
)} )}
</View> </View>
); );

View File

@@ -7,7 +7,7 @@ import { FlatList, Text, View } from 'react-native';
import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js'; import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js';
import FilterBar from '../components/Auction/FilterBar.js'; import FilterBar from '../components/Auction/FilterBar.js';
import AuctionListItem from '../containers/Auction/AuctionListItem.js'; import AuctionListItem from '../components/Auction/AuctionListItem.container.js';
import styles from './Auction.styles.js'; import styles from './Auction.styles.js';

View File

@@ -21,9 +21,10 @@ export default function Register({ doRegistration, navigation }) {
<View style={styles.container}> <View style={styles.container}>
<Text style={styles.heading}>{title}</Text> <Text style={styles.heading}>{title}</Text>
<EditProfile <EditProfile
cancelEditProfile={() => navigation.goBack()} cancelEditAction={() => navigation.goBack()}
saveProfileAction={_doRegistration} saveProfileAction={_doRegistration}
saveProfileLabel="Register" saveProfileLabel="Register"
showPasswordEntry
/> />
</View> </View>
); );

View File

@@ -848,9 +848,43 @@
); );
inputPaths = ( inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Eventment/Pods-Eventment-resources.sh", "${PODS_ROOT}/Target Support Files/Pods-Eventment/Pods-Eventment-resources.sh",
"${PODS_ROOT}/FBSDKCoreKit/FacebookSDKStrings.bundle",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
); );
name = "[CP] Copy Pods Resources"; name = "[CP] Copy Pods Resources";
outputPaths = ( outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FacebookSDKStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;

View File

@@ -1,6 +1,16 @@
PODS: PODS:
- boost-for-react-native (1.63.0) - boost-for-react-native (1.63.0)
- DoubleConversion (1.1.6) - DoubleConversion (1.1.6)
- FBSDKCoreKit (5.3.0):
- FBSDKCoreKit/Basics (= 5.3.0)
- FBSDKCoreKit/Core (= 5.3.0)
- FBSDKCoreKit/Basics (5.3.0)
- FBSDKCoreKit/Core (5.3.0):
- FBSDKCoreKit/Basics
- FBSDKLoginKit (5.3.0):
- FBSDKCoreKit (~> 5.0)
- FBSDKShareKit (5.3.0):
- FBSDKCoreKit (~> 5.0)
- Folly (2018.10.22.00): - Folly (2018.10.22.00):
- boost-for-react-native - boost-for-react-native
- DoubleConversion - DoubleConversion
@@ -57,6 +67,20 @@ PODS:
- React-cxxreact (= 0.60.0) - React-cxxreact (= 0.60.0)
- React-jsi (= 0.60.0) - React-jsi (= 0.60.0)
- React-jsinspector (0.60.0) - React-jsinspector (0.60.0)
- react-native-fbsdk (1.0.1):
- React
- react-native-fbsdk/Core (= 1.0.1)
- react-native-fbsdk/Login (= 1.0.1)
- react-native-fbsdk/Share (= 1.0.1)
- react-native-fbsdk/Core (1.0.1):
- FBSDKCoreKit (~> 5.0)
- React
- react-native-fbsdk/Login (1.0.1):
- FBSDKLoginKit (~> 5.0)
- React
- react-native-fbsdk/Share (1.0.1):
- FBSDKShareKit (~> 5.0)
- React
- React-RCTActionSheet (0.60.0): - React-RCTActionSheet (0.60.0):
- React-Core (= 0.60.0) - React-Core (= 0.60.0)
- React-RCTAnimation (0.60.0): - React-RCTAnimation (0.60.0):
@@ -81,10 +105,14 @@ PODS:
- React-RCTWebSocket (0.60.0): - React-RCTWebSocket (0.60.0):
- React-Core (= 0.60.0) - React-Core (= 0.60.0)
- React-fishhook (= 0.60.0) - React-fishhook (= 0.60.0)
- RNCAsyncStorage (1.6.1):
- React
- RNGestureHandler (1.3.0): - RNGestureHandler (1.3.0):
- React - React
- RNScreens (1.0.0-alpha.23): - RNScreens (1.0.0-alpha.23):
- React - React
- RNSecureStorage (0.1.2):
- React
- RNVectorIcons (6.6.0): - RNVectorIcons (6.6.0):
- React - React
- yoga (0.60.0.React) - yoga (0.60.0.React)
@@ -101,6 +129,7 @@ DEPENDENCIES:
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- react-native-fbsdk (from `/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-fbsdk`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
@@ -111,14 +140,19 @@ DEPENDENCIES:
- React-RCTText (from `../node_modules/react-native/Libraries/Text`) - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`) - React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`)
- RNGestureHandler (from `/Users/mifi/Temporary Projects/eventment-app/node_modules/react-native-gesture-handler`) - "RNCAsyncStorage (from `/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/@react-native-community/async-storage`)"
- RNScreens (from `/Users/mifi/Temporary Projects/eventment-app/node_modules/react-native-screens`) - RNGestureHandler (from `/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-gesture-handler`)
- RNVectorIcons (from `/Users/mifi/Temporary Projects/eventment-app/node_modules/react-native-vector-icons`) - RNScreens (from `/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-screens`)
- RNSecureStorage (from `/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-secure-storage`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- yoga (from `../node_modules/react-native/ReactCommon/yoga`) - yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS: SPEC REPOS:
https://github.com/cocoapods/specs.git: https://github.com/cocoapods/specs.git:
- boost-for-react-native - boost-for-react-native
- FBSDKCoreKit
- FBSDKLoginKit
- FBSDKShareKit
EXTERNAL SOURCES: EXTERNAL SOURCES:
DoubleConversion: DoubleConversion:
@@ -143,6 +177,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsiexecutor" :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
React-jsinspector: React-jsinspector:
:path: "../node_modules/react-native/ReactCommon/jsinspector" :path: "../node_modules/react-native/ReactCommon/jsinspector"
react-native-fbsdk:
:path: "/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-fbsdk"
React-RCTActionSheet: React-RCTActionSheet:
:path: "../node_modules/react-native/Libraries/ActionSheetIOS" :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
React-RCTAnimation: React-RCTAnimation:
@@ -163,18 +199,25 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/Vibration" :path: "../node_modules/react-native/Libraries/Vibration"
React-RCTWebSocket: React-RCTWebSocket:
:path: "../node_modules/react-native/Libraries/WebSocket" :path: "../node_modules/react-native/Libraries/WebSocket"
RNCAsyncStorage:
:path: "/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/@react-native-community/async-storage"
RNGestureHandler: RNGestureHandler:
:path: "/Users/mifi/Temporary Projects/eventment-app/node_modules/react-native-gesture-handler" :path: "/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-gesture-handler"
RNScreens: RNScreens:
:path: "/Users/mifi/Temporary Projects/eventment-app/node_modules/react-native-screens" :path: "/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-screens"
RNSecureStorage:
:path: "/Users/mfitzpatrick/Documents/Personal/eventment-app/node_modules/react-native-secure-storage"
RNVectorIcons: RNVectorIcons:
:path: "/Users/mifi/Temporary Projects/eventment-app/node_modules/react-native-vector-icons" :path: "../node_modules/react-native-vector-icons"
yoga: yoga:
:path: "../node_modules/react-native/ReactCommon/yoga" :path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS: SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
FBSDKCoreKit: 39748deefe37a005f983722e433be2ddcdd83ae7
FBSDKLoginKit: bc0329e10045789e8d40b12d4f15ddbd07a898e2
FBSDKShareKit: f61d03f36ce4f1b379c7de7dbfe173662e68be44
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: 1f3da668190260b06b429bb211bfbee5cd790c28 glog: 1f3da668190260b06b429bb211bfbee5cd790c28
React: 4b3c068e793e96672dcd186a2b572fac43e4b031 React: 4b3c068e793e96672dcd186a2b572fac43e4b031
@@ -185,6 +228,7 @@ SPEC CHECKSUMS:
React-jsi: 8e128c4d0d8febc2977ef617d1c09bb54326069c React-jsi: 8e128c4d0d8febc2977ef617d1c09bb54326069c
React-jsiexecutor: 7a3554f703a58963ec80b860144ea0f0e9b910e1 React-jsiexecutor: 7a3554f703a58963ec80b860144ea0f0e9b910e1
React-jsinspector: d4ed52225912efe0019bb7f1a225aec20f23049a React-jsinspector: d4ed52225912efe0019bb7f1a225aec20f23049a
react-native-fbsdk: 080f3bb23513c5b59b6528543206fe0d1436bb7e
React-RCTActionSheet: b27ff3cf3a68f917c46d2b94abf938b625b96570 React-RCTActionSheet: b27ff3cf3a68f917c46d2b94abf938b625b96570
React-RCTAnimation: 9e4708e5bd65fca8285ce7c0aa076f3f4fa5c2f8 React-RCTAnimation: 9e4708e5bd65fca8285ce7c0aa076f3f4fa5c2f8
React-RCTBlob: 6eafcc3a24f33785692a7be24918ade607bc8719 React-RCTBlob: 6eafcc3a24f33785692a7be24918ade607bc8719
@@ -195,11 +239,13 @@ SPEC CHECKSUMS:
React-RCTText: 685fca2e13b024271048e7e247ef24476f28a41e React-RCTText: 685fca2e13b024271048e7e247ef24476f28a41e
React-RCTVibration: 4ee1cf208ab17a50fafb1c16ffe28fe594a64e4f React-RCTVibration: 4ee1cf208ab17a50fafb1c16ffe28fe594a64e4f
React-RCTWebSocket: fca087d583724aa0e5fef7d911f0f2a28d0f2736 React-RCTWebSocket: fca087d583724aa0e5fef7d911f0f2a28d0f2736
RNCAsyncStorage: 2e2e3feb9bdadc752a026703d8c4065ca912e75a
RNGestureHandler: 5329a942fce3d41c68b84c2c2276ce06a696d8b0 RNGestureHandler: 5329a942fce3d41c68b84c2c2276ce06a696d8b0
RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788
RNSecureStorage: 24d433f7673a0daade43689de805933a70641731
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4 RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
yoga: 616fde658be980aa60a2158835170f3f9c2d04b4 yoga: 616fde658be980aa60a2158835170f3f9c2d04b4
PODFILE CHECKSUM: 26223b0d86281b1c70ae009fe120443ad6ad9bf9 PODFILE CHECKSUM: 9a233bb7438f412e17eeb945a7c5f563882773de
COCOAPODS: 1.7.4 COCOAPODS: 1.6.1