diff --git a/app/actions/profile.js b/app/actions/profile.js
index 412a6bc..b7fb866 100644
--- a/app/actions/profile.js
+++ b/app/actions/profile.js
@@ -5,6 +5,7 @@ import {
getNomAvailaibility,
loginUser,
registerNewUser,
+ setNomDeBid as setNomDeBidApi,
} from '../api/profile.js';
import {
@@ -15,11 +16,16 @@ import {
PROFILE_NOM_AVAILABLE,
REGISTRATION_FAILURE,
REGISTRATION_SUCCESS,
+ SET_NOM_FAILURE,
+ SET_NOM_SUCCESS,
UNSET_AUTH,
UNSET_PROFILE,
UPDATE_PROFILE,
} from '../constants/actionTypes.js';
+import { getAuthToken } from '../selectors/auth.js';
+import { getUserId } from '../selectors/profile.js';
+
const isValidEmail = (payload) => ({
type: PROFILE_EMAIL_AVAILABLE,
payload,
@@ -44,6 +50,16 @@ const logoutUser = () => ({
type: DO_LOGOUT,
});
+export const setNomFailure = ({ info }) => ({
+ type: SET_NOM_FAILURE,
+ payload: info,
+});
+
+export const setNomSuccess = ({ nomDeBid }) => ({
+ type: SET_NOM_SUCCESS,
+ payload: nomDeBid,
+});
+
const registrationFailure = (payload) => ({
type: REGISTRATION_FAILURE,
payload,
@@ -71,6 +87,15 @@ export const checkEmailAvailability = (email) => (dispatch) => {};
export const checkNomAvailability = (nomDeBid) => (dispatch) => {};
+export const setNomDeBid = (nomDeBid) => (dispatch, getState) => {
+ const id = getUserId(getState());
+ const auth = getAuthToken(getState());
+
+ setNomDeBidApi({ id, nomDeBid }, auth)
+ .then((result) => dispatch(setNomSuccess(result)))
+ .catch((err) => dispatch(setNomFailure(err)));
+};
+
export const login = (username, password) => (dispatch) => {
dispatch(blockUI());
loginUser(username, password)
diff --git a/app/api/index.js b/app/api/index.js
index 89c035c..b31a991 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -45,11 +45,11 @@ const cacheBuster = () => {
};
export const getEndpointUrl = (endpoint) => {
- if (!endpoints[endpoint]) {
+ if (!API_ENDPOINTS[endpoint]) {
throw new Error('Invalid API endpoint specified');
}
- return `${API_URL}${endpoints[endpoint]}`; //`${cacheBuster()}`;
+ return `${API_URL}${API_ENDPOINTS[endpoint]}`; //`${cacheBuster()}`;
};
export const requestGet = (path, queryParams = [], requestOptions = {}) => {
diff --git a/app/api/profile.js b/app/api/profile.js
index 639e907..28bc3d3 100644
--- a/app/api/profile.js
+++ b/app/api/profile.js
@@ -1,4 +1,4 @@
-import { API_ENDPOINTS, requestGet } from './index.js';
+import { API_ENDPOINTS, requestGet, requestPost } from './index.js';
export const getEmailAvailability = (email) =>
requestGet(`${API_ENDPOINTS.VALIDATE_SIGNUP_EMAIL}/&{encodeURI(email)}`);
@@ -17,3 +17,10 @@ export const registerNewUser = (user) =>
path: API_ENDPOINTS.USER_SIGNUP,
body: { user },
});
+
+export const setNomDeBid = (id, auth) => (nomDeBid) =>
+ requestPost({
+ path: `${API_ENDPOINTS.SET_NOM}/${id}`,
+ body: { nomDeBid },
+ requestOptions: { Authorization: auth ? `Bearer ${auth}` : null },
+ });
diff --git a/app/components/AppHeader/AppHeader.js b/app/components/AppHeader/AppHeader.js
index c6218f3..dac5132 100644
--- a/app/components/AppHeader/AppHeader.js
+++ b/app/components/AppHeader/AppHeader.js
@@ -7,8 +7,6 @@ import HeaderTitle from './HeaderTitle/HeaderTitle.container.js';
import HeaderContentLeft from './HeaderContentLeft.container.js';
import HeaderContentRight from './HeaderContentRight.container.js';
-import styles from './AppHeader.styles.js';
-
export default class AppHeader extends Component {
static get propTypes() {
return {
diff --git a/app/components/AppHeader/AppHeader.styles.js b/app/components/AppHeader/AppHeader.styles.js
deleted file mode 100644
index e69de29..0000000
diff --git a/app/components/AppHeader/HeaderContentLeft.js b/app/components/AppHeader/HeaderContentLeft.js
index 4915467..37c9f6f 100644
--- a/app/components/AppHeader/HeaderContentLeft.js
+++ b/app/components/AppHeader/HeaderContentLeft.js
@@ -1,12 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Text, TouchableOpacity, View } from 'react-native';
-
import BackIcon from './IconButtons/BackIcon.js';
import EventsIcon from './IconButtons/EventsIcon.js';
-export default function HeaderContentLeft({ activeRoute, hasMultipleEvents, navigation }) {
+export default function HeaderContentLeft({
+ activeRoute,
+ hasActiveEvent,
+ hasMultipleEvents,
+ navigation,
+}) {
const _goBack = () => {
if (hasActiveEvent) {
navigation.goBack();
@@ -35,9 +38,11 @@ export default function HeaderContentLeft({ activeRoute, hasMultipleEvents, navi
HeaderContentLeft.propTypes = {
activeRoute: PropTypes.string.isRequired,
hasActiveEvent: PropTypes.bool,
+ hasMultipleEvents: PropTypes.bool,
navigation: PropTypes.func.isRequired,
};
HeaderContentLeft.defaultProps = {
hasActiveEvent: false,
+ hasMultipleEvents: false,
};
diff --git a/app/components/AppHeader/HeaderContentRight.container.js b/app/components/AppHeader/HeaderContentRight.container.js
index 52f77c4..286b43a 100644
--- a/app/components/AppHeader/HeaderContentRight.container.js
+++ b/app/components/AppHeader/HeaderContentRight.container.js
@@ -6,7 +6,9 @@ import HeaderContentRight from './HeaderContentRight.js';
const matchStateToProps = (state, ownProps) => ({
avatarUrl: getProfileAvatarUrl(state),
- hideUserProfileButton: ownProps.navigation.state.routeName === 'Profile',
+ hideUserProfileButton:
+ ['Profile', 'Register', 'SignInOrRegister'].indexOf(ownProps.navigation.state.routeName) >
+ -1,
});
export default connect(
diff --git a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js
index 69ea31e..db36b07 100644
--- a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js
+++ b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js
@@ -1,5 +1,6 @@
import { connect } from 'react-redux';
+import { hasActiveEvent } from '../../../../selectors/activeEvent.js';
import { getActiveEvent, getDefaultEvent } from '../../../../selectors/events.js';
import EventTitle from './EventTitle.js';
diff --git a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.js b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.js
index 6a0958a..e619ab1 100644
--- a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.js
+++ b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.js
@@ -6,12 +6,16 @@ import { Text, TouchableOpacity, View } from 'react-native';
import styles from './EventTitle.styles.js';
export default function EventTitle({ action, date, end, name, start }) {
- const _generateEventTitle = () => (
-
- {name}
- {`${date} | ${start} - ${end}`}
-
- );
+ const _generateEventTitle = () => {
+ const whenString = `${date} | ${start} - ${end}`;
+
+ return (
+
+ {name}
+ {whenString}
+
+ );
+ };
if (action) {
return {_generateEventTitle()};
diff --git a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.styles.js b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.styles.js
index 16fe7ff..127a527 100644
--- a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.styles.js
+++ b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.styles.js
@@ -1,6 +1,6 @@
import { StyleSheet } from 'react-native';
-export default (styles = StyleSheet.create({
+export default StyleSheet.create({
eventInfo: {
flexDirection: 'row',
},
@@ -11,4 +11,4 @@ export default (styles = StyleSheet.create({
eventDate: {
flex: 1,
},
-}));
+});
diff --git a/app/components/AppHeader/HeaderTitle/HeaderTitle.js b/app/components/AppHeader/HeaderTitle/HeaderTitle.js
index 6429c4e..5556270 100644
--- a/app/components/AppHeader/HeaderTitle/HeaderTitle.js
+++ b/app/components/AppHeader/HeaderTitle/HeaderTitle.js
@@ -7,6 +7,10 @@ import EventTitle from './EventTitle/EventTitle.container.js';
import styles from './HeaderTitle.styles.js';
+const STRINGS = {
+ PROFILE: 'Profile',
+};
+
export default function HeaderTitle({
activeRoute,
hasActiveEvent,
@@ -30,13 +34,13 @@ export default function HeaderTitle({
if (activeRoute === 'Events') {
return (
- Profile
+ {STRINGS.PROFILE}
);
}
if (activeRoute === 'Profile') {
- return Profile;
+ return {STRINGS.PROFILE};
}
return ;
diff --git a/app/components/AppHeader/HeaderTitle/HeaderTitle.styles.js b/app/components/AppHeader/HeaderTitle/HeaderTitle.styles.js
index e4c5889..30ef859 100644
--- a/app/components/AppHeader/HeaderTitle/HeaderTitle.styles.js
+++ b/app/components/AppHeader/HeaderTitle/HeaderTitle.styles.js
@@ -1,6 +1,6 @@
import { StyleSheet } from 'react-native';
-export default (styles = StyleSheet.create({
+export default StyleSheet.create({
filterBar: {
backgroundColor: '#0F0',
flexDirection: 'row',
@@ -11,4 +11,4 @@ export default (styles = StyleSheet.create({
view: {
flex: 2,
},
-}));
+});
diff --git a/app/components/AppHeader/IconButtons/BackIcon.js b/app/components/AppHeader/IconButtons/BackIcon.js
index c2e314d..f839cfb 100644
--- a/app/components/AppHeader/IconButtons/BackIcon.js
+++ b/app/components/AppHeader/IconButtons/BackIcon.js
@@ -7,7 +7,7 @@ import { Icon } from 'react-native-elements';
export default function BackIcon({ action }) {
return (
- ;
+
);
}
diff --git a/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js b/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js
index 0832bbb..463fdc3 100644
--- a/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js
+++ b/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js
@@ -1,11 +1,17 @@
import { connect } from 'react-redux';
-import { getProfileAvatarUrl } from '../../../selectors/profile.js';
+import {
+ getProfileAvatarUrl,
+ getUserInitials,
+ isRegisteredAccount,
+} from '../../../selectors/profile.js';
import UserProfileButton from './UserProfileButton.js';
const matchStateToProps = (state) => ({
avatarUrl: getProfileAvatarUrl(state),
+ initials: getUserInitials(state),
+ isRegisteredAccount: isRegisteredAccount(state),
});
export default connect(
diff --git a/app/components/AppHeader/UserProfileButton/UserProfileButton.js b/app/components/AppHeader/UserProfileButton/UserProfileButton.js
index 1897118..d422310 100644
--- a/app/components/AppHeader/UserProfileButton/UserProfileButton.js
+++ b/app/components/AppHeader/UserProfileButton/UserProfileButton.js
@@ -2,11 +2,16 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Image, TouchableOpacity, View } from 'react-native';
-import { Icon } from 'react-native-elements';
+import { Avatar, Icon } from 'react-native-elements';
import styles from './UserProfileButton.styles.js';
-export default function UserProfileButton({ avatarUrl, navigation }) {
+export default function UserProfileButton({
+ avatarUrl,
+ initials,
+ isRegisteredAccount,
+ navigation,
+}) {
const _goToProfile = () => {
navigation.navigate('Profile');
return false;
@@ -14,10 +19,12 @@ export default function UserProfileButton({ avatarUrl, navigation }) {
return (
- {avatarUrl !== null ? (
-
-
-
+ {isRegisteredAccount !== null ? (
+ avatarUrl !== null ? (
+
+ ) : (
+
+ )
) : (
)}
@@ -27,8 +34,12 @@ export default function UserProfileButton({ avatarUrl, navigation }) {
UserProfileButton.propTypes = {
avatarUrl: PropTypes.string,
+ initials: PropTypes.string,
+ isRegisteredAccount: PropTypes.bool,
};
UserProfileButton.propTypes = {
avatarUrl: null,
+ initials: null,
+ isRegisteredAccount: false,
};
diff --git a/app/components/Auction/AuctionListItem.js b/app/components/Auction/AuctionListItem.js
index 341b85d..df3b2b9 100644
--- a/app/components/Auction/AuctionListItem.js
+++ b/app/components/Auction/AuctionListItem.js
@@ -83,28 +83,28 @@ export default class AuctionListItem extends Component {
)}
{type === ITEM_TYPES.AUCTION && }
-
+
{title}
-
+
{subtitle}
{donor && (
-
+
{donor}
)}
{type === ITEM_TYPES.AUCTION ? (
) : (
-
+
{formatPrice(startingPrice)}
)}
{this._getBidTime()}
-
+
{description}
diff --git a/app/components/Auction/AuctionPriceAndBidCount.js b/app/components/Auction/AuctionPriceAndBidCount.js
index 2d25cdd..87a7e9d 100644
--- a/app/components/Auction/AuctionPriceAndBidCount.js
+++ b/app/components/Auction/AuctionPriceAndBidCount.js
@@ -6,9 +6,11 @@ import { formatPrice } from '../../library/helpers.js';
import { StyleSheet, Text } from 'react-native';
const AuctionPriceAndBidCount = ({ bidCount, currentPrice }) => {
+ const _getPriceAndBidString = () => `${formatPrice(currentPrice)} (${bidCount} bids)`;
+
return (
- {`${formatPrice(currentPrice)} (${bidCount} bids)`}
+ {_getPriceAndBidString()}
);
};
diff --git a/app/components/Auction/BidStatus.js b/app/components/Auction/BidStatus.js
index eceed62..5771673 100644
--- a/app/components/Auction/BidStatus.js
+++ b/app/components/Auction/BidStatus.js
@@ -9,7 +9,7 @@ const BidStatus = ({ isBidding, isWinning }) => {
}
const statusBarStyle = isWinning
- ? [styles.bidStatus, styes.isWinning]
+ ? [styles.bidStatus, styles.isWinning]
: [styles.bidStatus, styles.isOutbid];
return (
diff --git a/app/components/Auction/FilterBar.js b/app/components/Auction/FilterBar.js
index 95b926e..3cb434a 100644
--- a/app/components/Auction/FilterBar.js
+++ b/app/components/Auction/FilterBar.js
@@ -3,10 +3,15 @@ import PropTypes from 'prop-types';
import { StyleSheet, Text, View } from 'react-native';
+const STRINGS = {
+ FILTER: 'Filter',
+ VIEW: 'View',
+};
+
const FilterBar = ({ changeFilterer, changeViewMode, filterMode, viewMode }) => (
- Filter
- View
+ {STRINGS.FILTER}
+ {STRINGS.VIEW}
);
diff --git a/app/components/Events/EventListItem.js b/app/components/Events/EventListItem.js
index ed99893..685ebad 100644
--- a/app/components/Events/EventListItem.js
+++ b/app/components/Events/EventListItem.js
@@ -33,24 +33,28 @@ export default class EventListItem extends Component {
constructor(props) {
super(props);
+ this._viewEventDetail = this._viewEventDetail.bind(this);
}
- _viewEventDetail = () => {
+ getTimeString() {
+ const { end, start } = this.props;
+ return `${start} - ${end}`;
+ }
+
+ _viewEventDetail() {
this.props.setActiveEvent(this.props.id);
this.props.navigation.navigate('Event');
- };
+ }
render() {
- const { date, description, end, name, start } = this.props;
+ const { date, description, name } = this.props;
return (
{name}
{date}
-
- {start} - {end}
-
+ {this.getTimeString()}
{description}
diff --git a/app/components/Login/LocalLogin.js b/app/components/Login/LocalLogin.js
index f048815..1bee62d 100644
--- a/app/components/Login/LocalLogin.js
+++ b/app/components/Login/LocalLogin.js
@@ -3,54 +3,51 @@ import PropTypes from 'prop-types';
import { Button, TextInput, View } from 'react-native';
+import styles from './Login.styles.js';
+
export default function LocalLogin({ doLoginAction }) {
+ const [enabled, setEnableSubmit] = useState(false);
+ const [password, setPassword] = useState(null);
+ const [username, setUsername] = useState(null);
- const [ enabled, setEnableSubmit ] = useState(false);
- const [ password, setPassword ] = useState(null);
- const [ username, setUsername ] = useState(null);
+ const _handleLoginSubmit = () => {
+ doLoginAction(username, password);
+ };
- const _handleLoginSubmit = () => {
- doLoginAction(username, password);
- };
+ const _updateState = (field, value) => {
+ if (field === 'username') {
+ setUsername(value);
+ }
- const _updateState = (field, value) => {
- if (field === 'username') {
- setUsername(value);
- }
+ if (field === 'password') {
+ setPassword(value);
+ }
- if (field === 'password') {
- setPassword(value);
- }
+ if (!!username && !!password) {
+ setEnableSubmit(true);
+ }
+ };
- if (!!username && !!password) {
- setEnableSubmit(true);
- }
- };
-
- return (
-
- _updateState('username', text)}
- placeholder="email"
- style={{height: 40}}
- value={username}
- />
- _updateState('password', text)}
- placeholder="password"
- secureTextEntry
- style={{height: 40}}
- value={password}
- />
-
-
- );
+ return (
+
+ _updateState('username', text)}
+ placeholder="email"
+ style={styles.textInput}
+ value={username}
+ />
+ _updateState('password', text)}
+ placeholder="password"
+ secureTextEntry
+ style={styles.textInput}
+ value={password}
+ />
+
+
+ );
}
LocalLogin.propTypes = {
diff --git a/app/components/Login/Login.styles.js b/app/components/Login/Login.styles.js
new file mode 100644
index 0000000..bdaab72
--- /dev/null
+++ b/app/components/Login/Login.styles.js
@@ -0,0 +1,8 @@
+import { StyleSheet } from 'react-native';
+
+export default StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ textInput: {},
+});
diff --git a/app/components/Profile/EditNomDeBid.container.js b/app/components/Profile/EditNomDeBid.container.js
new file mode 100644
index 0000000..1b98eba
--- /dev/null
+++ b/app/components/Profile/EditNomDeBid.container.js
@@ -0,0 +1,20 @@
+import { connect } from 'react-redux';
+
+import { setNomDeBid } from '../../actions/profile.js';
+import { getNomDeBid, isGeneratedNomDeBid } from '../../selectors/profile.js';
+
+import EditNomDeBid from './EditNomDeBid.js';
+
+const matchStateToProps = (state) => ({
+ isGeneratedNomDeBid: isGeneratedNomDeBid(state),
+ nomDeBid: getNomDeBid(state),
+});
+
+const matchDispatchToProps = (dispatch) => ({
+ updateNomDeBid: (nomDeBid) => dispatch(setNomDeBid(nomDeBid)),
+});
+
+export default connect(
+ matchStateToProps,
+ matchDispatchToProps,
+)(EditNomDeBid);
diff --git a/app/components/Profile/EditNomDeBid.js b/app/components/Profile/EditNomDeBid.js
new file mode 100644
index 0000000..235683e
--- /dev/null
+++ b/app/components/Profile/EditNomDeBid.js
@@ -0,0 +1,79 @@
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+import { Button, Text, TextInput, View } from 'react-native';
+import { Avatar } from 'react-native-elements';
+
+import { getNomAvailaibility } from '../../api/profile.js';
+import styles from './Profile.styles.js';
+
+const STRINGS = {
+ ABOUT_GENERATED_NOM:
+ 'You currently have a generated Nom De Bid - the alias other bidders will know you as - why not personalize it?',
+ NOM_EXPLANATION:
+ "Selecting a nom de bid allows you to bid anonymously - or not. By default, we'll use your first initial and last name.",
+ ONLY_SET_ONCE: 'This can only be set once!',
+ SUBMIT_NOM: 'Set Nom De Bid',
+};
+
+export default function EditNomDeBid({
+ isGeneratedNomDeBid,
+ isStandalone,
+ nomDeBid,
+ updateNomDeBid,
+}) {
+ const [newNom, setNomDeBid] = useState(isGeneratedNomDeBid || !nomDeBid ? '' : nomDeBid);
+ const [isNomValid, setValidNom] = useState(false);
+
+ const _handleEndEditing = (nomDeBid) => {
+ getNomAvailaibility(nomDeBid).then((result) => {
+ setValidNom(result.available);
+
+ if (isStandalone) {
+ updateNomDeBid(nomDeBid);
+ }
+ });
+ };
+
+ const _handleSubmitNom = () => {
+ if (isNomValid) {
+ updateNomDeBid(newNom);
+ }
+ };
+
+ const explanationString = isGeneratedNomDeBid
+ ? `${STRINGS.ABOUT_GENERATED_NOM} ${STRINGS.ONLY_SET_ONCE}`
+ : `${STRINGS.NOM_EXPLANATION} ${STRINGS.ONLY_SET_ONCE}`;
+
+ return (
+
+ {explanationString}
+ setNomDeBid(text)}
+ onEndEditing={(text) => _handleEndEditing(text)}
+ placeholder="nom de bid"
+ style={[styles.textInput, styles.requiredInput]}
+ value={newNom}
+ />
+ {!isStandalone && (
+
+ )}
+
+ );
+}
+
+EditNomDeBid.propTypes = {
+ isGeneratedNomDeBid: PropTypes.bool,
+ isStandalone: PropTypes.bool,
+ nomDeBid: PropTypes.string,
+ updateNomDeBid: PropTypes.func.isRequired,
+};
+
+EditNomDeBid.defaultProps = {
+ isGeneratedNomDeBid: false,
+ isStandalone: false,
+ nomDeBid: null,
+};
diff --git a/app/components/Profile/EditProfile.container.js b/app/components/Profile/EditProfile.container.js
index aead19e..e109147 100644
--- a/app/components/Profile/EditProfile.container.js
+++ b/app/components/Profile/EditProfile.container.js
@@ -1,9 +1,10 @@
import { connect } from 'react-redux';
+import { getProfile } from '../../selectors/profile.js';
import { commonProfileStateToProps } from './Profile.container.js';
import EditProfile from './EditProfile.js';
-const matchStateToProps = (dispatch) => {
+const matchStateToProps = (state) => {
const commonProps = commonProfileStateToProps(state);
const profile = getProfile(state);
@@ -14,4 +15,7 @@ const matchStateToProps = (dispatch) => {
};
};
-export default connect(matchStateToProps, null)(EditProfile);
+export default connect(
+ matchStateToProps,
+ null,
+)(EditProfile);
diff --git a/app/components/Profile/EditProfile.js b/app/components/Profile/EditProfile.js
index f352816..9c0a3d4 100644
--- a/app/components/Profile/EditProfile.js
+++ b/app/components/Profile/EditProfile.js
@@ -1,19 +1,19 @@
import React, { Component } from 'react';
-import { Text, TextInput, View } from 'react-native';
+import PropTypes from 'prop-types';
+import { Button, Text, TextInput, View } from 'react-native';
import { Avatar } from 'react-native-elements';
import { getEmailAvailability, getNomAvailability } from '../api/profile.js';
+import EditNomDeBid from './EditNomDeBid.js';
import styles from './Profile.styles.js';
const STRINGS = {
- CANCEL: 'Cancel',
- NOM_EXPLANATION: 'Selecting a nom de bid allows you to bid anonymously - or not. By default, we\'ll use your first initial and last name.',
- SAVE_PROFILE: 'Save profile',
+ CANCEL: 'Cancel',
+ SAVE_PROFILE: 'Save profile',
};
export default class EditProfile extends Component {
-
static get propTypes() {
return {
addresses: PropTypes.array,
@@ -22,6 +22,7 @@ export default class EditProfile extends Component {
email: PropTypes.string,
firstName: PropTypes.string,
initials: PropTypes.string,
+ isGeneratedNomDeBid: PropTypes.bool,
lastName: PropTypes.string,
nomDeBid: PropTypes.string,
phones: PropTypes.array,
@@ -37,6 +38,7 @@ export default class EditProfile extends Component {
email: null,
firstName: null,
initials: null,
+ isGeneratedNomDeBid: false,
lastName: null,
nomDeBid: null,
phones: null,
@@ -44,7 +46,7 @@ export default class EditProfile extends Component {
};
}
- constructor() {
+ constructor(props) {
super(props);
this.state = {
@@ -65,11 +67,15 @@ export default class EditProfile extends Component {
}
_validateEmail() {
- getEmailAvailability(this.state.email, (result) => this.setState('invalidEmail', !result.available));
+ getEmailAvailability(this.state.email, (result) =>
+ this.setState('invalidEmail', !result.available),
+ );
}
_validateNomDeBid() {
- getNomAvailability(this.state.nomDeBid, (result) => this.setState('invalidNomDeBid', !result.available));
+ getNomAvailability(this.state.nomDeBid, (result) =>
+ this.setState('invalidNomDeBid', !result.available),
+ );
}
getProfileFromState() {
@@ -100,16 +106,23 @@ export default class EditProfile extends Component {
}
isFormComplete() {
- return !this.state.invalidEmail && !this.state.invalidNomDeBid &&
- !!this.state.firstName && !!this.state.lastName && !!this.state.email &&
- !!this.state.nomDeBid && !!this.state.phones.length && !!this.state.password;
+ return (
+ !this.state.invalidEmail &&
+ !this.state.invalidNomDeBid &&
+ !!this.state.firstName &&
+ !!this.state.lastName &&
+ !!this.state.email &&
+ !!this.state.nomDeBid &&
+ !!this.state.phones.length &&
+ !!this.state.password
+ );
}
render() {
+ const { isGeneratedNomDeBid } = this.props;
const { avatar, firstName, lastName } = this.state;
- const avatarTitle = !avatar && firstName && lastName
- ? `${firstName.substring(0,1)}${lastName.substring(0,1)}`
- : null;
+ const addressesTitle = 'Addresses';
+ const numbersTitle = 'Numbers';
return (
@@ -144,29 +157,31 @@ export default class EditProfile extends Component {
value={this.state.email}
/>
-
- {STRINGS.NOM_EXPLANATION}
- this.setState({ nomDeBid: text })}
- onEndEditing={(text) => this._validateEmail(text)}
- placeholder="nom de bid"
- style={[styles.textInput, styles.requiredInput]}
- value={this.state.nomDeBid}
- />
-
+ {isGeneratedNomDeBid && (
+
+ this.setState({ nomDeBid })}
+ />
+
+ )}
- Numbers
- {phones.length > 0 && (
- // LIST PHONES
+ {numbersTitle}
+ {this.props.phones.length > 0 && (
+ /* LIST PHONES */
+
)}
-
- Addresses
- {addresses.length > 0 && (
- // LIST ADDRESSES
+ {addressesTitle}
+ {this.props.addresses.length > 0 && (
+ /* LIST ADDRESSES */
+
)}
- false}/>
+ false} />
diff --git a/app/components/Profile/Profile.container.js b/app/components/Profile/Profile.container.js
index 1a08697..694cb6d 100644
--- a/app/components/Profile/Profile.container.js
+++ b/app/components/Profile/Profile.container.js
@@ -1,6 +1,6 @@
import { connect } from 'react-redux';
-import { getProfile } from '../selectors/profile.js';
+import { getProfile, isGeneratedNomDeBid } from '../selectors/profile.js';
import Profile from './Profile.js';
@@ -12,9 +12,13 @@ export const commonProfileStateToProps = (state) => {
avatar: profile.get('avatar'),
email: profile.get('email'),
initials: profile.get('initials'),
+ isGeneratedNomDeBid: isGeneratedNomDeBid(state),
nomDeBid: profile.get('nomDeBid'),
phones: profile.get('phones'),
};
};
-export default connect(commonProfileStateToProps, null)(Profile);
+export default connect(
+ commonProfileStateToProps,
+ null,
+)(Profile);
diff --git a/app/components/Profile/Profile.js b/app/components/Profile/Profile.js
index d97dcc2..287efca 100644
--- a/app/components/Profile/Profile.js
+++ b/app/components/Profile/Profile.js
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
+import PropTypes from 'prop-types';
import { View } from 'react-native';
import EditProfile from './EditProfile.container.js';
@@ -20,7 +21,7 @@ export default function Profile({
const _saveProfileAction = (profile) => {
setEditMode(false);
saveProfileAction(profile);
- }
+ };
return (
diff --git a/app/components/Profile/Profile.styles.js b/app/components/Profile/Profile.styles.js
index e69de29..bdaab72 100644
--- a/app/components/Profile/Profile.styles.js
+++ b/app/components/Profile/Profile.styles.js
@@ -0,0 +1,8 @@
+import { StyleSheet } from 'react-native';
+
+export default StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ textInput: {},
+});
diff --git a/app/components/Profile/ViewProfile.container.js b/app/components/Profile/ViewProfile.container.js
index 5216149..474addd 100644
--- a/app/components/Profile/ViewProfile.container.js
+++ b/app/components/Profile/ViewProfile.container.js
@@ -1,17 +1,23 @@
import { connect } from 'react-redux';
+import { getProfile } from '../../selectors/profile.js';
import { commonProfileStateToProps } from './Profile.container.js';
+import { isRegisteredAccount } from '../../selectors/profile.js';
+
import ViewProfile from './ViewProfile.js';
-const matchStateToProps = (dispatch) => {
+const matchStateToProps = (state) => {
const commonProps = commonProfileStateToProps(state);
const profile = getProfile(state);
return {
...commonProps,
fullName: profile.get('fullName'),
- generatedNomDeBid: propfile.get('generatedNomDeBid'),
+ isRegisteredAccount: isRegisteredAccount(state),
};
};
-export default connect(matchStateToProps, null)(ViewProfile);
+export default connect(
+ matchStateToProps,
+ null,
+)(ViewProfile);
diff --git a/app/components/Profile/ViewProfile.js b/app/components/Profile/ViewProfile.js
index f4a9966..bcb8910 100644
--- a/app/components/Profile/ViewProfile.js
+++ b/app/components/Profile/ViewProfile.js
@@ -1,13 +1,14 @@
import React, { useState } from 'react';
-import { Text, TextInput, View } from 'react-native';
+import PropTypes from 'prop-types';
+import { Button, Text, TextInput, View } from 'react-native';
import { Avatar } from 'react-native-elements';
-import { getEmailAvailability, getNomAvailability } from '../api/profile.js';
+import EditNomDeBid from './EditNomDeBid.container.js';
import styles from './Profile.styles.js';
const STRINGS = {
- EDIT: 'Edit profile',
+ EDIT: 'Edit profile',
};
export default function ViewProfile({
@@ -16,16 +17,22 @@ export default function ViewProfile({
editProfileAction,
email,
fullName,
- generatedNomDeBid,
initials,
+ isGeneratedNomDeBid,
+ isRegisteredAccount,
nomDeBid,
phones,
}) {
- const addressesCount = addresses.length;
- const phonesCount = phones.length;
+ const _getSavedText = (count) => `${count} saved`;
+ const addressesCountString = _getSavedText(addresses.length);
+ const phonesCountString = _getSavedText(phones.length);
const [isEditingNom, setEditNom] = useState(false);
+ const addressesTitle = 'addresses';
+ const emailTitle = 'email';
+ const numbersTitle = 'numbers';
+
return (
@@ -39,33 +46,30 @@ export default function ViewProfile({
{fullName}
{isEditingNom ? (
-
) : (
- {nomDeBid}
- {generatedNomDeBid && (
- setEditNom(true)}
- />
- )}
+ {nomDeBid}
+ )}
+ {!isEditingNom && isGeneratedNomDeBid && isRegisteredAccount && (
+ setEditNom(true)} />
)}
- email
- {email}
+ {emailTitle}
+ {email}
- numbers
- {`${phonesCount} saved`}
+ {numbersTitle}
+ {phonesCountString}
- addresses
- {`${addressesCount} saved`}
+ {addressesTitle}
+ {addressesCountString}
{editProfileAction !== null && (
-
+
)}
@@ -78,8 +82,9 @@ ViewProfile.propTypes = {
editProfileAction: PropTypes.func,
email: PropTypes.string,
fullName: PropTypes.string,
- generatedNomDeBid: PropTypes.bool,
initials: PropTypes.string,
+ isGeneratedNomDeBid: PropTypes.bool,
+ isRegisteredAccount: PropTypes.bool,
nomDeBid: PropTypes.string,
phones: PropTypes.array,
};
@@ -90,13 +95,9 @@ ViewProfile.defaultProps = {
editProfileAction: null,
email: null,
fullName: null,
- generatedNomDeBid: false,
initials: null,
+ isGeneratedNomDeBid: false,
+ isRegisteredAccount: false,
nomDeBid: null,
phones: [],
};
-
- return (
- );
- }
-}
diff --git a/app/constants/actionTypes.js b/app/constants/actionTypes.js
index b744aee..1ca4d81 100644
--- a/app/constants/actionTypes.js
+++ b/app/constants/actionTypes.js
@@ -50,6 +50,9 @@ export const UNSET_PROFILE = 'UNSET_PROFILE';
export const UPDATE_PROFILE = 'UPDATE_PROFILE';
export const SET_NOM_DE_BID = 'SET_NOM_DE_BID';
+export const SET_NOM_FAILURE = 'SET_NOM_FAILURE';
+export const SET_NOM_SUCCESS = 'SET_NOM_SUCCESS';
+
export const SET_PASSWORD = 'SET_PASSWORD';
export const ADD_PAYMENT_DATA = 'ADD_PAYMENT_DATA';
diff --git a/app/containers/Events/EventListItem.js b/app/containers/Events/EventListItem.js
index c783c8c..fa95e0b 100644
--- a/app/containers/Events/EventListItem.js
+++ b/app/containers/Events/EventListItem.js
@@ -27,5 +27,5 @@ const mapDispatchToProps = (dispatch) => ({
export default connect(
mapStateToProps,
- null,
-)(AuctionListItem);
+ mapDispatchToProps,
+)(EventListItem);
diff --git a/app/domain/Profile.js b/app/domain/Profile.js
index f5629f4..110df7a 100644
--- a/app/domain/Profile.js
+++ b/app/domain/Profile.js
@@ -29,8 +29,8 @@ export default class Profile extends Record({
}
get initials() {
- const firstInitial = this.firstName ? this.firstName.substring(0,1) : null;
- const lastInitial = this.firstName ? this.firstName.substring(0,1) : null;
+ const firstInitial = this.firstName ? this.firstName.substring(0, 1) : null;
+ const lastInitial = this.firstName ? this.firstName.substring(0, 1) : null;
if (!firstInitial && !lastInitial) {
return null;
diff --git a/app/router.js b/app/router.js
index f0398c8..1799cc6 100644
--- a/app/router.js
+++ b/app/router.js
@@ -150,43 +150,3 @@ export const Tabs = createBottomTabNavigator({
},
},
});
-
-export const createRootNavigator = () => {
- return StackNavigator(
- {
- AuctionStack: {
- screen: AuctionStack,
- navigationOptions: {
- gesturesEnabled: false,
- },
- },
- BazaarStack: {
- screen: BazaarStack,
- navigationOptions: {
- gesturesEnabled: false,
- },
- },
- EventsStack: {
- screen: EventsStack,
- navigationOptions: {
- gesturesEnabled: false,
- },
- },
- SignInOrRegisterStack: {
- screen: SignInOrRegister,
- navigationOptions: {
- gesturesEnabled: false,
- },
- },
- Tabs: {
- screen: Tabs,
- navigationOptions: {
- gesturesEnabled: false,
- },
- },
- },
- {
- mode: 'modal',
- },
- );
-};
diff --git a/app/screens/Auction.container.js b/app/screens/Auction.container.js
index 1c2023e..ece2f6d 100644
--- a/app/screens/Auction.container.js
+++ b/app/screens/Auction.container.js
@@ -7,17 +7,16 @@ import { getAuctionItemsAsList } from '../selectors/items.js';
import Auction from './Auction.js';
-const matchStateToProps = (state) => {
- const items = getAuctionItemsAsList(state);
- console.log('items:', items);
+const changeViewMode = () => true;
- return { items };
-};
+const matchStateToProps = (state) => ({
+ items: getAuctionItemsAsList(state),
+});
const mapDispatchToProps = (dispatch) => ({
changeViewMode: (mode) => dispatch(changeViewMode(mode)),
- fetchItems: () => dispatch(fetchItems(dispatch)),
- fetchStatus: () => dispatch(fetchAuctionStatus(dispatch)),
+ fetchItems: () => dispatch(fetchItems()),
+ fetchStatus: () => dispatch(fetchAuctionStatus()),
});
export default connect(
diff --git a/app/screens/Auction.styles.js b/app/screens/Auction.styles.js
index 6720eb7..58f42cc 100644
--- a/app/screens/Auction.styles.js
+++ b/app/screens/Auction.styles.js
@@ -1,6 +1,6 @@
import { StyleSheet } from 'react-native';
-export default (styles = StyleSheet.create({
+export default StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
@@ -14,4 +14,4 @@ export default (styles = StyleSheet.create({
alignItems: 'stretch',
justifyContent: 'flex-start',
},
-}));
+});
diff --git a/app/screens/Checkout.js b/app/screens/Checkout.js
index d0ec3f3..571f9d5 100644
--- a/app/screens/Checkout.js
+++ b/app/screens/Checkout.js
@@ -3,9 +3,11 @@ import { StyleSheet, Text, View } from 'react-native';
export default class Checkout extends Component {
render() {
+ const title = 'Checkout';
+
return (
- Checkout
+ {title}
);
}
diff --git a/app/screens/Event.js b/app/screens/Event.js
index 3aedc03..94c5f9d 100644
--- a/app/screens/Event.js
+++ b/app/screens/Event.js
@@ -73,7 +73,7 @@ export default class Event extends Component {
return (
- Event
+ {title}
);
}
diff --git a/app/screens/Event.styles.js b/app/screens/Event.styles.js
index 39118d6..cebb486 100644
--- a/app/screens/Event.styles.js
+++ b/app/screens/Event.styles.js
@@ -1,6 +1,6 @@
import { StyleSheet } from 'react-native';
-export default (styles = StyleSheet.create({
+export default StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
@@ -12,4 +12,4 @@ export default (styles = StyleSheet.create({
textAlign: 'center',
margin: 10,
},
-}));
+});
diff --git a/app/screens/Events.js b/app/screens/Events.js
index 1cf44ad..e269038 100644
--- a/app/screens/Events.js
+++ b/app/screens/Events.js
@@ -2,7 +2,7 @@ import { List } from 'immutable';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { FlatList, StyleSheet, Text, View } from 'react-native';
+import { FlatList, StyleSheet, View } from 'react-native';
import EventListItem from '../components/Events/EventListItem.js';
diff --git a/app/screens/ImageDetail.js b/app/screens/ImageDetail.js
index 26baa60..e73d143 100644
--- a/app/screens/ImageDetail.js
+++ b/app/screens/ImageDetail.js
@@ -3,9 +3,11 @@ import { StyleSheet, Text, View } from 'react-native';
export default class ImageDetail extends Component {
render() {
+ const title = 'Item';
+
return (
- Item
+ {title}
);
}
diff --git a/app/screens/Item.js b/app/screens/Item.js
index fbeb669..50ad0a3 100644
--- a/app/screens/Item.js
+++ b/app/screens/Item.js
@@ -3,9 +3,11 @@ import { StyleSheet, Text, View } from 'react-native';
export default class Item extends Component {
render() {
+ const title = 'Item';
+
return (
- Item
+ {title}
);
}
diff --git a/app/screens/Login.js b/app/screens/Login.js
deleted file mode 100644
index 3a838dd..0000000
--- a/app/screens/Login.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import React, { Component } from 'react';
-import { StyleSheet, Text, View } from 'react-native';
-
-export default class Login extends Component {
- render() {
- return (
-
- Login
-
- );
- }
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#F5FCFF',
- },
- title: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
- },
-});
diff --git a/app/screens/Marketplace.js b/app/screens/Marketplace.js
index 6aada5b..4db0446 100644
--- a/app/screens/Marketplace.js
+++ b/app/screens/Marketplace.js
@@ -9,7 +9,7 @@ import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js';
import FilterBar from '../components/Auction/FilterBar.js';
import AuctionListItem from '../containers/Auction/AuctionListItem.js';
-//import styles from './Marketplace.styles.js';
+import styles from './Auction.styles.js';
export default class Marketplace extends Component {
static get propTypes() {
diff --git a/app/screens/Profile.js b/app/screens/Profile.js
index 706ddd2..c5ba3e4 100644
--- a/app/screens/Profile.js
+++ b/app/screens/Profile.js
@@ -1,12 +1,16 @@
import React, { Component } from 'react';
+import PropTypes from 'prop-types';
import { Text, View } from 'react-native';
import ProfileUtility from '../components/Profile/Profile.container.js';
import styles from './Profile.styles.js';
-export default class Profile extends Component {
+const STRINGS = {
+ EMAIL_NEEDS_VERIFICATION: 'Your acount has not been verified, please check your email.',
+};
+export default class Profile extends Component {
static get propTypes() {
return {
hasLinkedApple: PropTypes.bool,
@@ -48,9 +52,7 @@ export default class Profile extends Component {
{!isVerified && (
-
- {`Your acount has not been verified, please check your email.`}
-
+ {STRINGS.EMAIL_NEEDS_VERIFICATION}
)}
@@ -62,24 +64,30 @@ export default class Profile extends Component {
{!isAllowedToBid ? (
/* ADD PAYMENT METHOD */
+
) : (
/* SHOW/EDIT PAYMENT METHOD */
+
)}
{!hasLocalAccount && (
/* CREATE LOCAL ACCOUNT PASSWORD CTA */
+
)}
{hasLinkedApple && (
/* APPLE LINK/UNLINK */
+
)}
{hasLinkedFacebook && (
/* FACEBOOK LINK/UNLINK */
+
)}
{hasLinkedGoogle && (
/* GOOGLE LINK/UNLINK */
+
)}
);
diff --git a/app/screens/Register.js b/app/screens/Register.js
index 5ab2f7c..21d5277 100644
--- a/app/screens/Register.js
+++ b/app/screens/Register.js
@@ -1,4 +1,5 @@
import React from 'react';
+import PropTypes from 'prop-types';
import { Text, View } from 'react-native';
import EditProfile from '../components/Profile/EditProfile.container.js';
@@ -6,6 +7,7 @@ import EditProfile from '../components/Profile/EditProfile.container.js';
import styles from './Register.styles.js';
export default function Register({ doRegistration, navigation }) {
+ const title = 'Register';
const _doRegistration = (profile) => {
if (!profile) {
@@ -16,14 +18,14 @@ export default function Register({ doRegistration, navigation }) {
};
return (
-
- Register
- navigation.goBack()}
- saveProfileAction={doRegistration}
- saveProfileLabel="Register"
- />
-
+
+ {title}
+ navigation.goBack()}
+ saveProfileAction={_doRegistration}
+ saveProfileLabel="Register"
+ />
+
);
}
diff --git a/app/screens/SignInOrRegister.js b/app/screens/SignInOrRegister.js
index 666dfa7..0762591 100644
--- a/app/screens/SignInOrRegister.js
+++ b/app/screens/SignInOrRegister.js
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-import { Text, View } from 'react-native';
+import { Button, Text, View } from 'react-native';
import FacebookLogin from '../components/Login/FacebookLogin.container.js';
import LocalLogin from '../components/Login/LocalLogin.container.js';
@@ -7,9 +7,11 @@ import LocalLogin from '../components/Login/LocalLogin.container.js';
import styles from './SignInOrRegister.styles.js';
export default function SignInOrRegister({ navigation }) {
+ const title = 'Sign In or Register';
+
return (
- Sign In or Register
+ {title}
diff --git a/app/screens/SignInOrRegister.styles.js b/app/screens/SignInOrRegister.styles.js
index 39118d6..cebb486 100644
--- a/app/screens/SignInOrRegister.styles.js
+++ b/app/screens/SignInOrRegister.styles.js
@@ -1,6 +1,6 @@
import { StyleSheet } from 'react-native';
-export default (styles = StyleSheet.create({
+export default StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
@@ -12,4 +12,4 @@ export default (styles = StyleSheet.create({
textAlign: 'center',
margin: 10,
},
-}));
+});
diff --git a/app/screens/Ticketing.js b/app/screens/Ticketing.js
index ce18c59..eb2818e 100644
--- a/app/screens/Ticketing.js
+++ b/app/screens/Ticketing.js
@@ -3,9 +3,11 @@ import { StyleSheet, Text, View } from 'react-native';
export default class Ticketing extends Component {
render() {
+ const title = 'Ticketing';
+
return (
- Ticketing
+ {title}
);
}
diff --git a/app/selectors/auctions.js b/app/selectors/auctions.js
index 743f4b3..9fb471b 100644
--- a/app/selectors/auctions.js
+++ b/app/selectors/auctions.js
@@ -1,3 +1,4 @@
+import { Map } from 'immutable';
import { createSelector } from 'reselect';
const getState = (state) => state;
@@ -16,7 +17,7 @@ export const getAuctionStatus = (state, itemId) => state.getIn(['actions', itemI
export const getAuctionStatuses = createSelector(
[getState],
- (state) => state.get('actions') || new Map(),
+ (state) => state.get('autions') || new Map(),
);
export const getItemsIdsWithNoBids = createSelector(
diff --git a/app/selectors/profile.js b/app/selectors/profile.js
index 2955690..532952b 100644
--- a/app/selectors/profile.js
+++ b/app/selectors/profile.js
@@ -18,7 +18,27 @@ export const getProfileAvatarUrl = createSelector(
(profile) => profile.get('avatar'),
);
+export const getUserId = createSelector(
+ [getProfile],
+ (profile) => profile.get('id'),
+);
+
+export const getUserInitials = createSelector(
+ [getProfile],
+ (profile) => profile.get('initials'),
+);
+
export const isAllowedToBid = createSelector(
[getProfile],
(profile) => profile.get('isAllowedToBid'),
);
+
+export const isGeneratedNomDeBid = createSelector(
+ [getProfile],
+ (profile) => profile.get('generatedNomDeBid'),
+);
+
+export const isRegisteredAccount = createSelector(
+ [getProfile],
+ (profile) => profile.get('isRegisteredAccount'),
+);