- Cleanup
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {Fragment} from 'react';
|
import React from 'react';
|
||||||
import { createAppContainer } from 'react-navigation';
|
import { createAppContainer } from 'react-navigation';
|
||||||
|
|
||||||
import { Tabs } from './router.js';
|
import { Tabs } from './router.js';
|
||||||
|
|||||||
@@ -1,33 +1,36 @@
|
|||||||
import { List } from 'immutable';
|
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 {
|
import {
|
||||||
|
EVENTS_LOAD_FAILED,
|
||||||
EVENTS_LOADED,
|
EVENTS_LOADED,
|
||||||
GET_EVENTS,
|
GET_EVENTS,
|
||||||
} from '../constants/actionTypes.js';
|
} from '../constants/actionTypes.js';
|
||||||
|
|
||||||
import { blockUI, unblockUI } from './index.js';
|
|
||||||
import { API_ENDPOINTS } from '../constants/constants.js';
|
|
||||||
|
|
||||||
import Event from '../domain/Event.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 eventsLoadError = (payload) => ({ type: EVENTS_LOAD_FAILED, payload });
|
||||||
const payload = List(events).map((i) => Event.fromJS(i));
|
|
||||||
dispatch({ type: EVENTS_LOADED, payload });
|
const eventsFetchSuccess = (items) => (dispatch) => {
|
||||||
|
const payload = List(items).map((i) => Event.fromJS(i));
|
||||||
|
|
||||||
|
dispatch(eventsLoaded(payload));
|
||||||
dispatch(unblockUI);
|
dispatch(unblockUI);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setActiveEvent = (eventId) => ({
|
const eventsFetchFailure = (error) => (dispatch) => {
|
||||||
type: SET_ACTIVE_EVENT,
|
console.error('[actions::events::eventsFetchFailure]', error);
|
||||||
payload: eventId,
|
dispatch(eventsLoadError(error));
|
||||||
});
|
dispatch(unblockUI);
|
||||||
|
};
|
||||||
export const fetchEvents = () => (dispatch) => {
|
|
||||||
dispatch(blockUI());
|
export const fetchEvents = () => (dispatch, getState) => {
|
||||||
fetch(getEndpointUr(API_ENDPOINTS.GET_EVENTS))
|
const authToken = getAuthToken(getState());
|
||||||
.then(response => response.json())
|
|
||||||
.then(payload => eventsLoadSuccess(payload, dispatch))
|
fetchEventsApi(authToken)
|
||||||
.catch(err => console.error('[actions::getEvents]', err));
|
.then(payload => dispatch(eventsFetchSuccess(payload)))
|
||||||
|
.catch(err => dispatch(eventsFetchFailure(err)));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { List } from 'immutable';
|
import { List } from 'immutable';
|
||||||
|
|
||||||
import { fetchItems } from '../api/items.js';
|
import { fetchItems as fetchItemsApi } from '../api/items.js';
|
||||||
import {
|
import {
|
||||||
GET_ITEMS,
|
GET_ITEMS,
|
||||||
ITEMS_LOADED,
|
ITEMS_LOADED,
|
||||||
} from '../constants/actionTypes.js';
|
} from '../constants/actionTypes.js';
|
||||||
import { getActiveEventId } from '../selectors/activeEvent.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';
|
import { blockUI, unblockUI } from './index.js';
|
||||||
|
|
||||||
@@ -24,16 +24,16 @@ const itemsFetchSuccess = (items) => (dispatch) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const itemsFetchFailure = (error) => (dispatch) => {
|
const itemsFetchFailure = (error) => (dispatch) => {
|
||||||
console.error('[actions::getItems]', error));
|
console.error('[actions::items::itemsFetchFailure]', error);
|
||||||
dispatch(itemsLoadFailure(error));
|
dispatch(itemsLoadFailure(error));
|
||||||
dispatch(unblockUI);
|
dispatch(unblockUI);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchItems = () => (dispatch, getState) => {
|
export const fetchItems = () => (dispatch, getState) => {
|
||||||
const eventId = getActiveEventId(getState());
|
const eventId = getActiveEventId(getState());
|
||||||
const authToken = getLoginToken(getState());
|
const authToken = getAuthToken(getState());
|
||||||
|
|
||||||
fetchItems(activeEvent, authToken)
|
fetchItemsApi(activeEvent, authToken)
|
||||||
.then(payload => dispatch(itemsFetchSuccess(payload)))
|
.then(payload => dispatch(itemsFetchSuccess(payload)))
|
||||||
.catch(err => dispatch(itemsFetchFailure(err));
|
.catch(err => dispatch(itemsFetchFailure(err)));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,13 +3,18 @@ import { blockUI, unblockUI } from './index.js';
|
|||||||
import {
|
import {
|
||||||
getEmailAvailability,
|
getEmailAvailability,
|
||||||
getNomAvailaibility,
|
getNomAvailaibility,
|
||||||
|
loginUser,
|
||||||
registerNewUser,
|
registerNewUser,
|
||||||
} from '../api/profile.js';
|
} from '../api/profile.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DO_LOGOUT,
|
DO_LOGOUT,
|
||||||
|
LOGIN_FAILURE,
|
||||||
|
LOGIN_SUCCESS,
|
||||||
PROFILE_EMAIL_AVAILABLE,
|
PROFILE_EMAIL_AVAILABLE,
|
||||||
PROFILE_NOM_AVAILABLE,
|
PROFILE_NOM_AVAILABLE,
|
||||||
|
UNSET_AUTH,
|
||||||
|
UNSET_PROFILE,
|
||||||
UPDATE_PROFILE,
|
UPDATE_PROFILE,
|
||||||
} from '../constants/actionTypes.js';
|
} from '../constants/actionTypes.js';
|
||||||
|
|
||||||
@@ -23,6 +28,16 @@ const isValidNom = (payload) => ({
|
|||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const loginFailure = (payload) => ({
|
||||||
|
type: LOGIN_FAILURE,
|
||||||
|
payload,
|
||||||
|
});
|
||||||
|
|
||||||
|
const loginSuccess = (payload) => ({
|
||||||
|
type: LOGIN_SUCCESS,
|
||||||
|
payload,
|
||||||
|
});
|
||||||
|
|
||||||
const logoutUser = () => ({
|
const logoutUser = () => ({
|
||||||
type: DO_LOGOUT,
|
type: DO_LOGOUT,
|
||||||
});
|
});
|
||||||
@@ -37,6 +52,14 @@ const registrationSuccess = (payload) => ({
|
|||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const unsetAuth = () => ({
|
||||||
|
type: UNSET_AUTH,
|
||||||
|
});
|
||||||
|
|
||||||
|
const unsetProfile = () => ({
|
||||||
|
type: UNSET_PROFILE,
|
||||||
|
});
|
||||||
|
|
||||||
const updateProfile = (profile) => ({
|
const updateProfile = (profile) => ({
|
||||||
type: UPDATE_PROFILE,
|
type: UPDATE_PROFILE,
|
||||||
payload: 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
|
// USER REGISTRATION
|
||||||
const handleRegistrationSuccess = (user) => (dispatch) => {
|
const handleRegistrationSuccess = (user) => (dispatch) => {
|
||||||
|
|||||||
7
app/api/events.js
Normal file
7
app/api/events.js
Normal file
@@ -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);
|
||||||
|
};
|
||||||
@@ -40,7 +40,7 @@ const parseQueryParamsString = (queryParams) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const parseQueryParamsObject = (queryParams) => {
|
const parseQueryParamsObject = (queryParams) => {
|
||||||
if (typeof queryParams !== 'object' && Array.isArray(queryParams)) {
|
if (queryParams === null || typeof queryParams !== 'object' || Array.isArray(queryParams)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { API_URL } from '../constants/constants.js';
|
|||||||
|
|
||||||
const DefaultRequestOptions = {};
|
const DefaultRequestOptions = {};
|
||||||
|
|
||||||
const endpoints = {
|
export const API_ENDPOINTS = {
|
||||||
// Events and Items
|
// Events and Items
|
||||||
GET_EVENTS: '/events',
|
GET_EVENTS: '/events',
|
||||||
// GET_ITEMS: '/items?eventId=:event_id',
|
// GET_ITEMS: '/items?eventId=:event_id',
|
||||||
@@ -23,6 +23,9 @@ const endpoints = {
|
|||||||
PLACE_BID: '/bids/:item_id',
|
PLACE_BID: '/bids/:item_id',
|
||||||
PURCHASE_ITEM: '/sales',
|
PURCHASE_ITEM: '/sales',
|
||||||
|
|
||||||
|
// Login
|
||||||
|
LOGIN: '/auth',
|
||||||
|
|
||||||
// User/Profile
|
// User/Profile
|
||||||
USER_SIGNUP: '/signup',
|
USER_SIGNUP: '/signup',
|
||||||
USER_PROFILE: '/users/:user_id',
|
USER_PROFILE: '/users/:user_id',
|
||||||
@@ -42,11 +45,11 @@ const cacheBuster = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getEndpointUrl = (endpoint) => {
|
export const getEndpointUrl = (endpoint) => {
|
||||||
if (!endpoints[endpoint]) {
|
if (!API_ENDPOINTS[endpoint]) {
|
||||||
throw new Error('Invalid API endpoint specified');
|
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 = {}) => {
|
export const requestGet = (path, queryParams = [], requestOptions = {}) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getEndpointUrl, requestGet } from './index.js';
|
import { API_ENDPOINTS, requestGet } from './index.js';
|
||||||
|
|
||||||
export const fetchItems = (eventId, auth) => {
|
export const fetchItems = (eventId, auth) => {
|
||||||
const path = String(API_ENDPOINTS.GET_ITEMS).replace(/:event_id$/, eventId);
|
const path = String(API_ENDPOINTS.GET_ITEMS).replace(/:event_id$/, eventId);
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
};
|
||||||
|
|||||||
@@ -3,20 +3,22 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
import { Header } from 'react-native-elements';
|
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 HeaderContentLeft from './HeaderContentLeft.container.js';
|
||||||
import HeaderContentRight from './HeaderContentRight.container.js';
|
import HeaderContentRight from './HeaderContentRight.container.js';
|
||||||
|
|
||||||
import styles from './AppHeader.styles.js';
|
import styles from './AppHeader.styles.js';
|
||||||
|
|
||||||
export default function AppHeader({ navigation }) (
|
export default function AppHeader({ navigation }) {
|
||||||
<Header
|
return (
|
||||||
placement="left"
|
<Header
|
||||||
leftComponent={<HeaderContentRight navigation={navigation} />}
|
placement="left"
|
||||||
centerComponent={<HeaderTitle navigation={navigation} />}
|
leftComponent={<HeaderContentRight navigation={navigation} />}
|
||||||
rightComponent={<HeaderContentLeft navigation={navigation} />}
|
centerComponent={<HeaderTitle navigation={navigation} />}
|
||||||
/>
|
rightComponent={<HeaderContentLeft navigation={navigation} />}
|
||||||
)
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
AppHeader.propTypes = {
|
AppHeader.propTypes = {
|
||||||
navigation: PropTypes.func.isRequired,
|
navigation: PropTypes.func.isRequired,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { hasMultipleEvents } from '../selectors/events.js';
|
import { hasMultipleEvents } from '../../selectors/events.js';
|
||||||
|
|
||||||
import HeaderContentLeft from './HeaderContentLeft.js';
|
import HeaderContentLeft from './HeaderContentLeft.js';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { getProfileAvatarUrl } from '../selectors/profile.js';
|
import { getProfileAvatarUrl } from '../../selectors/profile.js';
|
||||||
|
|
||||||
import HeaderContentRight from './HeaderContentRight.js';
|
import HeaderContentRight from './HeaderContentRight.js';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { getActiveEvent, getDefaultEvent } from '../selectors/events.js';
|
import { getActiveEvent, getDefaultEvent } from '../../../../selectors/events.js';
|
||||||
|
|
||||||
import EventTitle from './EventTitle.js';
|
import EventTitle from './EventTitle.js';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export default const styles = StyleSheet.create({
|
export const styles = StyleSheet.create({
|
||||||
eventInfo: {
|
eventInfo: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
@@ -12,4 +12,3 @@ export default const styles = StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { hasActiveEvent } from '../selectors/activeEvent.js';
|
import { hasActiveEvent } from '../../../selectors/activeEvent.js';
|
||||||
import { hasMultipleEvents } from '../selectors/events.js';
|
import { hasMultipleEvents } from '../../../selectors/events.js';
|
||||||
|
|
||||||
import HeaderTitle from './HeaderTitle.js';
|
import HeaderTitle from './HeaderTitle.js';
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
|
|
||||||
import EventTitle from './EventTitle/EventTitle.container.js';
|
import EventTitle from './EventTitle/EventTitle.container.js';
|
||||||
|
|
||||||
import styles from './TitleBar.styles.js';
|
import styles from './HeaderTitle.styles.js';
|
||||||
|
|
||||||
export default function HeaderTitle({
|
export default function HeaderTitle({
|
||||||
activeRoute,
|
activeRoute,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export default const styles = StyleSheet.create({
|
export const styles = StyleSheet.create({
|
||||||
filterBar: {
|
filterBar: {
|
||||||
backgroundColor: '#0F0',
|
backgroundColor: '#0F0',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import PropTypes from 'prop-types';
|
|||||||
import { TouchableOpacity } from 'react-native';
|
import { TouchableOpacity } from 'react-native';
|
||||||
import { Icon } from 'react-native-elements';
|
import { Icon } from 'react-native-elements';
|
||||||
|
|
||||||
export default function BackIcon({ action }) (
|
export default function BackIcon({ action }) {
|
||||||
<TouchableOpacity onPress={action}>
|
return (
|
||||||
<Icon name="ei-chevron-left" type="evilicons" size={28} />;
|
<TouchableOpacity onPress={action}>
|
||||||
</TouchableOpacity>
|
<Icon name="ei-chevron-left" type="evilicons" size={28} />;
|
||||||
)
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
BackIcon.propTypes = {
|
BackIcon.propTypes = {
|
||||||
action: PropTypes.func.isRequired,
|
action: PropTypes.func.isRequired,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { connect } from 'react-redux';
|
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) => ({
|
const matchStateToProps = (state) => ({
|
||||||
avatarUrl: getProfileAvatarUrl(state),
|
avatarUrl: getProfileAvatarUrl(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, null)(HeaderContentRight);
|
export default connect(matchStateToProps, null)(UserProfileButton);
|
||||||
|
|||||||
@@ -20,16 +20,16 @@ export default function UserProfileButton({ avatarUrl, navigation }) {
|
|||||||
<Image source={{ uri: avatarUrl }} />
|
<Image source={{ uri: avatarUrl }} />
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<Icon name="ei-user" type="evilicons" size={28} />;
|
<Icon name="ei-user" type="evilicons" size={28} />
|
||||||
)}
|
)}
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderContentRight.propTypes = {
|
UserProfileButton.propTypes = {
|
||||||
avatarUrl: PropTypes.string,
|
avatarUrl: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
HeaderContentRight.propTypes = {
|
UserProfileButton.propTypes = {
|
||||||
avatarUrl: null,
|
avatarUrl: null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
logout,
|
logout,
|
||||||
registrationServiceError,
|
registrationServiceError,
|
||||||
userCanceledRegistration,
|
userCanceledRegistration,
|
||||||
} from '../actions/profile.js';
|
} from '../../actions/profile.js';
|
||||||
|
|
||||||
import FacebookLogin from './FacebookLogin.js';
|
import FacebookLogin from './FacebookLogin.js';
|
||||||
|
|
||||||
11
app/components/Login/LocalLogin.container.js
Normal file
11
app/components/Login/LocalLogin.container.js
Normal file
@@ -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);
|
||||||
55
app/components/Login/LocalLogin.js
Normal file
55
app/components/Login/LocalLogin.js
Normal file
@@ -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 (
|
||||||
|
<View style={styles.loginWrap}>
|
||||||
|
<TextInput
|
||||||
|
style={{height: 40}}
|
||||||
|
placeholder="email"
|
||||||
|
onChangeText={(text) => _updateState('username', text)}
|
||||||
|
value={username}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={{height: 40}}
|
||||||
|
placeholder="password"
|
||||||
|
onChangeText={(text) => _updateState('password', text)}
|
||||||
|
value={password}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
disabled={!enabled}
|
||||||
|
onPress={_handleLoginSubmit}
|
||||||
|
title="Login"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalLogin.propTypes = {
|
||||||
|
doLoginAction: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
@@ -16,6 +16,12 @@ export const BID_FAILURE = 'BID_FAILURE';
|
|||||||
export const BID_SUCCESS = 'BID_SUCCESS';
|
export const BID_SUCCESS = 'BID_SUCCESS';
|
||||||
|
|
||||||
export const DO_LOGIN = 'DO_LOGIN';
|
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_LOGOUT = 'DO_LOOUT';
|
||||||
|
|
||||||
export const DO_SIGNUP = 'DO_SIGNUP';
|
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 LINK_GOOGLE_SUCCESS = 'LINK_GOOGLE_SUCCESS';
|
||||||
|
|
||||||
export const SET_PROFILE = 'SET_PROFILE';
|
export const SET_PROFILE = 'SET_PROFILE';
|
||||||
|
export const UNSET_PROFILE = 'UNSET_PROFILE';
|
||||||
export const UPDATE_PROFILE = 'UPDATE_PROFILE';
|
export const UPDATE_PROFILE = 'UPDATE_PROFILE';
|
||||||
|
|
||||||
export const SET_NOM_DE_BID = 'SET_NOM_DE_BID';
|
export const SET_NOM_DE_BID = 'SET_NOM_DE_BID';
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default class Post extends Record({
|
|||||||
|
|
||||||
|
|
||||||
Post.fromJS = (data = {}) => {
|
Post.fromJS = (data = {}) => {
|
||||||
return new TicketClass({
|
return new Post({
|
||||||
id: data._id,
|
id: data._id,
|
||||||
...data,
|
...data,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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';
|
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) {
|
switch (action.type) {
|
||||||
case SET_AUCTION_FILTER:
|
case SET_AUCTION_FILTER:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
|
|||||||
14
app/reducers/auth.js
Normal file
14
app/reducers/auth.js
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -5,12 +5,11 @@ import { EVENTS_LOADED, GET_EVENTS } from '../constants/actionTypes.js';
|
|||||||
export const events = (state = new Map(), action) => {
|
export const events = (state = new Map(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case EVENTS_LOADED:
|
case EVENTS_LOADED:
|
||||||
return state.merge(
|
const mapped = action.payload.toMap().mapEntries((entry) => {
|
||||||
action.payload.toMap().mapEntries((entry) => {
|
|
||||||
const [, event] = entry;
|
const [, event] = entry;
|
||||||
return [`${event.id}`, event];
|
return [`${event.id}`, event];
|
||||||
}),
|
});
|
||||||
);
|
return state.merge(mapped);
|
||||||
case GET_EVENTS:
|
case GET_EVENTS:
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import { activeItem } from './activeItem.js';
|
|||||||
import { auctionFilter } from './auctionFilter.js';
|
import { auctionFilter } from './auctionFilter.js';
|
||||||
import { auctions } from './auctions.js';
|
import { auctions } from './auctions.js';
|
||||||
import { auctionView } from './auctionView.js';
|
import { auctionView } from './auctionView.js';
|
||||||
|
import { auth } from './auth.js';
|
||||||
import { blockUI } from './blockUI.js';
|
import { blockUI } from './blockUI.js';
|
||||||
import { events } from './events.js';
|
import { events } from './events.js';
|
||||||
import { items } from './items.js';
|
import { items } from './items.js';
|
||||||
|
import { profile } from './profile.js';
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
activeEvent,
|
activeEvent,
|
||||||
@@ -15,9 +17,11 @@ const rootReducer = combineReducers({
|
|||||||
auctionFilter,
|
auctionFilter,
|
||||||
auctions,
|
auctions,
|
||||||
auctionView,
|
auctionView,
|
||||||
|
auth,
|
||||||
blockUI,
|
blockUI,
|
||||||
events,
|
events,
|
||||||
items,
|
items,
|
||||||
|
profile,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import { Map } from 'immutable';
|
import { Map } from 'immutable';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
LOGIN_SUCCESS,
|
||||||
SET_PROFILE,
|
SET_PROFILE,
|
||||||
|
UNSET_PROFILE,
|
||||||
UPDATE_PROFILE,
|
UPDATE_PROFILE,
|
||||||
} from '../constants/actionTypes.js';
|
} from '../constants/actionTypes.js';
|
||||||
|
|
||||||
export const profile = (state = new Map(), action) => {
|
export const profile = (state = new Map(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
case LOGIN_SUCCESS:
|
||||||
|
return action.payload.user;
|
||||||
case SET_PROFILE:
|
case SET_PROFILE:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
|
case UNSET_PROFILE:
|
||||||
|
return new Map();
|
||||||
case UPDATE_PROFILE:
|
case UPDATE_PROFILE:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { Dimensions, Platform } from 'react-native';
|
|||||||
import { createBottomTabNavigator, createStackNavigator } from 'react-navigation';
|
import { createBottomTabNavigator, createStackNavigator } from 'react-navigation';
|
||||||
import { Icon } from 'react-native-elements';
|
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 Checkout from './screens/Checkout.js';
|
||||||
import Event from './screens/Event.container.js';
|
import Event from './screens/Event.container.js';
|
||||||
import Events from './screens/Events.container.js';
|
import Events from './screens/Events.container.js';
|
||||||
@@ -50,43 +50,43 @@ export const Tabs = createBottomTabNavigator({
|
|||||||
export const SignInOrRegisterStack = createStackNavigator({
|
export const SignInOrRegisterStack = createStackNavigator({
|
||||||
SignInOrRegister: {
|
SignInOrRegister: {
|
||||||
screen: SignInOrRegister,
|
screen: SignInOrRegister,
|
||||||
navigationOptions: ({ navigation }) => {
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: null,
|
header: null,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
Register: {
|
Register: {
|
||||||
screen: Register,
|
screen: Register,
|
||||||
navigationOptions: ({ navigation }) => {
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: null,
|
header: null,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AuctionStack = createStackNavigator({
|
export const AuctionStack = createStackNavigator({
|
||||||
Auction: {
|
Auction: {
|
||||||
screen: Auction,
|
screen: Auction,
|
||||||
navigationOptions: ({navigation}) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: <AppHeader navigation={navigation} />,
|
header: <AppHeader navigation={navigation} />,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
Item: {
|
Item: {
|
||||||
screen: Item,
|
screen: Item,
|
||||||
navigationOptions: ({navigation}) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: null,
|
header: null,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
ImageDetail: {
|
ImageDetail: {
|
||||||
screen: ImageDetail,
|
screen: ImageDetail,
|
||||||
navigationOptions: ({navigation}) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: null,
|
header: null,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -94,32 +94,32 @@ export const AuctionStack = createStackNavigator({
|
|||||||
export const BazaarStack = createStackNavigator({
|
export const BazaarStack = createStackNavigator({
|
||||||
Bazaar: {
|
Bazaar: {
|
||||||
screen: Marketplace,
|
screen: Marketplace,
|
||||||
navigationOptions: ({navigation}) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: <AppHeader navigation={navigation} />,
|
header: <AppHeader navigation={navigation} />,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
Item: {
|
Item: {
|
||||||
screen: Item,
|
screen: Item,
|
||||||
navigationOptions: ({navigation}) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: null,
|
header: null,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
ImageDetail: {
|
ImageDetail: {
|
||||||
screen: ImageDetail,
|
screen: ImageDetail,
|
||||||
navigationOptions: ({navigation}) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: null,
|
header: null,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
Checkout: {
|
Checkout: {
|
||||||
screen: Checkout,
|
screen: Checkout,
|
||||||
navigationOptions: ({navigation}) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: null,
|
header: null,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -130,7 +130,7 @@ export const EventsStack = createStackNavigator({
|
|||||||
navigationOptions: ({ navigation }) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: <AppHeader navigation={navigation} />,
|
header: <AppHeader navigation={navigation} />,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -141,30 +141,30 @@ export const createRootNavigator = () => {
|
|||||||
AuctionStack: {
|
AuctionStack: {
|
||||||
screen: AuctionStack,
|
screen: AuctionStack,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BazaarStack: {
|
BazaarStack: {
|
||||||
screen: BazaarStack,
|
screen: BazaarStack,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
EventsStack: {
|
EventsStack: {
|
||||||
screen: EventsStack,
|
screen: EventsStack,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Tabs: {
|
Tabs: {
|
||||||
screen: Tabs,
|
screen: Tabs,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
gesturesEnabled: false
|
gesturesEnabled: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mode: "modal"
|
mode: "modal",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { fetchEvent } from '../actions/events.js';
|
import { fetchEvents } from '../actions/events.js';
|
||||||
import { getEventById } from '../selectors/events.js';
|
import EventRecord from '../domain/Event.js';
|
||||||
|
import { getActiveEvent, getDefaultEvent } from '../selectors/events.js';
|
||||||
|
|
||||||
import Event from './Event.js';
|
import Event from './Event.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => {
|
const matchStateToProps = (state) => {
|
||||||
const eventId = state.get('activeEvent');
|
const event = getActiveEvent(state) || getDefaultEvent(state) || new EventRecord();
|
||||||
const event = getEventById(state, eventId);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: event.get('description'),
|
description: event.get('description'),
|
||||||
endTime: event.get('endTime'),
|
endTime: event.get('endTime'),
|
||||||
id: event.get('id'),
|
id: event.get('id'),
|
||||||
images: event.get('images'),
|
images: event.get('images').toArray(),
|
||||||
isTicketed: event.get('isTicketed'),
|
isTicketed: event.get('isTicketed'),
|
||||||
posts: event.get('posts'),
|
posts: event.get('posts').toArray(),
|
||||||
requireLoginToSeeAuction: event.get('requireLoginToSeeAuction'),
|
requireLoginToSeeAuction: event.get('requireLoginToSeeAuction'),
|
||||||
showFrom: event.get('showFrom'),
|
showFrom: event.get('showFrom'),
|
||||||
showUntil: event.get('showUntil'),
|
showUntil: event.get('showUntil'),
|
||||||
startTime: event.get('startTime'),
|
startTime: event.get('startTime'),
|
||||||
tagline: event.get('tagline'),
|
tagline: event.get('tagline'),
|
||||||
ticketClasses: event.get('ticketClasses'),
|
ticketClasses: event.get('ticketClasses').toArray(),
|
||||||
title: event.get('title'),
|
title: event.get('title'),
|
||||||
url: event.get('url'),
|
url: event.get('url'),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
fetchEvent: () => dispatch(fetchEvent(dispatch)),
|
fetchEvents: () => dispatch(fetchEvents()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, mapDispatchToProps)(Event);
|
export default connect(matchStateToProps, mapDispatchToProps)(Event);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
import styles from './Event.styles.js';
|
import styles from './Event.styles.js';
|
||||||
@@ -6,10 +7,10 @@ import styles from './Event.styles.js';
|
|||||||
export default class Event extends Component {
|
export default class Event extends Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
description: PropTypes.string.isRequired,
|
description: PropTypes.string,
|
||||||
endTime: PropTypes.string.isRequired,
|
endTime: PropTypes.string,
|
||||||
fetchEvent: PropTypes.func.isRequired,
|
fetchEvents: PropTypes.func,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string,
|
||||||
images: PropTypes.arrayOf(
|
images: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
url: PropTypes.string,
|
url: PropTypes.string,
|
||||||
@@ -18,27 +19,27 @@ export default class Event extends Component {
|
|||||||
isTicketed: PropTypes.bool,
|
isTicketed: PropTypes.bool,
|
||||||
posts: PropTypes.arrayOf(
|
posts: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
author: PropTypes.string.isRequired,
|
author: PropTypes.string,
|
||||||
content: PropTypes.string.isRequired,
|
content: PropTypes.string,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string,
|
||||||
isPublic: PropTypes.bool,
|
isPublic: PropTypes.bool,
|
||||||
scheduledPost: PropTypes.bool,
|
scheduledPost: PropTypes.bool,
|
||||||
sendNotification: PropTypes.bool,
|
sendNotification: PropTypes.bool,
|
||||||
timestamp: PropTypes.string.isRequired,
|
timestamp: PropTypes.string,
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
requireLoginToSeeAuction: PropTypes.bool.isRequired,
|
requireLoginToSeeAuction: PropTypes.bool,
|
||||||
showFrom: PropTypes.string.isRequired,
|
showFrom: PropTypes.string,
|
||||||
showUntil: PropTypes.string.isRequired,
|
showUntil: PropTypes.string,
|
||||||
startTime: PropTypes.string.isRequired,
|
startTime: PropTypes.string,
|
||||||
tagline: PropTypes.string,
|
tagline: PropTypes.string,
|
||||||
ticketClasses: PropTypes.arrayOf(
|
ticketClasses: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
|
|
||||||
}),
|
}),
|
||||||
)
|
),
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string,
|
||||||
url: PropTypes.string,
|
url: PropTypes.string,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -59,6 +60,10 @@ export default class Event extends Component {
|
|||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.fetchEvents();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
description,
|
description,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export default const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
@@ -13,3 +13,5 @@ export default const styles = StyleSheet.create({
|
|||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default styles;
|
||||||
|
|||||||
@@ -1,30 +1,38 @@
|
|||||||
|
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 {
|
import {
|
||||||
FlatList,
|
FlatList,
|
||||||
StyleSheet,
|
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
} from 'react-native';
|
} 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 FilterBar from '../components/Auction/FilterBar.js';
|
||||||
import ListItem from '../components/Item/List.js';
|
import AuctionListItem from '../containers/Auction/AuctionListItem.js';
|
||||||
|
|
||||||
|
//import styles from './Marketplace.styles.js';
|
||||||
|
|
||||||
export default class Marketplace extends Component {
|
export default class Marketplace extends Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
changeFilter: PropTypes.func,
|
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() {
|
static get defaultProps() {
|
||||||
return {
|
return {
|
||||||
changeFilter: () => { console.log('Change Filter Default Prop', arguments); },
|
changeFilter: () => { console.log('Change Filter Default Prop', arguments); },
|
||||||
header: null,
|
items: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,57 +44,42 @@ export default class Marketplace extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
sort: SORT_MODES.TITLE_ASC,
|
sort: SORT_MODES.TITLE_ASC,
|
||||||
view: VIEW_MODES.LIST,
|
view: AUCTION_VIEW_MODES.ALL,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.fetchStatus();
|
||||||
|
this.props.fetchItems();
|
||||||
|
}
|
||||||
|
|
||||||
changeFilter(filter) {
|
changeFilter(filter) {
|
||||||
this.props.changeFilter('market', filter);
|
this.props.changeFilter('auction', filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeViewMode(mode) {
|
_keyExtractor = (item, index) => `${item._id}_${index}`;
|
||||||
this.setState({ view: mode });
|
|
||||||
}
|
|
||||||
|
|
||||||
_keyExtractor = (item, index) => item.id;
|
_renderAuctionListItem = ({ item }) => <AuctionListItem item={item} />;
|
||||||
|
|
||||||
_renderItem = (view) => ({ item }) => {
|
|
||||||
if (view === VIEW_MODES.GRID) {
|
|
||||||
return <GridItem {...item} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ListItem {...item} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { items, view } = this.state;
|
const { items } = this.props;
|
||||||
|
const { sort, view } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<FilterBar
|
<FilterBar
|
||||||
changeFilterer={this.changeFilter}
|
changeFilterer={this.changeFilter}
|
||||||
changeViewMode={this.changeViewMode}
|
|
||||||
/>
|
|
||||||
<FlatList
|
|
||||||
data={items}
|
|
||||||
keyExtractor={this._keyExtractor}
|
|
||||||
renderItem={this.renderItem(view)}
|
|
||||||
/>
|
/>
|
||||||
|
{items.size > 0 && (
|
||||||
|
<FlatList
|
||||||
|
data={items}
|
||||||
|
keyExtractor={this._keyExtractor}
|
||||||
|
renderItem={this._renderAuctionListItem}
|
||||||
|
contentContainerStyle={styles.itemListContentContainer}
|
||||||
|
style={styles.itemList}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
backgroundColor: '#F5FCFF',
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
fontSize: 20,
|
|
||||||
textAlign: 'center',
|
|
||||||
margin: 10,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|||||||
16
app/screens/Register.styles.js
Normal file
16
app/screens/Register.styles.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
export const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
},
|
||||||
|
localLogin: {
|
||||||
|
},
|
||||||
|
services: {
|
||||||
|
},
|
||||||
|
register: {
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Text, View } from 'react-native';
|
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';
|
import styles from './SignInOrRegister.styles.js';
|
||||||
|
|
||||||
@@ -28,7 +30,7 @@ export default class SignInOrRegister extends Component {
|
|||||||
<FacebookLogin />
|
<FacebookLogin />
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.register}>
|
<View style={styles.register}>
|
||||||
<Button onPress={this._doRegistration} />
|
<Button title="Signup with Email" onPress={this._doRegistration} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export default const styles = StyleSheet.create({
|
export const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ export const getActiveEventId = createSelector(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const hasActiveEvent = createSelector(
|
export const hasActiveEvent = createSelector(
|
||||||
[getState],
|
[getActiveEventId],
|
||||||
(state) => !!state.get('activeEvent'),
|
(eventId) => !!eventId,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,15 +19,15 @@ export const getAuctionStatuses = createSelector(
|
|||||||
|
|
||||||
export const getItemsIdsWithNoBids = createSelector(
|
export const getItemsIdsWithNoBids = createSelector(
|
||||||
[getAuctionStatuses],
|
[getAuctionStatuses],
|
||||||
(auctions) => auctions.filter(auction => auction.bidCount === 0);
|
(auctions) => auctions.filter(auction => auction.bidCount === 0),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getMyBidItemIds = createSelector(
|
export const getMyBidItemIds = createSelector(
|
||||||
[getAuctionStatuses],
|
[getAuctionStatuses],
|
||||||
(auctions) => auctions.filter(auction => auction.isBidding);
|
(auctions) => auctions.filter(auction => auction.isBidding),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getMyWinningItemIds = createSelector(
|
export const getMyWinningItemIds = createSelector(
|
||||||
[getAuctionStatuses],
|
[getAuctionStatuses],
|
||||||
(auctions) => auctions.filter(auction => auction.isWinning);
|
(auctions) => auctions.filter(auction => auction.isWinning),
|
||||||
);
|
);
|
||||||
|
|||||||
8
app/selectors/auth.js
Normal file
8
app/selectors/auth.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
|
const getState = (state) => state;
|
||||||
|
|
||||||
|
export const getAuthToken = createSelector(
|
||||||
|
[getState],
|
||||||
|
(state) => state.get('auth'),
|
||||||
|
);
|
||||||
@@ -14,7 +14,7 @@ export const getEvents = createSelector(
|
|||||||
|
|
||||||
export const getActiveEvent = createSelector(
|
export const getActiveEvent = createSelector(
|
||||||
[getActiveEventId, getEvents],
|
[getActiveEventId, getEvents],
|
||||||
(eventId, eventsAsMap) => eventId ? eventsAsMap.get(eventId) : false,
|
(eventId, eventsAsMap) => eventId ? eventsAsMap.get(eventId) : null,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getDefaultEvent = createSelector(
|
export const getDefaultEvent = createSelector(
|
||||||
|
|||||||
Reference in New Issue
Block a user