diff --git a/app/App.js b/app/App.js
index 5f821e9..c0b07db 100644
--- a/app/App.js
+++ b/app/App.js
@@ -6,7 +6,7 @@
* @flow
*/
-import React, {Fragment} from 'react';
+import React from 'react';
import { createAppContainer } from 'react-navigation';
import { Tabs } from './router.js';
diff --git a/app/actions/events.js b/app/actions/events.js
index a926f1b..b52ef30 100644
--- a/app/actions/events.js
+++ b/app/actions/events.js
@@ -1,33 +1,36 @@
import { List } from 'immutable';
-import { getEndpointUrl } from '../api/index.js';
-
+import { blockUI, unblockUI } from './index.js';
+import { fetchEvents as fetchEventsApi } from '../api/events.js';
import {
+ EVENTS_LOAD_FAILED,
EVENTS_LOADED,
GET_EVENTS,
} from '../constants/actionTypes.js';
-
-import { blockUI, unblockUI } from './index.js';
-import { API_ENDPOINTS } from '../constants/constants.js';
-
import Event from '../domain/Event.js';
+import { getAuthToken } from '../selectors/auth.js';
+const eventsLoaded = (payload) => ({ type: EVENTS_LOADED, payload });
-const eventsLoadSuccess = (events, dispatch) => {
- const payload = List(events).map((i) => Event.fromJS(i));
- dispatch({ type: EVENTS_LOADED, payload });
+const eventsLoadError = (payload) => ({ type: EVENTS_LOAD_FAILED, payload });
+
+const eventsFetchSuccess = (items) => (dispatch) => {
+ const payload = List(items).map((i) => Event.fromJS(i));
+
+ dispatch(eventsLoaded(payload));
dispatch(unblockUI);
};
-export const setActiveEvent = (eventId) => ({
- type: SET_ACTIVE_EVENT,
- payload: eventId,
-});
-
-export const fetchEvents = () => (dispatch) => {
- dispatch(blockUI());
- fetch(getEndpointUr(API_ENDPOINTS.GET_EVENTS))
- .then(response => response.json())
- .then(payload => eventsLoadSuccess(payload, dispatch))
- .catch(err => console.error('[actions::getEvents]', err));
+const eventsFetchFailure = (error) => (dispatch) => {
+ console.error('[actions::events::eventsFetchFailure]', error);
+ dispatch(eventsLoadError(error));
+ dispatch(unblockUI);
+};
+
+export const fetchEvents = () => (dispatch, getState) => {
+ const authToken = getAuthToken(getState());
+
+ fetchEventsApi(authToken)
+ .then(payload => dispatch(eventsFetchSuccess(payload)))
+ .catch(err => dispatch(eventsFetchFailure(err)));
};
diff --git a/app/actions/items.js b/app/actions/items.js
index 73a1c05..becac35 100644
--- a/app/actions/items.js
+++ b/app/actions/items.js
@@ -1,12 +1,12 @@
import { List } from 'immutable';
-import { fetchItems } from '../api/items.js';
+import { fetchItems as fetchItemsApi } from '../api/items.js';
import {
GET_ITEMS,
ITEMS_LOADED,
} from '../constants/actionTypes.js';
import { getActiveEventId } from '../selectors/activeEvent.js';
-import { getLoginToken } from '../selectors/profile.js';
+import { getAuthToken } from '../selectors/auth.js';
import { blockUI, unblockUI } from './index.js';
@@ -24,16 +24,16 @@ const itemsFetchSuccess = (items) => (dispatch) => {
};
const itemsFetchFailure = (error) => (dispatch) => {
- console.error('[actions::getItems]', error));
+ console.error('[actions::items::itemsFetchFailure]', error);
dispatch(itemsLoadFailure(error));
dispatch(unblockUI);
};
export const fetchItems = () => (dispatch, getState) => {
const eventId = getActiveEventId(getState());
- const authToken = getLoginToken(getState());
+ const authToken = getAuthToken(getState());
- fetchItems(activeEvent, authToken)
+ fetchItemsApi(activeEvent, authToken)
.then(payload => dispatch(itemsFetchSuccess(payload)))
- .catch(err => dispatch(itemsFetchFailure(err));
+ .catch(err => dispatch(itemsFetchFailure(err)));
};
diff --git a/app/actions/profile.js b/app/actions/profile.js
index cd29173..9e6b0da 100644
--- a/app/actions/profile.js
+++ b/app/actions/profile.js
@@ -3,13 +3,18 @@ import { blockUI, unblockUI } from './index.js';
import {
getEmailAvailability,
getNomAvailaibility,
+ loginUser,
registerNewUser,
} from '../api/profile.js';
import {
DO_LOGOUT,
+ LOGIN_FAILURE,
+ LOGIN_SUCCESS,
PROFILE_EMAIL_AVAILABLE,
PROFILE_NOM_AVAILABLE,
+ UNSET_AUTH,
+ UNSET_PROFILE,
UPDATE_PROFILE,
} from '../constants/actionTypes.js';
@@ -23,6 +28,16 @@ const isValidNom = (payload) => ({
payload,
});
+const loginFailure = (payload) => ({
+ type: LOGIN_FAILURE,
+ payload,
+});
+
+const loginSuccess = (payload) => ({
+ type: LOGIN_SUCCESS,
+ payload,
+});
+
const logoutUser = () => ({
type: DO_LOGOUT,
});
@@ -37,6 +52,14 @@ const registrationSuccess = (payload) => ({
payload,
});
+const unsetAuth = () => ({
+ type: UNSET_AUTH,
+});
+
+const unsetProfile = () => ({
+ type: UNSET_PROFILE,
+});
+
const updateProfile = (profile) => ({
type: UPDATE_PROFILE,
payload: profile,
@@ -50,8 +73,20 @@ export const checkNomAvailability = (nomDeBid) => (dispatch) => {
};
+export const login = (username, password) => (dispatch) => {
+ dispatch(blockUI());
+ loginUser(username, password)
+ .then(result => {
+ dispatch(loginSuccess(result))
+ })
+ .catch(err => dispatch(loginFailure(err)));
+};
-export const logout = () => (dispatch) => dispatch(logoutUser());
+export const logout = () => (dispatch) => {
+ dispatch(unsetProfile());
+ dispatch(unsetAuth());
+ dispatch(logoutUser());
+};
// USER REGISTRATION
const handleRegistrationSuccess = (user) => (dispatch) => {
diff --git a/app/api/events.js b/app/api/events.js
new file mode 100644
index 0000000..1cf72ae
--- /dev/null
+++ b/app/api/events.js
@@ -0,0 +1,7 @@
+import { API_ENDPOINTS, requestGet } from './index.js';
+
+export const fetchEvents = (auth) => {
+ const path = String(API_ENDPOINTS.GET_EVENTS);
+ const opts = { Authorization: auth ? `Bearer ${auth}` : null };
+ return requestGet(path, null, opts);
+};
diff --git a/app/api/helpers.js b/app/api/helpers.js
index fbc2f47..2ddea3c 100644
--- a/app/api/helpers.js
+++ b/app/api/helpers.js
@@ -40,7 +40,7 @@ const parseQueryParamsString = (queryParams) => {
};
const parseQueryParamsObject = (queryParams) => {
- if (typeof queryParams !== 'object' && Array.isArray(queryParams)) {
+ if (queryParams === null || typeof queryParams !== 'object' || Array.isArray(queryParams)) {
return null;
}
diff --git a/app/api/index.js b/app/api/index.js
index f2cac76..408053b 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -11,7 +11,7 @@ import { API_URL } from '../constants/constants.js';
const DefaultRequestOptions = {};
-const endpoints = {
+export const API_ENDPOINTS = {
// Events and Items
GET_EVENTS: '/events',
// GET_ITEMS: '/items?eventId=:event_id',
@@ -23,6 +23,9 @@ const endpoints = {
PLACE_BID: '/bids/:item_id',
PURCHASE_ITEM: '/sales',
+ // Login
+ LOGIN: '/auth',
+
// User/Profile
USER_SIGNUP: '/signup',
USER_PROFILE: '/users/:user_id',
@@ -42,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/items.js b/app/api/items.js
index 79a1580..f1ece26 100644
--- a/app/api/items.js
+++ b/app/api/items.js
@@ -1,4 +1,4 @@
-import { getEndpointUrl, requestGet } from './index.js';
+import { API_ENDPOINTS, requestGet } from './index.js';
export const fetchItems = (eventId, auth) => {
const path = String(API_ENDPOINTS.GET_ITEMS).replace(/:event_id$/, eventId);
diff --git a/app/api/profile.js b/app/api/profile.js
index e69de29..4c92f81 100644
--- a/app/api/profile.js
+++ b/app/api/profile.js
@@ -0,0 +1,18 @@
+import { API_ENDPOINTS, requestGet } from './index.js';
+
+export const getEmailAvailability = (email) => {
+};
+
+export const getNomAvailaibility = (nomDeBid) => {
+};
+
+export const loginUser = (username, password) => {
+ const path = String(API_ENDPOINTS.LOGIN);
+ return requestPost({
+ path: API_ENDPOINTS.LOGIN,
+ body: { username, password },
+ });
+};
+
+export const registerNewUser = (user) => {
+};
diff --git a/app/components/AppHeader/AppHeader.js b/app/components/AppHeader/AppHeader.js
index 122125a..3c58171 100644
--- a/app/components/AppHeader/AppHeader.js
+++ b/app/components/AppHeader/AppHeader.js
@@ -3,20 +3,22 @@ import PropTypes from 'prop-types';
import { Header } from 'react-native-elements';
-import HeaderTitle from './HeaderTitle.container.js';
+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 function AppHeader({ navigation }) (
- }
- centerComponent={}
- rightComponent={}
- />
-)
+export default function AppHeader({ navigation }) {
+ return (
+ }
+ centerComponent={}
+ rightComponent={}
+ />
+ );
+}
AppHeader.propTypes = {
navigation: PropTypes.func.isRequired,
diff --git a/app/components/AppHeader/HeaderContentLeft.container.js b/app/components/AppHeader/HeaderContentLeft.container.js
index e3ffc6d..a9b0d62 100644
--- a/app/components/AppHeader/HeaderContentLeft.container.js
+++ b/app/components/AppHeader/HeaderContentLeft.container.js
@@ -1,6 +1,6 @@
import { connect } from 'react-redux';
-import { hasMultipleEvents } from '../selectors/events.js';
+import { hasMultipleEvents } from '../../selectors/events.js';
import HeaderContentLeft from './HeaderContentLeft.js';
diff --git a/app/components/AppHeader/HeaderContentRight.container.js b/app/components/AppHeader/HeaderContentRight.container.js
index 5080ead..b4ad083 100644
--- a/app/components/AppHeader/HeaderContentRight.container.js
+++ b/app/components/AppHeader/HeaderContentRight.container.js
@@ -1,6 +1,6 @@
import { connect } from 'react-redux';
-import { getProfileAvatarUrl } from '../selectors/profile.js';
+import { getProfileAvatarUrl } from '../../selectors/profile.js';
import HeaderContentRight from './HeaderContentRight.js';
diff --git a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js
index e90feb6..77bfcd8 100644
--- a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js
+++ b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.container.js
@@ -1,6 +1,6 @@
import { connect } from 'react-redux';
-import { getActiveEvent, getDefaultEvent } from '../selectors/events.js';
+import { getActiveEvent, getDefaultEvent } from '../../../../selectors/events.js';
import EventTitle from './EventTitle.js';
diff --git a/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.styles.js b/app/components/AppHeader/HeaderTitle/EventTitle/EventTitle.styles.js
index befc216..1140069 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 const styles = StyleSheet.create({
+export const styles = StyleSheet.create({
eventInfo: {
flexDirection: 'row',
},
@@ -12,4 +12,3 @@ export default const styles = StyleSheet.create({
flex: 1,
},
});
-
diff --git a/app/components/AppHeader/HeaderTitle/HeaderTitle.container.js b/app/components/AppHeader/HeaderTitle/HeaderTitle.container.js
index a59812a..1c3584a 100644
--- a/app/components/AppHeader/HeaderTitle/HeaderTitle.container.js
+++ b/app/components/AppHeader/HeaderTitle/HeaderTitle.container.js
@@ -1,7 +1,7 @@
import { connect } from 'react-redux';
-import { hasActiveEvent } from '../selectors/activeEvent.js';
-import { hasMultipleEvents } from '../selectors/events.js';
+import { hasActiveEvent } from '../../../selectors/activeEvent.js';
+import { hasMultipleEvents } from '../../../selectors/events.js';
import HeaderTitle from './HeaderTitle.js';
diff --git a/app/components/AppHeader/HeaderTitle/HeaderTitle.js b/app/components/AppHeader/HeaderTitle/HeaderTitle.js
index 6833937..4a583e0 100644
--- a/app/components/AppHeader/HeaderTitle/HeaderTitle.js
+++ b/app/components/AppHeader/HeaderTitle/HeaderTitle.js
@@ -9,7 +9,7 @@ import {
import EventTitle from './EventTitle/EventTitle.container.js';
-import styles from './TitleBar.styles.js';
+import styles from './HeaderTitle.styles.js';
export default function HeaderTitle({
activeRoute,
diff --git a/app/components/AppHeader/HeaderTitle/HeaderTitle.styles.js b/app/components/AppHeader/HeaderTitle/HeaderTitle.styles.js
index d070666..e0207bc 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 const styles = StyleSheet.create({
+export const styles = StyleSheet.create({
filterBar: {
backgroundColor: '#0F0',
flexDirection: 'row',
diff --git a/app/components/AppHeader/IconButtons/BackIcon.js b/app/components/AppHeader/IconButtons/BackIcon.js
index 6f5642a..dfa08e8 100644
--- a/app/components/AppHeader/IconButtons/BackIcon.js
+++ b/app/components/AppHeader/IconButtons/BackIcon.js
@@ -4,11 +4,13 @@ import PropTypes from 'prop-types';
import { TouchableOpacity } from 'react-native';
import { Icon } from 'react-native-elements';
-export default function BackIcon({ action }) (
-
- ;
-
-)
+export default function BackIcon({ action }) {
+ return (
+
+ ;
+
+ );
+}
BackIcon.propTypes = {
action: PropTypes.func.isRequired,
diff --git a/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js b/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js
index 304da74..b0cb7a2 100644
--- a/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js
+++ b/app/components/AppHeader/UserProfileButton/UserProfileButton.container.js
@@ -1,11 +1,11 @@
import { connect } from 'react-redux';
-import { getProfileAvatarUrl } from '../selectors/profile.js';
+import { getProfileAvatarUrl } from '../../../selectors/profile.js';
-import HeaderContentRight from './HeaderContentRight.js';
+import UserProfileButton from './UserProfileButton.js';
const matchStateToProps = (state) => ({
avatarUrl: getProfileAvatarUrl(state),
});
-export default connect(matchStateToProps, null)(HeaderContentRight);
+export default connect(matchStateToProps, null)(UserProfileButton);
diff --git a/app/components/AppHeader/UserProfileButton/UserProfileButton.js b/app/components/AppHeader/UserProfileButton/UserProfileButton.js
index 6fccdb1..61307ed 100644
--- a/app/components/AppHeader/UserProfileButton/UserProfileButton.js
+++ b/app/components/AppHeader/UserProfileButton/UserProfileButton.js
@@ -20,16 +20,16 @@ export default function UserProfileButton({ avatarUrl, navigation }) {
) : (
- ;
+
)}
);
}
-HeaderContentRight.propTypes = {
+UserProfileButton.propTypes = {
avatarUrl: PropTypes.string,
};
-HeaderContentRight.propTypes = {
+UserProfileButton.propTypes = {
avatarUrl: null,
};
diff --git a/app/components/FacebookLogin/FacebookLogin.container.js b/app/components/Login/FacebookLogin.container.js
similarity index 94%
rename from app/components/FacebookLogin/FacebookLogin.container.js
rename to app/components/Login/FacebookLogin.container.js
index 4004851..bd46217 100644
--- a/app/components/FacebookLogin/FacebookLogin.container.js
+++ b/app/components/Login/FacebookLogin.container.js
@@ -5,7 +5,7 @@ import {
logout,
registrationServiceError,
userCanceledRegistration,
-} from '../actions/profile.js';
+} from '../../actions/profile.js';
import FacebookLogin from './FacebookLogin.js';
diff --git a/app/components/FacebookLogin/FacebookLogin.js b/app/components/Login/FacebookLogin.js
similarity index 100%
rename from app/components/FacebookLogin/FacebookLogin.js
rename to app/components/Login/FacebookLogin.js
diff --git a/app/components/Login/LocalLogin.container.js b/app/components/Login/LocalLogin.container.js
new file mode 100644
index 0000000..cdeb6a7
--- /dev/null
+++ b/app/components/Login/LocalLogin.container.js
@@ -0,0 +1,11 @@
+import { connect } from 'react-redux';
+
+import { login } from '../../actions/profile.js';
+
+import LocalLogin from './LocalLogin.js';
+
+const mapDispatchToProps = (dispatch) => ({
+ doLoginAction: (username, password) => dispatch(login(username, password)),
+});
+
+export default connect(null, mapDispatchToProps)(LocalLogin);
diff --git a/app/components/Login/LocalLogin.js b/app/components/Login/LocalLogin.js
new file mode 100644
index 0000000..0f0d621
--- /dev/null
+++ b/app/components/Login/LocalLogin.js
@@ -0,0 +1,55 @@
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+
+import { Button, TextInput, View } from 'react-native';
+
+export default function LocalLogin({ doLoginAction }) {
+
+ const [ enabled, setEnableSubmit ] = useState(false);
+ const [ password, setPassword ] = useState(null);
+ const [ username, setUsername ] = useState(null);
+
+ const _handleLoginSubmit = () => {
+ doLoginAction(username, password);
+ };
+
+ const _updateState = (field, value) => {
+ if (field === 'username') {
+ setUsername(value);
+ }
+
+ if (field === 'password') {
+ setPassword(value);
+ }
+
+ if (!!username && !!password) {
+ setEnableSubmit(true);
+ }
+ };
+
+ return (
+
+ _updateState('username', text)}
+ value={username}
+ />
+ _updateState('password', text)}
+ value={password}
+ />
+
+
+ );
+}
+
+LocalLogin.propTypes = {
+ doLoginAction: PropTypes.func.isRequired,
+};
diff --git a/app/constants/actionTypes.js b/app/constants/actionTypes.js
index 994eb39..b744aee 100644
--- a/app/constants/actionTypes.js
+++ b/app/constants/actionTypes.js
@@ -16,6 +16,12 @@ export const BID_FAILURE = 'BID_FAILURE';
export const BID_SUCCESS = 'BID_SUCCESS';
export const DO_LOGIN = 'DO_LOGIN';
+export const LOGIN_FAILURE = 'LOGIN_FAILURE';
+export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
+
+export const SET_AUTH = 'SET_AUTH';
+export const UNSET_AUTH = 'UNSET_AUTH';
+
export const DO_LOGOUT = 'DO_LOOUT';
export const DO_SIGNUP = 'DO_SIGNUP';
@@ -40,6 +46,7 @@ export const LINK_GOOGLE_FAILURE = 'LINK_GOOGLE_FAILURE';
export const LINK_GOOGLE_SUCCESS = 'LINK_GOOGLE_SUCCESS';
export const SET_PROFILE = 'SET_PROFILE';
+export const UNSET_PROFILE = 'UNSET_PROFILE';
export const UPDATE_PROFILE = 'UPDATE_PROFILE';
export const SET_NOM_DE_BID = 'SET_NOM_DE_BID';
diff --git a/app/domain/Post.js b/app/domain/Post.js
index 6aa0b26..2fb0159 100644
--- a/app/domain/Post.js
+++ b/app/domain/Post.js
@@ -13,7 +13,7 @@ export default class Post extends Record({
Post.fromJS = (data = {}) => {
- return new TicketClass({
+ return new Post({
id: data._id,
...data,
});
diff --git a/app/reducers/auctionFilter.js b/app/reducers/auctionFilter.js
index cfb90d4..048a4fb 100644
--- a/app/reducers/auctionFilter.js
+++ b/app/reducers/auctionFilter.js
@@ -1,7 +1,7 @@
-import { SET_ITEM_FILTER } from '../constants/actionTypes.js';
+import { SET_AUCTION_FILTER } from '../constants/actionTypes.js';
import { ITEM_FILTERS } from '../constants/constants.js';
-export const itemFilter = (state = ITEM_FILTERS.ALL, action) => {
+export const auctionFilter = (state = ITEM_FILTERS.ALL, action) => {
switch (action.type) {
case SET_AUCTION_FILTER:
return action.payload;
diff --git a/app/reducers/auth.js b/app/reducers/auth.js
new file mode 100644
index 0000000..9aa8be2
--- /dev/null
+++ b/app/reducers/auth.js
@@ -0,0 +1,14 @@
+import { LOGIN_SUCCESS, SET_AUTH, UNSET_AUTH } from '../constants/actionTypes.js';
+
+export const auth = (state = null, action) => {
+ switch (action.type) {
+ case LOGIN_SUCCESS:
+ return action.payload.token;
+ case SET_AUTH:
+ return action.payload;
+ case UNSET_AUTH:
+ return null;
+ default:
+ return state;
+ }
+};
diff --git a/app/reducers/events.js b/app/reducers/events.js
index 7d9571f..c199510 100644
--- a/app/reducers/events.js
+++ b/app/reducers/events.js
@@ -5,12 +5,11 @@ import { EVENTS_LOADED, GET_EVENTS } from '../constants/actionTypes.js';
export const events = (state = new Map(), action) => {
switch (action.type) {
case EVENTS_LOADED:
- return state.merge(
- action.payload.toMap().mapEntries((entry) => {
+ const mapped = action.payload.toMap().mapEntries((entry) => {
const [, event] = entry;
return [`${event.id}`, event];
- }),
- );
+ });
+ return state.merge(mapped);
case GET_EVENTS:
default:
return state;
diff --git a/app/reducers/index.js b/app/reducers/index.js
index 58e24ee..9090d9d 100644
--- a/app/reducers/index.js
+++ b/app/reducers/index.js
@@ -5,9 +5,11 @@ import { activeItem } from './activeItem.js';
import { auctionFilter } from './auctionFilter.js';
import { auctions } from './auctions.js';
import { auctionView } from './auctionView.js';
+import { auth } from './auth.js';
import { blockUI } from './blockUI.js';
import { events } from './events.js';
import { items } from './items.js';
+import { profile } from './profile.js';
const rootReducer = combineReducers({
activeEvent,
@@ -15,9 +17,11 @@ const rootReducer = combineReducers({
auctionFilter,
auctions,
auctionView,
+ auth,
blockUI,
events,
items,
+ profile,
});
export default rootReducer;
diff --git a/app/reducers/profile.js b/app/reducers/profile.js
index d4f3b7f..06338fd 100644
--- a/app/reducers/profile.js
+++ b/app/reducers/profile.js
@@ -1,14 +1,20 @@
import { Map } from 'immutable';
import {
+ LOGIN_SUCCESS,
SET_PROFILE,
+ UNSET_PROFILE,
UPDATE_PROFILE,
} from '../constants/actionTypes.js';
export const profile = (state = new Map(), action) => {
switch (action.type) {
+ case LOGIN_SUCCESS:
+ return action.payload.user;
case SET_PROFILE:
return action.payload;
+ case UNSET_PROFILE:
+ return new Map();
case UPDATE_PROFILE:
return action.payload;
default:
diff --git a/app/router.js b/app/router.js
index 9869ed0..55b68c9 100644
--- a/app/router.js
+++ b/app/router.js
@@ -3,9 +3,9 @@ import { Dimensions, Platform } from 'react-native';
import { createBottomTabNavigator, createStackNavigator } from 'react-navigation';
import { Icon } from 'react-native-elements';
-import AppHeader from './Components/AppHeader/AppHeader.js';
+import AppHeader from './components/AppHeader/AppHeader.js';
-import Auction from './screen/Auction.container.js';
+import Auction from './screens/Auction.container.js';
import Checkout from './screens/Checkout.js';
import Event from './screens/Event.container.js';
import Events from './screens/Events.container.js';
@@ -50,43 +50,43 @@ export const Tabs = createBottomTabNavigator({
export const SignInOrRegisterStack = createStackNavigator({
SignInOrRegister: {
screen: SignInOrRegister,
- navigationOptions: ({ navigation }) => {
+ navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
- gesturesEnabled: false
- },
+ gesturesEnabled: false,
+ }),
},
Register: {
screen: Register,
- navigationOptions: ({ navigation }) => {
+ navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
- gesturesEnabled: false
- },
+ gesturesEnabled: false,
+ }),
},
});
export const AuctionStack = createStackNavigator({
Auction: {
screen: Auction,
- navigationOptions: ({navigation}) => ({
+ navigationOptions: ({ navigation }) => ({
header: ,
}),
},
Item: {
screen: Item,
- navigationOptions: ({navigation}) => ({
+ navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
- gesturesEnabled: false
+ gesturesEnabled: false,
}),
},
ImageDetail: {
screen: ImageDetail,
- navigationOptions: ({navigation}) => ({
+ navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
- gesturesEnabled: false
+ gesturesEnabled: false,
}),
},
});
@@ -94,32 +94,32 @@ export const AuctionStack = createStackNavigator({
export const BazaarStack = createStackNavigator({
Bazaar: {
screen: Marketplace,
- navigationOptions: ({navigation}) => ({
+ navigationOptions: ({ navigation }) => ({
header: ,
}),
},
Item: {
screen: Item,
- navigationOptions: ({navigation}) => ({
+ navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
- gesturesEnabled: false
+ gesturesEnabled: false,
}),
},
ImageDetail: {
screen: ImageDetail,
- navigationOptions: ({navigation}) => ({
+ navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
- gesturesEnabled: false
+ gesturesEnabled: false,
}),
},
Checkout: {
screen: Checkout,
- navigationOptions: ({navigation}) => ({
+ navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
- gesturesEnabled: false
+ gesturesEnabled: false,
}),
},
});
@@ -130,7 +130,7 @@ export const EventsStack = createStackNavigator({
navigationOptions: ({ navigation }) => ({
header: ,
tabBarVisible: false,
- gesturesEnabled: false
+ gesturesEnabled: false,
}),
}
});
@@ -141,30 +141,30 @@ export const createRootNavigator = () => {
AuctionStack: {
screen: AuctionStack,
navigationOptions: {
- gesturesEnabled: false
+ gesturesEnabled: false,
}
},
BazaarStack: {
screen: BazaarStack,
navigationOptions: {
- gesturesEnabled: false
+ gesturesEnabled: false,
}
},
EventsStack: {
screen: EventsStack,
navigationOptions: {
- gesturesEnabled: false
+ gesturesEnabled: false,
}
},
Tabs: {
screen: Tabs,
navigationOptions: {
- gesturesEnabled: false
+ gesturesEnabled: false,
}
}
},
{
- mode: "modal"
+ mode: "modal",
}
);
};
diff --git a/app/screens/Event.container.js b/app/screens/Event.container.js
index 64a3a44..34132d3 100644
--- a/app/screens/Event.container.js
+++ b/app/screens/Event.container.js
@@ -1,34 +1,34 @@
import { connect } from 'react-redux';
-import { fetchEvent } from '../actions/events.js';
-import { getEventById } from '../selectors/events.js';
+import { fetchEvents } from '../actions/events.js';
+import EventRecord from '../domain/Event.js';
+import { getActiveEvent, getDefaultEvent } from '../selectors/events.js';
import Event from './Event.js';
const matchStateToProps = (state) => {
- const eventId = state.get('activeEvent');
- const event = getEventById(state, eventId);
+ const event = getActiveEvent(state) || getDefaultEvent(state) || new EventRecord();
return {
description: event.get('description'),
endTime: event.get('endTime'),
id: event.get('id'),
- images: event.get('images'),
+ images: event.get('images').toArray(),
isTicketed: event.get('isTicketed'),
- posts: event.get('posts'),
+ posts: event.get('posts').toArray(),
requireLoginToSeeAuction: event.get('requireLoginToSeeAuction'),
showFrom: event.get('showFrom'),
showUntil: event.get('showUntil'),
startTime: event.get('startTime'),
tagline: event.get('tagline'),
- ticketClasses: event.get('ticketClasses'),
+ ticketClasses: event.get('ticketClasses').toArray(),
title: event.get('title'),
url: event.get('url'),
};
};
const mapDispatchToProps = (dispatch) => ({
- fetchEvent: () => dispatch(fetchEvent(dispatch)),
+ fetchEvents: () => dispatch(fetchEvents()),
});
export default connect(matchStateToProps, mapDispatchToProps)(Event);
diff --git a/app/screens/Event.js b/app/screens/Event.js
index b938736..79c6acc 100644
--- a/app/screens/Event.js
+++ b/app/screens/Event.js
@@ -1,4 +1,5 @@
import React, { Component } from 'react';
+import PropTypes from 'prop-types';
import { Text, View } from 'react-native';
import styles from './Event.styles.js';
@@ -6,10 +7,10 @@ import styles from './Event.styles.js';
export default class Event extends Component {
static get propTypes() {
return {
- description: PropTypes.string.isRequired,
- endTime: PropTypes.string.isRequired,
- fetchEvent: PropTypes.func.isRequired,
- id: PropTypes.string.isRequired,
+ description: PropTypes.string,
+ endTime: PropTypes.string,
+ fetchEvents: PropTypes.func,
+ id: PropTypes.string,
images: PropTypes.arrayOf(
PropTypes.shape({
url: PropTypes.string,
@@ -18,27 +19,27 @@ export default class Event extends Component {
isTicketed: PropTypes.bool,
posts: PropTypes.arrayOf(
PropTypes.shape({
- author: PropTypes.string.isRequired,
- content: PropTypes.string.isRequired,
- id: PropTypes.string.isRequired,
+ author: PropTypes.string,
+ content: PropTypes.string,
+ id: PropTypes.string,
isPublic: PropTypes.bool,
scheduledPost: PropTypes.bool,
sendNotification: PropTypes.bool,
- timestamp: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
+ timestamp: PropTypes.string,
+ title: PropTypes.string,
}),
),
- requireLoginToSeeAuction: PropTypes.bool.isRequired,
- showFrom: PropTypes.string.isRequired,
- showUntil: PropTypes.string.isRequired,
- startTime: PropTypes.string.isRequired,
+ requireLoginToSeeAuction: PropTypes.bool,
+ showFrom: PropTypes.string,
+ showUntil: PropTypes.string,
+ startTime: PropTypes.string,
tagline: PropTypes.string,
ticketClasses: PropTypes.arrayOf(
PropTypes.shape({
}),
- )
- title: PropTypes.string.isRequired,
+ ),
+ title: PropTypes.string,
url: PropTypes.string,
};
}
@@ -59,6 +60,10 @@ export default class Event extends Component {
super(props);
}
+ componentDidMount() {
+ this.props.fetchEvents();
+ }
+
render() {
const {
description,
diff --git a/app/screens/Event.styles.js b/app/screens/Event.styles.js
index d0fc2fc..bb1db67 100644
--- a/app/screens/Event.styles.js
+++ b/app/screens/Event.styles.js
@@ -1,6 +1,6 @@
import { StyleSheet } from 'react-native';
-export default const styles = StyleSheet.create({
+const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
@@ -13,3 +13,5 @@ export default const styles = StyleSheet.create({
margin: 10,
}
});
+
+export default styles;
diff --git a/app/screens/Marketplace.js b/app/screens/Marketplace.js
index 3ebbf8c..0140a6b 100644
--- a/app/screens/Marketplace.js
+++ b/app/screens/Marketplace.js
@@ -1,30 +1,38 @@
+import { List } from 'immutable';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
FlatList,
- StyleSheet,
Text,
View,
} from 'react-native';
-import { SORT_MODES, VIEW_MODES } from '../constants/constants.js';
+import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js';
-import GridItem from '../components/Item/Grid.js';
-import ListItem from '../components/Item/List.js';
+import FilterBar from '../components/Auction/FilterBar.js';
+import AuctionListItem from '../containers/Auction/AuctionListItem.js';
+
+//import styles from './Marketplace.styles.js';
export default class Marketplace extends Component {
static get propTypes() {
return {
changeFilter: PropTypes.func,
- items: PropTypes.array.isRequired,
+ changeViewMode: PropTypes.func.isRequired,
+ fetchItems: PropTypes.func.isRequired,
+ fetchStatus: PropTypes.func.isRequired,
+ items: PropTypes.oneOfType([
+ PropTypes.array,
+ PropTypes.instanceOf(List),
+ ]),
};
}
static get defaultProps() {
return {
changeFilter: () => { console.log('Change Filter Default Prop', arguments); },
- header: null,
+ items: [],
};
}
@@ -36,57 +44,42 @@ export default class Marketplace extends Component {
this.state = {
sort: SORT_MODES.TITLE_ASC,
- view: VIEW_MODES.LIST,
+ view: AUCTION_VIEW_MODES.ALL,
};
}
+ componentDidMount() {
+ this.props.fetchStatus();
+ this.props.fetchItems();
+ }
+
changeFilter(filter) {
- this.props.changeFilter('market', filter);
+ this.props.changeFilter('auction', filter);
}
- changeViewMode(mode) {
- this.setState({ view: mode });
- }
+ _keyExtractor = (item, index) => `${item._id}_${index}`;
- _keyExtractor = (item, index) => item.id;
-
- _renderItem = (view) => ({ item }) => {
- if (view === VIEW_MODES.GRID) {
- return ;
- }
-
- return ;
- }
+ _renderAuctionListItem = ({ item }) => ;
render() {
- const { items, view } = this.state;
+ const { items } = this.props;
+ const { sort, view } = this.state;
return (
-
+ {items.size > 0 && (
+
+ )}
);
}
}
-
-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/Register.styles.js b/app/screens/Register.styles.js
new file mode 100644
index 0000000..bdf6cc3
--- /dev/null
+++ b/app/screens/Register.styles.js
@@ -0,0 +1,16 @@
+import { StyleSheet } from 'react-native';
+
+export const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ flexDirection: 'column',
+ },
+ title: {
+ },
+ localLogin: {
+ },
+ services: {
+ },
+ register: {
+ },
+});
diff --git a/app/screens/SignInOrRegister.js b/app/screens/SignInOrRegister.js
index 8831bc2..7938307 100644
--- a/app/screens/SignInOrRegister.js
+++ b/app/screens/SignInOrRegister.js
@@ -1,7 +1,9 @@
import React, { Component } from 'react';
import { Text, View } from 'react-native';
+import { Button } from 'react-native-elements';
-import FacebookLogin from '../components/FacebookLogin/FacebookLogin.container.js';
+import FacebookLogin from '../components/Login/FacebookLogin.container.js';
+import LocalLogin from '../components/Login/LocalLogin.container.js';
import styles from './SignInOrRegister.styles.js';
@@ -28,7 +30,7 @@ export default class SignInOrRegister extends Component {
-
+
);
diff --git a/app/screens/SignInOrRegister.styles.js b/app/screens/SignInOrRegister.styles.js
index d0fc2fc..95d78fc 100644
--- a/app/screens/SignInOrRegister.styles.js
+++ b/app/screens/SignInOrRegister.styles.js
@@ -1,6 +1,6 @@
import { StyleSheet } from 'react-native';
-export default const styles = StyleSheet.create({
+export const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
diff --git a/app/selectors/activeEvent.js b/app/selectors/activeEvent.js
index ac8f7d5..817c05e 100644
--- a/app/selectors/activeEvent.js
+++ b/app/selectors/activeEvent.js
@@ -8,6 +8,6 @@ export const getActiveEventId = createSelector(
);
export const hasActiveEvent = createSelector(
- [getState],
- (state) => !!state.get('activeEvent'),
+ [getActiveEventId],
+ (eventId) => !!eventId,
);
diff --git a/app/selectors/auctions.js b/app/selectors/auctions.js
index 81d7ea7..6be6d28 100644
--- a/app/selectors/auctions.js
+++ b/app/selectors/auctions.js
@@ -19,15 +19,15 @@ export const getAuctionStatuses = createSelector(
export const getItemsIdsWithNoBids = createSelector(
[getAuctionStatuses],
- (auctions) => auctions.filter(auction => auction.bidCount === 0);
+ (auctions) => auctions.filter(auction => auction.bidCount === 0),
);
export const getMyBidItemIds = createSelector(
[getAuctionStatuses],
- (auctions) => auctions.filter(auction => auction.isBidding);
+ (auctions) => auctions.filter(auction => auction.isBidding),
);
export const getMyWinningItemIds = createSelector(
[getAuctionStatuses],
- (auctions) => auctions.filter(auction => auction.isWinning);
+ (auctions) => auctions.filter(auction => auction.isWinning),
);
diff --git a/app/selectors/auth.js b/app/selectors/auth.js
new file mode 100644
index 0000000..be5015d
--- /dev/null
+++ b/app/selectors/auth.js
@@ -0,0 +1,8 @@
+import { createSelector } from 'reselect';
+
+const getState = (state) => state;
+
+export const getAuthToken = createSelector(
+ [getState],
+ (state) => state.get('auth'),
+);
diff --git a/app/selectors/events.js b/app/selectors/events.js
index b6a383c..7e10be5 100644
--- a/app/selectors/events.js
+++ b/app/selectors/events.js
@@ -14,7 +14,7 @@ export const getEvents = createSelector(
export const getActiveEvent = createSelector(
[getActiveEventId, getEvents],
- (eventId, eventsAsMap) => eventId ? eventsAsMap.get(eventId) : false,
+ (eventId, eventsAsMap) => eventId ? eventsAsMap.get(eventId) : null,
);
export const getDefaultEvent = createSelector(